SPH
Quantity.h
Go to the documentation of this file.
1 #pragma once
2 
7 
12 
14 
15 enum class OrderEnum {
16  ZERO,
17  FIRST,
18  SECOND,
19 };
20 
21 
23 enum class VisitorEnum {
27  ZERO_ORDER = 1 << 0,
28 
30  FIRST_ORDER = 1 << 1,
31 
34  SECOND_ORDER = 1 << 2,
35 
38  ALL_BUFFERS = 1 << 3,
39 
42  ALL_VALUES = 1 << 4,
43 
46  STATE_VALUES = 1 << 5,
47 
50  HIGHEST_DERIVATIVES = 1 << 6,
51 };
52 
53 
54 namespace Detail {
58 template <typename TValue>
59 class Holder {
60 private:
61  Array<TValue> v;
62  Array<TValue> dv_dt;
63  Array<TValue> d2v_dt2;
64 
65  OrderEnum order;
66 
67  Holder(const OrderEnum order)
68  : order(order) {}
69 
70 public:
71  Holder(const OrderEnum order, const TValue& defaultValue, const Size size)
72  : order(order) {
73  v.resize(size);
74  v.fill(defaultValue);
75  initDerivatives(size);
76  }
77 
78  Holder(const OrderEnum order, Array<TValue>&& values)
79  : v(std::move(values))
80  , order(order) {
81  initDerivatives(v.size());
82  }
83 
86  return order;
87  }
88 
92  }
93 
95  INLINE Size size() const {
96  // the quantity can be incomplete (can hold only derivatives), just return the maximum size
97  return max(v.size(), dv_dt.size(), d2v_dt2.size());
98  }
99 
101  return v;
102  }
103 
104  INLINE const Array<TValue>& getValue() const {
105  return v;
106  }
107 
109  SPH_ASSERT(order == OrderEnum::FIRST || order == OrderEnum::SECOND);
110  return dv_dt;
111  }
112 
113  INLINE const Array<TValue>& getDt() const {
114  SPH_ASSERT(order == OrderEnum::FIRST || order == OrderEnum::SECOND);
115  return dv_dt;
116  }
117 
119  SPH_ASSERT(order == OrderEnum::SECOND);
120  return d2v_dt2;
121  }
122 
123  INLINE const Array<TValue>& getD2t() const {
124  SPH_ASSERT(order == OrderEnum::SECOND);
125  return d2v_dt2;
126  }
127 
129  switch (order) {
130  case OrderEnum::ZERO:
131  return { v };
132  case OrderEnum::FIRST:
133  return { v, dv_dt };
134  case OrderEnum::SECOND:
135  return { v, dv_dt, d2v_dt2 };
136  default:
138  }
139  }
140 
142  switch (order) {
143  case OrderEnum::ZERO:
144  return { v };
145  case OrderEnum::FIRST:
146  return { v, dv_dt };
147  case OrderEnum::SECOND:
148  return { v, dv_dt, d2v_dt2 };
149  default:
151  }
152  }
153 
154  Holder clone(const Flags<VisitorEnum> flags) const;
155 
156 
157  Holder createZeros(const Size particleCnt) const;
158 
159  void swap(Holder& other, Flags<VisitorEnum> flags);
160 
161  void setOrder(const OrderEnum newOrder);
162 
163 private:
164  void initDerivatives(const Size size);
165 
166  template <typename TFunctor>
167  void visitMutable(Holder& other, const Flags<VisitorEnum> flags, TFunctor&& functor);
168 
169  template <typename TFunctor>
170  void visitConst(Holder& other, const Flags<VisitorEnum> flags, TFunctor&& functor) const;
171 };
172 } // namespace Detail
173 
200 class Quantity : public Noncopyable {
201 private:
202  template <typename... TArgs>
204 
205  // Types must be in same order as in ValueEnum!
207  Holder data;
208 
209  Quantity(Holder&& holder)
210  : data(std::move(holder)) {}
211 
212 public:
217  Quantity() = default;
218 
225  template <typename TValue>
226  Quantity(const OrderEnum order, const TValue& defaultValue, const Size size)
227  : data(Detail::Holder<TValue>(order, defaultValue, size)) {}
228 
232  template <typename TValue>
233  Quantity(const OrderEnum order, Array<TValue>&& values)
234  : data(Detail::Holder<TValue>(order, std::move(values))) {}
235 
242  return forValue(data, [](auto& holder) INL { return holder.getOrderEnum(); });
243  }
244 
247  SPH_ASSERT(data.getTypeIdx() != 0);
248  return ValueEnum(data.getTypeIdx() - 1);
249  }
250 
252  Quantity clone(const Flags<VisitorEnum> flags) const {
253  return forValue(data, [flags](auto& holder) -> Holder { return holder.clone(flags); });
254  }
255 
259  Quantity createZeros(const Size particleCnt) const {
260  return forValue(data, [particleCnt](auto& holder) -> Holder { //
261  return holder.createZeros(particleCnt);
262  });
263  }
264 
269  void swap(Quantity& other, const Flags<VisitorEnum> flags) {
270  SPH_ASSERT(this->getValueEnum() == other.getValueEnum());
271  forValue(data, [flags, &other](auto& holder) {
272  using Type = std::decay_t<decltype(holder)>;
273  return holder.swap(other.data.get<Type>(), flags);
274  });
275  }
276 
278  INLINE Size size() const {
279  return forValue(data, [](auto& holder) INL { return holder.size(); });
280  }
281 
286  template <typename TValue>
288  return get<TValue>().getValue();
289  }
290 
292  template <typename TValue>
293  INLINE const Array<TValue>& getValue() const {
294  return get<TValue>().getValue();
295  }
296 
297  void setOrder(const OrderEnum order) {
298  return forValue(data, [order](auto& holder) INL { return holder.setOrder(order); });
299  }
300 
306  template <typename TValue>
308  return get<TValue>().getDt();
309  }
310 
312  template <typename TValue>
313  INLINE const Array<TValue>& getDt() const {
314  return get<TValue>().getDt();
315  }
316 
322  template <typename TValue>
324  return get<TValue>().getD2t();
325  }
326 
328  template <typename TValue>
329  INLINE const Array<TValue>& getD2t() const {
330  return get<TValue>().getD2t();
331  }
332 
337  template <typename TValue>
339  return get<TValue>().getAll();
340  }
341 
342  template <typename TValue>
344  return get<TValue>().getAll();
345  }
346 
350  template <typename TIndexSequence>
351  void clamp(const TIndexSequence& sequence, const Interval range) {
352  forValue(data, [&sequence, range](auto& v) {
353  auto& values = v.getValue();
354  for (Size idx : sequence) {
355  values[idx] = Sph::clamp(values[idx], range);
356  }
357  });
358  }
359 
360 private:
361  template <typename TValue>
362  Detail::Holder<TValue>& get() {
363  return data.get<Detail::Holder<TValue>>();
364  }
365 
366  template <typename TValue>
367  const Detail::Holder<TValue>& get() const {
368  return data.get<Detail::Holder<TValue>>();
369  }
370 };
371 
Generic dynamically allocated resizable storage.
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
#define NOT_IMPLEMENTED
Helper macro marking missing implementation.
Definition: Assert.h:100
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
Wrapper over enum allowing setting (and querying) individual bits of the stored value.
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
constexpr INLINE T max(const T &f1, const T &f2)
Definition: MathBasic.h:20
constexpr INLINE T clamp(const T &f, const T &f1, const T &f2)
Definition: MathBasic.h:35
#define INLINE
Macros for conditional compilation based on selected compiler.
Definition: Object.h:31
#define NAMESPACE_SPH_END
Definition: Object.h:12
#define INL
Definition: Object.h:32
Conversions for quantity enums.
ValueEnum
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.
Object capable of storing values of different types.
decltype(auto) INLINE forValue(Variant< TArgs... > &variant, TFunctor &&functor)
Definition: Variant.h:428
void resize(const TCounter newSize)
Resizes the array to new size.
Definition: Array.h:215
void fill(const T &t)
Sets all elements of the array to given value.
Definition: Array.h:187
INLINE TCounter size() const noexcept
Definition: Array.h:193
void swap(Holder &other, Flags< VisitorEnum > flags)
Definition: Quantity.cpp:22
INLINE Array< TValue > & getD2t()
Definition: Quantity.h:118
Holder createZeros(const Size particleCnt) const
Definition: Quantity.cpp:17
Holder(const OrderEnum order, Array< TValue > &&values)
Definition: Quantity.h:78
INLINE const Array< TValue > & getValue() const
Definition: Quantity.h:104
void setOrder(const OrderEnum newOrder)
Definition: Quantity.cpp:27
Holder(const OrderEnum order, const TValue &defaultValue, const Size size)
Definition: Quantity.h:71
INLINE StaticArray< Array< TValue > &, 3 > getAll()
Definition: Quantity.h:128
INLINE const Array< TValue > & getDt() const
Definition: Quantity.h:113
INLINE const Array< TValue > & getD2t() const
Definition: Quantity.h:123
INLINE OrderEnum getOrderEnum() const
Returns number of derivatives stored within the quantity.
Definition: Quantity.h:85
INLINE Array< TValue > & getValue()
Definition: Quantity.h:100
INLINE Size size() const
Returns size of the stored arrays (=number of particles).
Definition: Quantity.h:95
Holder clone(const Flags< VisitorEnum > flags) const
Definition: Quantity.cpp:8
INLINE ValueEnum getValueEnum() const
Return type of quantity values.
Definition: Quantity.h:90
INLINE Array< TValue > & getDt()
Definition: Quantity.h:108
INLINE StaticArray< const Array< TValue > &, 3 > getAll() const
Definition: Quantity.h:141
Wrapper of an integral value providing functions for reading and modifying individual bits.
Definition: Flags.h:20
Object representing a 1D interval of real numbers.
Definition: Interval.h:17
Generic container for storing scalar, vector or tensor quantity and its derivatives.
Definition: Quantity.h:200
INLINE const Array< TValue > & getDt() const
Returns a reference to array of first derivatives of quantity, const version.
Definition: Quantity.h:313
INLINE Size size() const
Returns the size of the quantity (number of particles)
Definition: Quantity.h:278
void setOrder(const OrderEnum order)
Definition: Quantity.h:297
Quantity()=default
Constructs an empty quantity.
Quantity createZeros(const Size particleCnt) const
Creates a new quantity with the same type and order as this one.
Definition: Quantity.h:259
Quantity clone(const Flags< VisitorEnum > flags) const
Clones all buffers contained by the quantity, or optionally only selected ones.
Definition: Quantity.h:252
INLINE const Array< TValue > & getD2t() const
Returns a reference to array of second derivatives of quantity, const version.
Definition: Quantity.h:329
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
INLINE const Array< TValue > & getValue() const
Returns a reference to array of quantity values, const version.
Definition: Quantity.h:293
StaticArray< Array< TValue > &, 3 > getAll()
Returns all buffers of given type stored in this quantity.
Definition: Quantity.h:338
StaticArray< const Array< TValue > &, 3 > getAll() const
Definition: Quantity.h:343
INLINE Array< TValue > & getValue()
Returns a reference to array of quantity values.
Definition: Quantity.h:287
void clamp(const TIndexSequence &sequence, const Interval range)
Definition: Quantity.h:351
Quantity(const OrderEnum order, const TValue &defaultValue, const Size size)
Creates a quantity given number of particles and default value of the quantity.
Definition: Quantity.h:226
INLINE Array< TValue > & getDt()
Returns a reference to array of first derivatives of quantity.
Definition: Quantity.h:307
void swap(Quantity &other, const Flags< VisitorEnum > flags)
Swap quantity (or selected part of it) with other quantity.
Definition: Quantity.h:269
ValueEnum getValueEnum() const
Returns the value order of the quantity.
Definition: Quantity.h:246
Quantity(const OrderEnum order, Array< TValue > &&values)
Creates a quantity from an array of values.
Definition: Quantity.h:233
Array with fixed number of allocated elements.
Definition: StaticArray.h:19
Variant, an implementation of type-safe union, similar to std::variant or boost::variant.
Definition: Variant.h:171
void swap(Variant &other)
Swaps value stored in the variant with value of different variant.
Definition: Variant.h:290
INLINE Size getTypeIdx() const
Returns index of type currently stored in variant.
Definition: Variant.h:310
INLINE T & get()
Returns the stored value.
Definition: Variant.h:335
Overload of std::swap for Sph::Array.
Definition: Array.h:578
Convert type to ValueType enum.
Object with deleted copy constructor and copy operator.
Definition: Object.h:54