1 #include "quantities/Quantity.h"
2 
3 NAMESPACE_SPH_BEGIN
4 
5 namespace Detail {
6 
7 template <typename TValue>
clone(const Flags<VisitorEnum> flags) const8 Holder<TValue> Holder<TValue>::clone(const Flags<VisitorEnum> flags) const {
9     Holder cloned(order);
10     visitConst(cloned, flags, [](const Array<TValue>& array, Array<TValue>& clonedArray) {
11         clonedArray = array.clone();
12     });
13     return cloned;
14 }
15 
16 template <typename TValue>
createZeros(const Size particleCnt) const17 Holder<TValue> Holder<TValue>::createZeros(const Size particleCnt) const {
18     return Holder(order, TValue(0._f), particleCnt);
19 }
20 
21 template <typename TValue>
swap(Holder & other,Flags<VisitorEnum> flags)22 void Holder<TValue>::swap(Holder& other, Flags<VisitorEnum> flags) {
23     visitMutable(other, flags, [](Array<TValue>& ar1, Array<TValue>& ar2) { ar1.swap(ar2); });
24 }
25 
26 template <typename TValue>
setOrder(const OrderEnum newOrder)27 void Holder<TValue>::setOrder(const OrderEnum newOrder) {
28     SPH_ASSERT(Size(newOrder) > Size(order));
29     if (newOrder == OrderEnum::SECOND) {
30         d2v_dt2.resize(v.size());
31         d2v_dt2.fill(TValue(0._f));
32     } else if (newOrder == OrderEnum::FIRST) {
33         dv_dt.resize(v.size());
34         dv_dt.fill(TValue(0._f));
35     }
36     order = newOrder;
37 }
38 
39 template <typename TValue>
initDerivatives(const Size size)40 void Holder<TValue>::initDerivatives(const Size size) {
41     switch (order) {
42     case OrderEnum::SECOND:
43         d2v_dt2.resize(size);
44         d2v_dt2.fill(TValue(0._f));
45         dv_dt.resize(size);
46         dv_dt.fill(TValue(0._f));
47         // [[fallthrough]] - somehow doesn't work with gcc6
48         break;
49     case OrderEnum::FIRST:
50         dv_dt.resize(size);
51         dv_dt.fill(TValue(0._f));
52         break;
53     default:
54         break;
55     }
56 }
57 
58 template <typename TValue>
59 template <typename TFunctor>
visitMutable(Holder & other,const Flags<VisitorEnum> flags,TFunctor && functor)60 void Holder<TValue>::visitMutable(Holder& other, const Flags<VisitorEnum> flags, TFunctor&& functor) {
61     if (flags.hasAny(VisitorEnum::ZERO_ORDER,
62             VisitorEnum::ALL_BUFFERS,
63             VisitorEnum::ALL_VALUES,
64             VisitorEnum::STATE_VALUES)) {
65         functor(v, other.v);
66     }
67     switch (order) {
68     case OrderEnum::FIRST:
69         if (flags.hasAny(
70                 VisitorEnum::FIRST_ORDER, VisitorEnum::ALL_BUFFERS, VisitorEnum::HIGHEST_DERIVATIVES)) {
71             functor(dv_dt, other.dv_dt);
72         }
73         break;
74     case OrderEnum::SECOND:
75         if (flags.hasAny(VisitorEnum::ALL_BUFFERS, VisitorEnum::STATE_VALUES)) {
76             functor(dv_dt, other.dv_dt);
77         }
78         if (flags.hasAny(
79                 VisitorEnum::ALL_BUFFERS, VisitorEnum::SECOND_ORDER, VisitorEnum::HIGHEST_DERIVATIVES)) {
80             functor(d2v_dt2, other.d2v_dt2);
81         }
82         break;
83     default:
84         break;
85     }
86 }
87 
88 template <typename TValue>
89 template <typename TFunctor>
visitConst(Holder & other,const Flags<VisitorEnum> flags,TFunctor && functor) const90 void Holder<TValue>::visitConst(Holder& other, const Flags<VisitorEnum> flags, TFunctor&& functor) const {
91     const_cast<Holder*>(this)->visitMutable(other, flags, std::forward<TFunctor>(functor));
92 }
93 
94 template class Holder<Size>;
95 template class Holder<Float>;
96 template class Holder<Vector>;
97 template class Holder<SymmetricTensor>;
98 template class Holder<TracelessTensor>;
99 template class Holder<Tensor>;
100 
101 } // namespace Detail
102 
103 
104 NAMESPACE_SPH_END
105