SPH
Iterate.h
Go to the documentation of this file.
1 #pragma once
2 
7 
9 #include "quantities/Quantity.h"
10 #include "quantities/Storage.h"
11 
13 
21 template <VisitorEnum TVisitorType>
23 
24 template <VisitorEnum TVisitorType>
26 
27 
31 template <>
33  template <typename TValue, typename TFunctor>
34  void visit(Quantity& q, const QuantityId id, TFunctor&& functor) {
35  functor(id, q.getValue<TValue>());
36  }
37 };
38 template <>
40  template <typename TValue, typename TFunctor>
41  void visit(Quantity& q1, Quantity& q2, TFunctor&& functor) {
42  functor(q1.getValue<TValue>(), q2.getValue<TValue>());
43  }
44 };
45 
51 template <>
53  template <typename TValue, typename TFunctor>
54  void visit(Quantity& q, const QuantityId UNUSED(id), TFunctor&& functor) {
55  for (auto& i : q.getAll<TValue>()) {
56  functor(i);
57  }
58  }
59  template <typename TValue, typename TFunctor>
60  void visit(const Quantity& q, const QuantityId UNUSED(id), TFunctor&& functor) {
61  for (const auto& i : q.getAll<TValue>()) {
62  functor(i);
63  }
64  }
65 };
66 template <>
68  template <typename TValue, typename TFunctor>
69  void visit(Quantity& q1, Quantity& q2, const QuantityId UNUSED(id), TFunctor&& functor) {
70  auto values1 = q1.template getAll<TValue>();
71  auto values2 = q2.template getAll<TValue>();
72  SPH_ASSERT(values1.size() == values2.size());
73  for (Size j = 0; j < values1.size(); ++j) {
74  functor(values1[j], values2[j]);
75  }
76  }
77 };
78 
79 
84 template <>
86  template <typename TValue, typename TFunctor>
87  void visit(Quantity& q, const QuantityId id, TFunctor&& functor) {
88  if (q.getOrderEnum() != OrderEnum::ZERO) {
89  return;
90  }
91  functor(id, q.getValue<TValue>());
92  }
93  template <typename TValue, typename TFunctor>
94  void visit(const Quantity& q, const QuantityId id, TFunctor&& functor) {
95  if (q.getOrderEnum() != OrderEnum::ZERO) {
96  return;
97  }
98  functor(id, q.getValue<TValue>());
99  }
100 };
101 template <>
103  template <typename TValue, typename TFunctor>
104  void visit(Quantity& q1, Quantity& q2, const QuantityId id, TFunctor&& functor) {
105  if (q1.getOrderEnum() != OrderEnum::ZERO) {
106  return;
107  }
109  functor(id, q1.getValue<TValue>(), q2.getValue<TValue>());
110  }
111 
112  template <typename TValue, typename TFunctor>
113  void visit(const Quantity& q1, const Quantity& q2, const QuantityId id, TFunctor&& functor) {
114  if (q1.getOrderEnum() != OrderEnum::ZERO) {
115  return;
116  }
118  functor(id, q1.getValue<TValue>(), q2.getValue<TValue>());
119  }
120 };
121 
122 
127 template <>
129  template <typename TValue, typename TFunctor>
130  void visit(Quantity& q, const QuantityId id, TFunctor&& functor) {
131  if (q.getOrderEnum() != OrderEnum::FIRST) {
132  return;
133  }
134  functor(id, q.getValue<TValue>(), q.getDt<TValue>());
135  }
136  template <typename TValue, typename TFunctor>
137  void visit(const Quantity& q, const QuantityId id, TFunctor&& functor) {
138  if (q.getOrderEnum() != OrderEnum::FIRST) {
139  return;
140  }
141  functor(id, q.getValue<TValue>(), q.getDt<TValue>());
142  }
143 };
144 template <>
146  template <typename TValue, typename TFunctor>
147  void visit(Quantity& q1, Quantity& q2, const QuantityId id, TFunctor&& functor) {
148  if (q1.getOrderEnum() != OrderEnum::FIRST) {
149  return;
150  }
152  functor(id, q1.getValue<TValue>(), q1.getDt<TValue>(), q2.getValue<TValue>(), q2.getDt<TValue>());
153  }
154 
155  template <typename TValue, typename TFunctor>
156  void visit(const Quantity& q1, const Quantity& q2, const QuantityId id, TFunctor&& functor) {
157  if (q1.getOrderEnum() != OrderEnum::FIRST) {
158  return;
159  }
161  functor(id, q1.getValue<TValue>(), q1.getDt<TValue>(), q2.getValue<TValue>(), q2.getDt<TValue>());
162  }
163 };
164 
167 template <>
169  template <typename TValue, typename TFunctor>
170  void visit(Quantity& q, const QuantityId id, TFunctor&& functor) {
171  if (q.getOrderEnum() != OrderEnum::SECOND) {
172  return;
173  }
174  functor(id, q.getValue<TValue>(), q.getDt<TValue>(), q.getD2t<TValue>());
175  }
176  template <typename TValue, typename TFunctor>
177  void visit(const Quantity& q, const QuantityId id, TFunctor&& functor) {
178  if (q.getOrderEnum() != OrderEnum::SECOND) {
179  return;
180  }
181  functor(id, q.getValue<TValue>(), q.getDt<TValue>(), q.getD2t<TValue>());
182  }
183 };
184 template <>
186  template <typename TValue, typename TFunctor>
187  void visit(Quantity& q1, Quantity& q2, const QuantityId id, TFunctor&& functor) {
188  if (q1.getOrderEnum() != OrderEnum::SECOND) {
189  return;
190  }
192  functor(id,
193  q1.getValue<TValue>(),
194  q1.getDt<TValue>(),
195  q1.getD2t<TValue>(),
196  q2.getValue<TValue>(),
197  q2.getDt<TValue>(),
198  q2.getD2t<TValue>());
199  }
200 
201  template <typename TValue, typename TFunctor>
202  void visit(const Quantity& q1, const Quantity& q2, const QuantityId id, TFunctor&& functor) {
203  if (q1.getOrderEnum() != OrderEnum::SECOND) {
204  return;
205  }
207  functor(id,
208  q1.getValue<TValue>(),
209  q1.getDt<TValue>(),
210  q1.getD2t<TValue>(),
211  q2.getValue<TValue>(),
212  q2.getDt<TValue>(),
213  q2.getD2t<TValue>());
214  }
215 };
216 
217 
222 template <>
224  template <typename TValue, typename TFunctor>
225  void visit(Quantity& q, const QuantityId id, TFunctor&& functor) {
226  const OrderEnum order = q.getOrderEnum();
227  if (order == OrderEnum::FIRST) {
228  functor(id, q.getDt<TValue>());
229  } else if (order == OrderEnum::SECOND) {
230  functor(id, q.getD2t<TValue>());
231  }
232  }
233  template <typename TValue, typename TFunctor>
234  void visit(const Quantity& q, const QuantityId id, TFunctor&& functor) {
235  const OrderEnum order = q.getOrderEnum();
236  if (order == OrderEnum::FIRST) {
237  functor(id, q.getDt<TValue>());
238  } else if (order == OrderEnum::SECOND) {
239  functor(id, q.getD2t<TValue>());
240  }
241  }
242 };
243 template <>
245  template <typename TValue, typename TFunctor>
246  void visit(Quantity& q1, Quantity& q2, TFunctor&& functor) {
247  const OrderEnum order1 = q1.getOrderEnum();
248  SPH_ASSERT(order1 == q2.getOrderEnum());
249  if (order1 == OrderEnum::FIRST) {
250  functor(q1.getDt<TValue>(), q2.getDt<TValue>());
251  } else if (order1 == OrderEnum::SECOND) {
252  functor(q1.getD2t<TValue>(), q2.getD2t<TValue>());
253  }
254  }
255 };
256 
257 
265 template <VisitorEnum Type, typename TFunctor>
266 void iterate(Storage& storage, TFunctor&& functor) {
267  StorageVisitor<Type> visitor;
268  for (auto q : storage.getQuantities()) {
269  dispatch(q.quantity.getValueEnum(), visitor, q.quantity, q.id, std::forward<TFunctor>(functor));
270  }
271 }
272 
274 template <VisitorEnum Type, typename TFunctor>
275 void iterate(const Storage& storage, TFunctor&& functor) {
276  StorageVisitor<Type> visitor;
277  for (auto q : storage.getQuantities()) {
278  dispatch(q.quantity.getValueEnum(), visitor, q.quantity, q.id, std::forward<TFunctor>(functor));
279  }
280 }
281 
283  template <typename TValue, typename TFunctor>
284  void visit(Quantity& q, Array<Vector>& r, QuantityId key, TFunctor&& functor) {
285  if (key == QuantityId::POSITION) {
286  // exclude positions, iterate only derivatives
287  auto buffers = q.getAll<TValue>();
288  // usually, there are 3 buffers (positions, velocities, accelerations), but we allow any number of
289  // buffers to make it more general (and this is actually used in DiehlDistribution, for example).
290  for (Size i = 1; i < buffers.size(); ++i) {
291  functor(buffers[i], r);
292  }
293  } else {
294  for (auto& i : q.getAll<TValue>()) {
295  functor(i, r);
296  }
297  }
298  }
299 };
300 
305 template <typename TFunctor>
306 void iterateWithPositions(Storage& storage, TFunctor&& functor) {
309  for (auto q : storage.getQuantities()) {
310  dispatch(q.quantity.getValueEnum(), visitor, q.quantity, r, q.id, functor);
311  }
312 }
313 
315 template <VisitorEnum Type, typename TFunctor>
316 void iteratePair(Storage& storage1, Storage& storage2, TFunctor&& functor) {
317  SPH_ASSERT(storage1.getQuantityCnt() == storage2.getQuantityCnt(),
318  storage1.getQuantityCnt(),
319  storage2.getQuantityCnt());
320  StoragePairVisitor<Type> visitor;
321  struct Element {
322  StorageElement e1;
323  StorageElement e2;
324  };
325 
326  for (auto i : iterateTuple<Element>(storage1.getQuantities(), storage2.getQuantities())) {
327  SPH_ASSERT(i.e1.id == i.e2.id);
328  Quantity& q1 = i.e1.quantity;
329  Quantity& q2 = i.e2.quantity;
330  SPH_ASSERT(q1.getValueEnum() == q2.getValueEnum());
331  dispatch(q1.getValueEnum(), visitor, q1, q2, i.e1.id, functor);
332  }
333 }
334 
336 template <VisitorEnum Type, typename TFunctor>
337 void iteratePair(const Storage& storage1, const Storage& storage2, TFunctor&& functor) {
338  SPH_ASSERT(storage1.getQuantityCnt() == storage2.getQuantityCnt(),
339  storage1.getQuantityCnt(),
340  storage2.getQuantityCnt());
341  StoragePairVisitor<Type> visitor;
342  struct Element {
345  };
346 
347  for (auto i : iterateTuple<Element>(storage1.getQuantities(), storage2.getQuantities())) {
348  SPH_ASSERT(i.e1.id == i.e2.id);
349  const Quantity& q1 = i.e1.quantity;
350  const Quantity& q2 = i.e2.quantity;
351  SPH_ASSERT(q1.getValueEnum() == q2.getValueEnum());
352  dispatch(q1.getValueEnum(), visitor, q1, q2, i.e1.id, functor);
353  }
354 }
355 
356 
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
void iterateWithPositions(Storage &storage, TFunctor &&functor)
Iterate over all quantities and execute a functor, passing quantity buffers together with particle po...
Definition: Iterate.h:306
void iteratePair(Storage &storage1, Storage &storage2, TFunctor &&functor)
Iterate over given type of quantities in two storage views and executes functor for each pair.
Definition: Iterate.h:316
void iterate(Storage &storage, TFunctor &&functor)
Iterate over given type of quantities and executes functor for each.
Definition: Iterate.h:266
Helper objects allowing to iterate in reverse, iterate over multiple containeres, etc.
#define UNUSED(x)
Definition: Object.h:37
#define NAMESPACE_SPH_END
Definition: Object.h:12
decltype(auto) dispatch(const ValueEnum value, TVisitor &&visitor, TArgs &&... args)
Selects type based on run-time ValueEnum value and runs visit<Type>() method of the visitor.
QuantityId
Unique IDs of basic quantities of SPH particles.
Definition: QuantityIds.h:19
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
Holder of quantity values and their temporal derivatives.
VisitorEnum
Types of iteration over storage.
Definition: Quantity.h:23
@ FIRST_ORDER
Iterates only over first-order quantities. Passes values and derivatives as arguments of functor.
OrderEnum
Definition: Quantity.h:15
@ SECOND
Quantity with 1st and 2nd derivative.
@ FIRST
Quantity with 1st derivative.
@ ZERO
Quantity without derivatives, or "zero order" of quantity.
Container for storing particle quantities and materials.
Generic dynamically allocated resizable storage.
Definition: Array.h:43
Generic container for storing scalar, vector or tensor quantity and its derivatives.
Definition: Quantity.h:200
OrderEnum getOrderEnum() const
Returns the order of the quantity.
Definition: Quantity.h:241
INLINE Array< TValue > & getD2t()
Returns a reference to array of second derivatives of quantity.
Definition: Quantity.h:323
StaticArray< Array< TValue > &, 3 > getAll()
Returns all buffers of given type stored in this quantity.
Definition: Quantity.h:338
INLINE Array< TValue > & getValue()
Returns a reference to array of quantity values.
Definition: Quantity.h:287
INLINE Array< TValue > & getDt()
Returns a reference to array of first derivatives of quantity.
Definition: Quantity.h:307
ValueEnum getValueEnum() const
Returns the value order of the quantity.
Definition: Quantity.h:246
Container storing all quantities used within the simulations.
Definition: Storage.h:230
StorageSequence getQuantities()
Returns the sequence of quantities.
Definition: Storage.cpp:416
Size getQuantityCnt() const
Returns the number of stored quantities.
Definition: Storage.cpp:441
Array< TValue > & getValue(const QuantityId key)
Retrieves a quantity values from the storage, given its key and value type.
Definition: Storage.cpp:191
void visit(Quantity &q1, Quantity &q2, const QuantityId UNUSED(id), TFunctor &&functor)
Definition: Iterate.h:69
void visit(Quantity &q1, Quantity &q2, TFunctor &&functor)
Definition: Iterate.h:41
void visit(Quantity &q1, Quantity &q2, const QuantityId id, TFunctor &&functor)
Definition: Iterate.h:147
void visit(const Quantity &q1, const Quantity &q2, const QuantityId id, TFunctor &&functor)
Definition: Iterate.h:156
void visit(Quantity &q1, Quantity &q2, TFunctor &&functor)
Definition: Iterate.h:246
void visit(Quantity &q1, Quantity &q2, const QuantityId id, TFunctor &&functor)
Definition: Iterate.h:187
void visit(const Quantity &q1, const Quantity &q2, const QuantityId id, TFunctor &&functor)
Definition: Iterate.h:202
void visit(Quantity &q1, Quantity &q2, const QuantityId id, TFunctor &&functor)
Definition: Iterate.h:104
void visit(const Quantity &q1, const Quantity &q2, const QuantityId id, TFunctor &&functor)
Definition: Iterate.h:113
void visit(Quantity &q, Array< Vector > &r, QuantityId key, TFunctor &&functor)
Definition: Iterate.h:284
void visit(const Quantity &q, const QuantityId UNUSED(id), TFunctor &&functor)
Definition: Iterate.h:60
void visit(Quantity &q, const QuantityId UNUSED(id), TFunctor &&functor)
Definition: Iterate.h:54
void visit(Quantity &q, const QuantityId id, TFunctor &&functor)
Definition: Iterate.h:34
void visit(Quantity &q, const QuantityId id, TFunctor &&functor)
Definition: Iterate.h:130
void visit(const Quantity &q, const QuantityId id, TFunctor &&functor)
Definition: Iterate.h:137
void visit(Quantity &q, const QuantityId id, TFunctor &&functor)
Definition: Iterate.h:225
void visit(const Quantity &q, const QuantityId id, TFunctor &&functor)
Definition: Iterate.h:234
void visit(Quantity &q, const QuantityId id, TFunctor &&functor)
Definition: Iterate.h:170
void visit(const Quantity &q, const QuantityId id, TFunctor &&functor)
Definition: Iterate.h:177
void visit(Quantity &q, const QuantityId id, TFunctor &&functor)
Definition: Iterate.h:87
void visit(const Quantity &q, const QuantityId id, TFunctor &&functor)
Definition: Iterate.h:94