ls1-MarDyn
ls1-MarDyn molecular dynamics code
C08BasedTraversals.h
1/*
2 * C08BasedTraversals.h
3 *
4 * Created on: 16 May 2017
5 * Author: tchipevn
6 */
7
8#ifndef SRC_PARTICLECONTAINER_LINKEDCELLTRAVERSALS_C08BASEDTRAVERSALS_H_
9#define SRC_PARTICLECONTAINER_LINKEDCELLTRAVERSALS_C08BASEDTRAVERSALS_H_
10
11#include "particleContainer/LinkedCellTraversals/CellPairTraversals.h"
12#include "particleContainer/adapter/CellProcessor.h"
13#include "utils/threeDimensionalMapping.h"
14#include "WrapOpenMP.h"
15
16template <class CellTemplate>
17class C08BasedTraversals : public CellPairTraversals<CellTemplate> {
18public:
20 std::vector<CellTemplate>& cells,
21 const std::array<unsigned long, 3>& dims) :
23 computeOffsets();
24 }
25 virtual ~~C08BasedTraversals() {
26 }
27
28 virtual void rebuild(std::vector<CellTemplate> &cells,
29 const std::array<unsigned long, 3> &dims, double cellLength[3], double cutoff,
31 CellPairTraversals<CellTemplate>::rebuild(cells, dims, cellLength, cutoff, data);
32 computeOffsets();
33 };
34
35protected:
36 template <bool eighthShell=false>
37 void processBaseCell(CellProcessor& cellProcessor, unsigned long cellIndex) const;
38
39private:
40 void computeOffsets();
41
42 std::array<std::pair<unsigned long, unsigned long>, 14> _cellPairOffsets8Pack;
43 std::array<unsigned long, 8> _cellOffsets8Pack;
44};
45
46template<class CellTemplate>
47template<bool eighthShell>
48void C08BasedTraversals<CellTemplate>::processBaseCell(CellProcessor& cellProcessor, unsigned long baseIndex) const {
49 // leads to performance degradation!
50 //#ifdef ENABLE_REDUCED_MEMORY_MODE
51 // for (int i = 0; i < 8; ++i) {
52 // this->_cells->at(baseIndex + _cellOffsets[i]).prefetchForForce();
53 // }
54 //#endif /* ENABLE_REDUCED_MEMORY_MODE */
55
56 using std::pair;
57
58#ifndef NDEBUG
59 // map to 3D index and check that we're not on the "right" boundary
60 std::array<unsigned long, 3> threeDIndex = threeDimensionalMapping::oneToThreeD(baseIndex, this->_dims);
61 for (int d = 0; d < 3; ++d) {
62 mardyn_assert(threeDIndex[d] != this->_dims[d]-1);
63 }
64#endif
65
66 const int num_pairs = _cellPairOffsets8Pack.size();
67 for(int j = 0; j < num_pairs; ++j) {
68 pair<long, long> current_pair = _cellPairOffsets8Pack[j];
69
70 unsigned offset1 = current_pair.first;
71 unsigned cellIndex1 = baseIndex + offset1;
72
73 unsigned offset2 = current_pair.second;
74 unsigned cellIndex2 = baseIndex + offset2;
75
76 CellTemplate& cell1 = this->_cells->at(cellIndex1);
77 CellTemplate& cell2 = this->_cells->at(cellIndex2);
78
79 if((not eighthShell) and cell1.isHaloCell() and cell2.isHaloCell()) {
80 continue;
81 }
82
83 if(cellIndex1 == cellIndex2) {
84 cellProcessor.processCell(cell1);
85 }
86 else {
87 if(not eighthShell) {
88 if (!cell1.isHaloCell()) {
89 cellProcessor.processCellPair(cell1, cell2);
90 } else {
91 cellProcessor.processCellPair(cell2, cell1);
92 }
93 } else {
94 // if we use eighthShell, we have to sum everything. also we don't care about order of the cells!
95 cellProcessor.processCellPair(cell1, cell2, true);
96 }
97 }
98 }
99}
100
101template<class CellTemplate>
103 using threeDimensionalMapping::threeToOneD;
104 using std::make_pair;
105
106 std::array<long, 3> dims;
107 for (int d = 0; d < 3; ++d) {
108 dims[d] = static_cast<long>(this->_dims[d]);
109 }
110
111 long int o = threeToOneD(0l, 0l, 0l, dims); // origin
112 long int x = threeToOneD(1l, 0l, 0l, dims); // displacement to the right
113 long int y = threeToOneD(0l, 1l, 0l, dims); // displacement ...
114 long int z = threeToOneD(0l, 0l, 1l, dims);
115 long int xy = threeToOneD(1l, 1l, 0l, dims);
116 long int yz = threeToOneD(0l, 1l, 1l, dims);
117 long int xz = threeToOneD(1l, 0l, 1l, dims);
118 long int xyz = threeToOneD(1l, 1l, 1l, dims);
119
120 int i = 0;
121 // if incrementing along X, the following order will be more cache-efficient:
122 _cellPairOffsets8Pack[i++] = make_pair(o, o );
123 _cellPairOffsets8Pack[i++] = make_pair(o, y );
124 _cellPairOffsets8Pack[i++] = make_pair(y, z );
125 _cellPairOffsets8Pack[i++] = make_pair(o, z );
126 _cellPairOffsets8Pack[i++] = make_pair(o, yz );
127
128 _cellPairOffsets8Pack[i++] = make_pair(x, yz );
129 _cellPairOffsets8Pack[i++] = make_pair(x, y );
130 _cellPairOffsets8Pack[i++] = make_pair(x, z );
131 _cellPairOffsets8Pack[i++] = make_pair(o, x );
132 _cellPairOffsets8Pack[i++] = make_pair(o, xy );
133 _cellPairOffsets8Pack[i++] = make_pair(xy, z );
134 _cellPairOffsets8Pack[i++] = make_pair(y, xz );
135 _cellPairOffsets8Pack[i++] = make_pair(o, xz );
136 _cellPairOffsets8Pack[i++] = make_pair(o, xyz);
137
138 i = 0;
139 _cellOffsets8Pack[i++] = o;
140 _cellOffsets8Pack[i++] = y;
141 _cellOffsets8Pack[i++] = z;
142 _cellOffsets8Pack[i++] = yz;
143
144 _cellOffsets8Pack[i++] = x;
145 _cellOffsets8Pack[i++] = xy;
146 _cellOffsets8Pack[i++] = xz;
147 _cellOffsets8Pack[i++] = xyz;
148
149}
150
151
152#endif /* SRC_PARTICLECONTAINER_LINKEDCELLTRAVERSALS_C08BASEDTRAVERSALS_H_ */
Definition: C08BasedTraversals.h:17
virtual void rebuild(std::vector< CellTemplate > &cells, const std::array< unsigned long, 3 > &dims, double cellLength[3], double cutoff, CellPairTraversalData *data)
Definition: C08BasedTraversals.h:28
Definition: CellPairTraversals.h:21
virtual void rebuild(std::vector< CellTemplate > &cells, const std::array< unsigned long, 3 > &dims, double cellLength[3], double cutoff, CellPairTraversalData *data)
Definition: CellPairTraversals.h:32
Definition: CellProcessor.h:29
virtual void processCell(ParticleCell &cell)=0
virtual void processCellPair(ParticleCell &cell1, ParticleCell &cell2, bool sumAll=false)=0
Definition: CellPairTraversals.h:16