ls1-MarDyn
ls1-MarDyn molecular dynamics code
CellDataSoA.h
1/*
2 * CellDataSoA.h
3 *
4 * @Date: 25.03.2013
5 * @Author: eckhardw
6 */
7
8#ifndef CELLDATASOA_H_
9#define CELLDATASOA_H_
10
11#include "CellDataSoABase.h"
12#include "utils/AlignedArrayTriplet.h"
13#include "utils/ConcatenatedSites.h"
15#include <cstdint>
16#include <array>
17
23
24 //for better readability:
27
28
29public:
30 CellDataSoA(size_t mol_arg, size_t ljc_arg, size_t charges_arg, size_t dipoles_arg, size_t quadrupoles_arg) {
31 resize(mol_arg, ljc_arg, charges_arg, dipoles_arg, quadrupoles_arg);
32 }
33
37 enum class QuantityType {
38 MOL_POSITION, CENTER_POSITION, FORCE, VIRIAL
39 };
40
41 size_t _ljc_num;
42 size_t _charges_num;
43 size_t _dipoles_num;
44 size_t _quadrupoles_num;
45 size_t _centers_num;
46
47 // entries per molecule
49 AlignedArray<int> _mol_ljc_num;
50 AlignedArray<int> _mol_charges_num;
51 AlignedArray<int> _mol_dipoles_num;
52 AlignedArray<int> _mol_quadrupoles_num;
53
54 // entries per center
59
60 // entries per lj center
62
63 // entries per charge
65
66 // entries per dipole
67 AlignedArray<vcp_real_calc> _dipoles_p; // dipole moment
68 AlignedArrayTriplet<vcp_real_calc> _dipoles_e; // orientation vector of dipole moment
69 AlignedArrayTriplet<vcp_real_accum> _dipoles_M; // torque vector
70
71 // entries per quadrupole
72 AlignedArray<vcp_real_calc> _quadrupoles_m; // quadrupole moment
73 AlignedArrayTriplet<vcp_real_calc> _quadrupoles_e; // orientation vector of quadrupole moment
74 AlignedArrayTriplet<vcp_real_accum> _quadrupoles_M; // torque vector
75
76
85 vcp_inline vcp_real_calc* getBeginCalc(QuantityType qt, SiteType st, CoordinateType coord) {
86 mardyn_assert(qt == QuantityType::MOL_POSITION or qt == QuantityType::CENTER_POSITION);
87 ConcatenatedSites<vcp_real_calc> * thisQuantity = resolveQuantityCalc(qt);
88 return thisQuantity->getBeginPointer(st, coord);
89 }
90
91 vcp_inline const vcp_real_calc* getBeginCalc(QuantityType qt, SiteType st, CoordinateType coord) const {
92 mardyn_assert(qt == QuantityType::MOL_POSITION or qt == QuantityType::CENTER_POSITION);
93 const ConcatenatedSites<vcp_real_calc> * thisQuantity = resolveQuantityCalc(qt);
94 return thisQuantity->getBeginPointer(st, coord);
95 }
96
97 vcp_inline vcp_real_accum* getBeginAccum(QuantityType qt, SiteType st, CoordinateType coord) {
98 mardyn_assert(qt == QuantityType::FORCE or qt == QuantityType::VIRIAL);
99 ConcatenatedSites<vcp_real_accum> * thisQuantity = resolveQuantityAccum(qt);
100 return thisQuantity->getBeginPointer(st, coord);
101 }
102
103 vcp_inline const vcp_real_accum* getBeginAccum(QuantityType qt, SiteType st, CoordinateType coord) const {
104 mardyn_assert(qt == QuantityType::FORCE or qt == QuantityType::VIRIAL);
105 const ConcatenatedSites<vcp_real_accum> * thisQuantity = resolveQuantityAccum(qt);
106 return thisQuantity->getBeginPointer(st, coord);
107 }
108
112 vcp_inline std::array<vcp_real_calc, 3> getTripletCalc(QuantityType qt, SiteType st, size_t index) const {
113 const ConcatenatedSites<vcp_real_calc>* thisQuantity = resolveQuantityCalc(qt);
114 return thisQuantity->getTriplet(st, index);
115 }
116
117 vcp_inline std::array<vcp_real_accum, 3> getTripletAccum(QuantityType qt, SiteType st, size_t index) const {
118 const ConcatenatedSites<vcp_real_accum>* thisQuantity = resolveQuantityAccum(qt);
119 return thisQuantity->getTriplet(st, index);
120 }
121
125 vcp_inline void setTripletCalc(std::array<vcp_real_calc, 3> t, QuantityType qt, SiteType st, size_t index) {
126 ConcatenatedSites<vcp_real_calc>* thisQuantity = resolveQuantityCalc(qt);
127 thisQuantity->setTriplet(t, st, index);
128 }
129
130 vcp_inline void setTripletAccum(std::array<vcp_real_accum, 3> t, QuantityType qt, SiteType st, size_t index) {
131 ConcatenatedSites<vcp_real_accum>* thisQuantity = resolveQuantityAccum(qt);
132 thisQuantity->setTriplet(t, st, index);
133 }
134
138 void pushBackLJC(const size_t index, std::array<vcp_real_calc,3> moleculePos, std::array<vcp_real_calc,3> centerPos, vcp_ljc_id_t lookUpIndex) {
139 setTripletCalc(moleculePos, QuantityType::MOL_POSITION, SiteType::LJC, index);
140 setTripletCalc(centerPos, QuantityType::CENTER_POSITION, SiteType::LJC, index);
141 _ljc_id[index] = lookUpIndex;
142 }
143
147 void pushBackCharge(const size_t index, std::array<vcp_real_calc,3> moleculePos, std::array<vcp_real_calc,3> centerPos, vcp_real_calc charge) {
148 setTripletCalc(moleculePos, QuantityType::MOL_POSITION, SiteType::CHARGE, index);
149 setTripletCalc(centerPos, QuantityType::CENTER_POSITION, SiteType::CHARGE, index);
150 _charges_q[index] = charge;
151 }
152
156 void pushBackDipole(const size_t index, std::array<vcp_real_calc,3> moleculePos, std::array<vcp_real_calc,3> centerPos,
157 vcp_real_calc dipoleMoment, std::array<vcp_real_calc,3> orientation) {
158 setTripletCalc(moleculePos, QuantityType::MOL_POSITION, SiteType::DIPOLE, index);
159 setTripletCalc(centerPos, QuantityType::CENTER_POSITION, SiteType::DIPOLE, index);
160 _dipoles_p[index] = dipoleMoment;
161 _dipoles_e.x(index) = orientation[0];
162 _dipoles_e.y(index) = orientation[1];
163 _dipoles_e.z(index) = orientation[2];
164 }
165
169 void pushBackQuadrupole(const size_t index, std::array<vcp_real_calc,3> moleculePos, std::array<vcp_real_calc,3> centerPos,
170 vcp_real_calc quadrupoleMoment, std::array<vcp_real_calc,3> orientation) {
171 setTripletCalc(moleculePos, QuantityType::MOL_POSITION, SiteType::QUADRUPOLE, index);
172 setTripletCalc(centerPos, QuantityType::CENTER_POSITION, SiteType::QUADRUPOLE, index);
173 _quadrupoles_m[index] = quadrupoleMoment;
174 _quadrupoles_e.x(index) = orientation[0];
175 _quadrupoles_e.y(index) = orientation[1];
176 _quadrupoles_e.z(index) = orientation[2];
177 }
178
179 void vcp_inline initDistLookupPointers(
180 AlignedArray<vcp_lookupOrMask_single>& centers_dist_lookup,
181 vcp_lookupOrMask_single*& ljc_dist_lookup,
182 vcp_lookupOrMask_single*& charges_dist_lookup,
183 vcp_lookupOrMask_single*& dipoles_dist_lookup,
184 vcp_lookupOrMask_single*& quadrupoles_dist_lookup) const {
185
186 size_t ljc_size = AlignedArray<vcp_real_calc>::_round_up(_ljc_num);
187 size_t charges_size = AlignedArray<vcp_real_calc>::_round_up(_charges_num);
188 size_t dipoles_size = AlignedArray<vcp_real_calc>::_round_up(_dipoles_num);
189 size_t quadrupoles_size = AlignedArray<vcp_real_calc>::_round_up(_quadrupoles_num);
190 size_t centers_size = ljc_size + charges_size + dipoles_size + quadrupoles_size;
191
192 centers_dist_lookup.resize_zero_shrink(centers_size);
193 setPaddingToZero(centers_dist_lookup);
194
195 ljc_dist_lookup = centers_dist_lookup;
196 charges_dist_lookup = ljc_dist_lookup + (ljc_size + VCP_INDICES_PER_LOOKUP_SINGLE_M1)/VCP_INDICES_PER_LOOKUP_SINGLE;
197 dipoles_dist_lookup = charges_dist_lookup + (charges_size + VCP_INDICES_PER_LOOKUP_SINGLE_M1)/VCP_INDICES_PER_LOOKUP_SINGLE;
198 quadrupoles_dist_lookup = dipoles_dist_lookup + (dipoles_size + VCP_INDICES_PER_LOOKUP_SINGLE_M1)/VCP_INDICES_PER_LOOKUP_SINGLE;
199 }
200
201 void vcp_inline initDistLookupPointersSingle(
202 AlignedArray<vcp_lookupOrMask_single>& centers_dist_lookup,
203 vcp_lookupOrMask_single*& sites_dist_lookup,
204 size_t sites_num) const {
205
206 centers_dist_lookup.resize_zero_shrink(sites_num, true, false);
207 sites_dist_lookup = centers_dist_lookup;
208 }
209
210 void resize(size_t molecules_arg, size_t ljcenters_arg, size_t charges_arg, size_t dipoles_arg, size_t quadrupoles_arg) {
211// const bool allow_shrink = false; // TODO shrink at some point in the future
212
213 setMolNum(molecules_arg);
214 _ljc_num = ljcenters_arg;
215 _charges_num = charges_arg;
216 _dipoles_num = dipoles_arg;
217 _quadrupoles_num = quadrupoles_arg;
218
219 // entries per molecule
220 _mol_pos .resize_zero_shrink(getMolNum());
221 _mol_ljc_num .resize_zero_shrink(getMolNum());
222 _mol_charges_num .resize_zero_shrink(getMolNum());
223 _mol_dipoles_num .resize_zero_shrink(getMolNum());
224 _mol_quadrupoles_num.resize_zero_shrink(getMolNum());
225
226 _centers_m_r.resize(ljcenters_arg, charges_arg, dipoles_arg, quadrupoles_arg);
227 _centers_r .resize(ljcenters_arg, charges_arg, dipoles_arg, quadrupoles_arg);
228 _centers_f .resize(ljcenters_arg, charges_arg, dipoles_arg, quadrupoles_arg);
229 _centers_V .resize(ljcenters_arg, charges_arg, dipoles_arg, quadrupoles_arg);
230
231 // entries per lj center
232 _ljc_id.resize_zero_shrink(_ljc_num, true);
233
234 // entries per charge
235 _charges_q.resize_zero_shrink(_charges_num);
236
237 // entries per dipole
238 _dipoles_p.resize_zero_shrink(_dipoles_num);
239 _dipoles_e.resize_zero_shrink(_dipoles_num);
240 _dipoles_M.resize_zero_shrink(_dipoles_num);
241
242 // entries per quadrupole
243 _quadrupoles_m.resize_zero_shrink(_quadrupoles_num);
244 _quadrupoles_e.resize_zero_shrink(_quadrupoles_num);
245 _quadrupoles_M.resize_zero_shrink(_quadrupoles_num);
246
247 }
248
249 size_t getDynamicSize() const {
250 size_t total = 0;
251
252 total += _mol_pos.get_dynamic_memory();
253 total += _mol_ljc_num.get_dynamic_memory();
254 total += _mol_charges_num.get_dynamic_memory();
255 total += _mol_dipoles_num.get_dynamic_memory();
256 total += _mol_quadrupoles_num.get_dynamic_memory();
257
258 total += _centers_m_r.get_dynamic_memory();
259 total += _centers_r.get_dynamic_memory();
260 total += _centers_f.get_dynamic_memory();
261 total += _centers_V.get_dynamic_memory();
262
263 total += _dipoles_p.get_dynamic_memory();
264 total += _dipoles_e.get_dynamic_memory();
265 total += _dipoles_M.get_dynamic_memory();
266
267 total += _quadrupoles_m.get_dynamic_memory();
268 total += _quadrupoles_e.get_dynamic_memory();
269 total += _quadrupoles_M.get_dynamic_memory();
270
271 return total;
272 }
273
274private:
275
276 vcp_inline void setPaddingToZero(AlignedArray<vcp_lookupOrMask_single>& t) const {
277 size_t ljc_size = AlignedArray<vcp_real_calc>::_round_up(_ljc_num);
278 size_t charges_size = AlignedArray<vcp_real_calc>::_round_up(_charges_num);
279 size_t dipoles_size = AlignedArray<vcp_real_calc>::_round_up(_dipoles_num);
280
281 t.zero(_ljc_num); // TODO: this call actually sets all after _ljc_num to zero. The subsequent calls are not necessary..?
282 t.zero(ljc_size + _charges_num);
283 t.zero(ljc_size + charges_size + _dipoles_num);
284 t.zero(ljc_size + charges_size + dipoles_size + _quadrupoles_num);
285 }
286
290 vcp_inline ConcatenatedSites<vcp_real_calc>* resolveQuantityCalc(QuantityType qt) {
291 mardyn_assert(qt == QuantityType::MOL_POSITION or qt == QuantityType::CENTER_POSITION);
292 ConcatenatedSites<vcp_real_calc>* returnQuantity;
293 switch(qt) {
294 case QuantityType::MOL_POSITION:
295 returnQuantity = &_centers_m_r;
296 break;
297 case QuantityType::CENTER_POSITION:
298 returnQuantity = &_centers_r;
299 break;
300 default:
301 returnQuantity = nullptr;
302 break;
303 }
304
305 mardyn_assert(returnQuantity != nullptr);
306 return returnQuantity;
307 }
308
309 vcp_inline ConcatenatedSites<vcp_real_accum>* resolveQuantityAccum(QuantityType qt) {
310 mardyn_assert(qt == QuantityType::FORCE or qt == QuantityType::VIRIAL);
311 ConcatenatedSites<vcp_real_accum>* returnQuantity;
312 switch(qt) {
313 case QuantityType::FORCE:
314 returnQuantity = &_centers_f;
315 break;
316 case QuantityType::VIRIAL:
317 returnQuantity = &_centers_V;
318 break;
319 default:
320 returnQuantity = nullptr;
321 break;
322 }
323
324 mardyn_assert(returnQuantity != nullptr);
325 return returnQuantity;
326 }
327
328 vcp_inline const ConcatenatedSites<vcp_real_calc>* resolveQuantityCalc(QuantityType qt) const {
329 mardyn_assert(qt == QuantityType::MOL_POSITION or qt == QuantityType::CENTER_POSITION);
330 const ConcatenatedSites<vcp_real_calc>* returnQuantity;
331 switch(qt) {
332 case QuantityType::MOL_POSITION:
333 returnQuantity = &_centers_m_r;
334 break;
335 case QuantityType::CENTER_POSITION:
336 returnQuantity = &_centers_r;
337 break;
338 default:
339 returnQuantity = nullptr;
340 break;
341 }
342
343 mardyn_assert(returnQuantity != nullptr);
344 return returnQuantity;
345 }
346
347 vcp_inline const ConcatenatedSites<vcp_real_accum>* resolveQuantityAccum(QuantityType qt) const {
348 mardyn_assert(qt == QuantityType::FORCE or qt == QuantityType::VIRIAL);
349 const ConcatenatedSites<vcp_real_accum>* returnQuantity;
350 switch(qt) {
351 case QuantityType::FORCE:
352 returnQuantity = &_centers_f;
353 break;
354 case QuantityType::VIRIAL:
355 returnQuantity = &_centers_V;
356 break;
357 default:
358 returnQuantity = nullptr;
359 break;
360 }
361
362 mardyn_assert(returnQuantity != nullptr);
363 return returnQuantity;
364 }
365
366};
367
368#endif /* CELLDATASOA_H_ */
Defines the length of the vectors and the corresponding functions.
Definition: AlignedArrayTriplet.h:15
An aligned array.
Definition: AlignedArray.h:75
size_t get_dynamic_memory() const
Return amount of allocated storage + .
Definition: AlignedArray.h:225
Definition: CellDataSoABase.h:13
Structure of Arrays for vectorized force calculation.
Definition: CellDataSoA.h:22
vcp_inline std::array< vcp_real_calc, 3 > getTripletCalc(QuantityType qt, SiteType st, size_t index) const
Get a triplet of data from a ConcatenatedSites at specific index.
Definition: CellDataSoA.h:112
void pushBackLJC(const size_t index, std::array< vcp_real_calc, 3 > moleculePos, std::array< vcp_real_calc, 3 > centerPos, vcp_ljc_id_t lookUpIndex)
Add a set of LJC-data at position index.
Definition: CellDataSoA.h:138
void pushBackQuadrupole(const size_t index, std::array< vcp_real_calc, 3 > moleculePos, std::array< vcp_real_calc, 3 > centerPos, vcp_real_calc quadrupoleMoment, std::array< vcp_real_calc, 3 > orientation)
Add a set of quadrupole-data at position index.
Definition: CellDataSoA.h:169
void pushBackDipole(const size_t index, std::array< vcp_real_calc, 3 > moleculePos, std::array< vcp_real_calc, 3 > centerPos, vcp_real_calc dipoleMoment, std::array< vcp_real_calc, 3 > orientation)
Add a set of dipole-data at position index.
Definition: CellDataSoA.h:156
vcp_inline vcp_real_calc * getBeginCalc(QuantityType qt, SiteType st, CoordinateType coord)
Get Pointer to the beginning of the specified data.
Definition: CellDataSoA.h:85
void pushBackCharge(const size_t index, std::array< vcp_real_calc, 3 > moleculePos, std::array< vcp_real_calc, 3 > centerPos, vcp_real_calc charge)
Add a set of charge-data at position index.
Definition: CellDataSoA.h:147
vcp_inline void setTripletCalc(std::array< vcp_real_calc, 3 > t, QuantityType qt, SiteType st, size_t index)
Set a triplet of data in a ConcatenatedSites to specified values.
Definition: CellDataSoA.h:125
Class to manage the storage of ljc-, charge-, dipole- and quadrupole-data in one single AlignedArrayT...
Definition: ConcatenatedSites.h:37
void resize(size_t ljc_num, size_t charges_num, size_t dipoles_num, size_t quadrupoles_num)
Resize the ConcatenatedSites to have enough space for the given number of elements.
Definition: ConcatenatedSites.h:151
vcp_inline void setTriplet(std::array< T, 3 > values, ConcSites::SiteType st, size_t index)
Set the value triplet X,Y,Z of ConcSites::SiteType st at position index to given values.
Definition: ConcatenatedSites.h:138
vcp_inline T * getBeginPointer(ConcSites::SiteType st, ConcSites::CoordinateType coord)
Get a Pointer to the beginning of the specified data.
Definition: ConcatenatedSites.h:55
vcp_inline std::array< T, 3 > getTriplet(ConcSites::SiteType st, size_t index) const
Get the value triplet X,Y,Z of ConcSites::SiteType st at position index.
Definition: ConcatenatedSites.h:127
size_t get_dynamic_memory() const
Get the size of currently occupied memory.
Definition: ConcatenatedSites.h:171
SiteType
Specify which of the 4 data-categories is needed.
Definition: ConcatenatedSites.h:25
CoordinateType
What coordinate would you like to have?
Definition: ConcatenatedSites.h:18