1 #include "quantities/Particle.h"
2 #include "quantities/Quantity.h"
3 #include "quantities/Storage.h"
4
5 NAMESPACE_SPH_BEGIN
6
7 struct ParticleVisitor {
8 FlatMap<QuantityId, Particle::InternalQuantityData>& data;
9
10 template <typename TValue>
visitParticleVisitor11 void visit(const QuantityId id, const Quantity& q, const Size idx) {
12 const auto& values = q.getAll<TValue>();
13 switch (q.getOrderEnum()) {
14 case OrderEnum::SECOND:
15 data[id].d2t = values[2][idx];
16 SPH_FALLTHROUGH
17 case OrderEnum::FIRST:
18 data[id].dt = values[1][idx];
19 SPH_FALLTHROUGH
20 case OrderEnum::ZERO:
21 data[id].value = values[0][idx];
22 break;
23 default:
24 NOT_IMPLEMENTED;
25 }
26 }
27 };
28
29
Particle(const Storage & storage,const Size idx)30 Particle::Particle(const Storage& storage, const Size idx)
31 : idx(idx) {
32 for (ConstStorageElement i : storage.getQuantities()) {
33 quantities.insert(i.id, InternalQuantityData{});
34
35 ParticleVisitor visitor{ quantities };
36 dispatch(i.quantity.getValueEnum(), visitor, i.id, i.quantity, idx);
37 }
38 }
39
Particle(const QuantityId id,const Dynamic & value,const Size idx)40 Particle::Particle(const QuantityId id, const Dynamic& value, const Size idx)
41 : idx(idx) {
42 quantities.insert(id, InternalQuantityData{});
43 quantities[id].value = value;
44 }
45
Particle(const Particle & other)46 Particle::Particle(const Particle& other) {
47 *this = other;
48 }
49
Particle(Particle && other)50 Particle::Particle(Particle&& other) {
51 *this = std::move(other);
52 }
53
operator =(const Particle & other)54 Particle& Particle::operator=(const Particle& other) {
55 quantities = other.quantities.clone();
56 material = other.material.clone();
57 idx = other.idx;
58 return *this;
59 }
60
operator =(Particle && other)61 Particle& Particle::operator=(Particle&& other) {
62 quantities = std::move(other.quantities);
63 material = std::move(other.material);
64 idx = other.idx;
65 return *this;
66 }
67
addValue(const QuantityId id,const Dynamic & value)68 Particle& Particle::addValue(const QuantityId id, const Dynamic& value) {
69 if (!quantities.contains(id)) {
70 quantities.insert(id, InternalQuantityData{});
71 }
72 quantities[id].value = value;
73 return *this;
74 }
75
addDt(const QuantityId id,const Dynamic & value)76 Particle& Particle::addDt(const QuantityId id, const Dynamic& value) {
77 if (!quantities.contains(id)) {
78 quantities.insert(id, InternalQuantityData{});
79 }
80 quantities[id].dt = value;
81 return *this;
82 }
83
addD2t(const QuantityId id,const Dynamic & value)84 Particle& Particle::addD2t(const QuantityId id, const Dynamic& value) {
85 if (!quantities.contains(id)) {
86 quantities.insert(id, InternalQuantityData{});
87 }
88 quantities[id].d2t = value;
89 return *this;
90 }
91
addParameter(const BodySettingsId id,const Dynamic & value)92 Particle& Particle::addParameter(const BodySettingsId id, const Dynamic& value) {
93 if (!material.contains(id)) {
94 material.insert(id, NOTHING);
95 }
96 material[id] = value;
97 return *this;
98 }
99
100
getValue(const QuantityId id) const101 Dynamic Particle::getValue(const QuantityId id) const {
102 Optional<const InternalQuantityData&> quantity = quantities.tryGet(id);
103 SPH_ASSERT(quantity);
104 return quantity->value;
105 }
106
getDt(const QuantityId id) const107 Dynamic Particle::getDt(const QuantityId id) const {
108 Optional<const InternalQuantityData&> quantity = quantities.tryGet(id);
109 SPH_ASSERT(quantity);
110 return quantity->dt;
111 }
112
getD2t(const QuantityId id) const113 Dynamic Particle::getD2t(const QuantityId id) const {
114 Optional<const InternalQuantityData&> quantity = quantities.tryGet(id);
115 SPH_ASSERT(quantity);
116 return quantity->d2t;
117 }
118
getParameter(const BodySettingsId id) const119 Dynamic Particle::getParameter(const BodySettingsId id) const {
120 Optional<const Dynamic&> value = material.tryGet(id);
121 SPH_ASSERT(value);
122 return value.value();
123 }
124
125
QuantityIterator(const ActIterator iterator,Badge<Particle>)126 Particle::QuantityIterator::QuantityIterator(const ActIterator iterator, Badge<Particle>)
127 : iter(iterator) {}
128
operator ++()129 Particle::QuantityIterator& Particle::QuantityIterator::operator++() {
130 ++iter;
131 return *this;
132 }
133
operator *() const134 Particle::QuantityData Particle::QuantityIterator::operator*() const {
135 const InternalQuantityData& internal = iter->value();
136 DynamicId type;
137 if (internal.value) {
138 type = internal.value.getType();
139 SPH_ASSERT(internal.dt.empty() || internal.dt.getType() == type);
140 SPH_ASSERT(internal.d2t.empty() || internal.d2t.getType() == type);
141 } else if (internal.dt) {
142 type = internal.dt.getType();
143 SPH_ASSERT(internal.d2t.empty() || internal.d2t.getType() == type);
144 } else {
145 SPH_ASSERT(internal.d2t);
146 type = internal.d2t.getType();
147 }
148 return { iter->key(), type, internal.value, internal.dt, internal.d2t };
149 }
150
operator !=(const QuantityIterator & other) const151 bool Particle::QuantityIterator::operator!=(const QuantityIterator& other) const {
152 return iter != other.iter;
153 }
154
QuantitySequence(const Particle & particle)155 Particle::QuantitySequence::QuantitySequence(const Particle& particle)
156 : first(particle.quantities.begin(), {})
157 , last(particle.quantities.end(), {}) {}
158
begin() const159 Particle::QuantityIterator Particle::QuantitySequence::begin() const {
160 return first;
161 }
162
end() const163 Particle::QuantityIterator Particle::QuantitySequence::end() const {
164 return last;
165 }
166
getQuantities() const167 Particle::QuantitySequence Particle::getQuantities() const {
168 return QuantitySequence(*this);
169 }
170
171
ParamIterator(const ActIterator iterator,Badge<Particle>)172 Particle::ParamIterator::ParamIterator(const ActIterator iterator, Badge<Particle>)
173 : iter(iterator) {}
174
operator ++()175 Particle::ParamIterator& Particle::ParamIterator::operator++() {
176 ++iter;
177 return *this;
178 }
179
operator *() const180 Particle::ParamData Particle::ParamIterator::operator*() const {
181 return { iter->key(), iter->value() };
182 }
183
operator !=(const ParamIterator & other) const184 bool Particle::ParamIterator::operator!=(const ParamIterator& other) const {
185 return iter != other.iter;
186 }
187
188
ParamSequence(const Particle & particle)189 Particle::ParamSequence::ParamSequence(const Particle& particle)
190 : first(particle.material.begin(), {})
191 , last(particle.material.end(), {}) {}
192
begin() const193 Particle::ParamIterator Particle::ParamSequence::begin() const {
194 return first;
195 }
196
end() const197 Particle::ParamIterator Particle::ParamSequence::end() const {
198 return last;
199 }
200
getParameters() const201 Particle::ParamSequence Particle::getParameters() const {
202 return ParamSequence(*this);
203 }
204
205 NAMESPACE_SPH_END
206