ls1-MarDyn
ls1-MarDyn molecular dynamics code
OriginalCellPairTraversal.h
1/*
2 * OriginalCellPairTraversal.h
3 *
4 * Created on: 15 May 2017
5 * Author: tchipevn
6 */
7
8#ifndef SRC_PARTICLECONTAINER_LINKEDCELLTRAVERSALS_ORIGINALCELLPAIRTRAVERSAL_H_
9#define SRC_PARTICLECONTAINER_LINKEDCELLTRAVERSALS_ORIGINALCELLPAIRTRAVERSAL_H_
10
11#include "CellPairTraversals.h"
12#include "utils/Logger.h"
13#include "utils/mardyn_assert.h"
14#include "utils/threeDimensionalMapping.h"
15#include "particleContainer/adapter/CellProcessor.h"
16
18};
19
20template <class CellTemplate>
21class OriginalCellPairTraversal: public CellPairTraversals<CellTemplate> {
22public:
23 OriginalCellPairTraversal(std::vector<CellTemplate> &cells, const std::array<unsigned long, 3> &dims) :
25 computeNeighbourOffsets();
26 }
27
28 virtual ~~OriginalCellPairTraversal() {}
29
30 virtual void rebuild(std::vector<CellTemplate>& cells,
31 const std::array<unsigned long, 3>& dims, double cellLength[3], double cutoff,
32 struct CellPairTraversalData *data);
33
34 void traverseCellPairs(CellProcessor& cellProcessor);
35 void traverseCellPairsOuter(CellProcessor& cellProcessor);
36 void traverseCellPairsInner(CellProcessor& cellProcessor, unsigned stage, unsigned stageCount);
37
38 virtual void processBaseCell(CellProcessor& cellProcessor, unsigned long cellIndex) const;
39
40protected:
41 // couldn't get it to compile when the enum is part of the class, so making it global...
42 enum TraverseType {
43 ALL_CELLS,
44 INNER_CELLS,
45 OUTER_CELLS
46 };
47
48 void computeNeighbourOffsets();
49 void traverseCellPairsBackend(CellProcessor& cellProcessor, unsigned loIndex, unsigned hiIndex, TraverseType type) const;
50
51
52 std::array<long, 13> _forwardNeighbourOffsets;
53 std::array<long, 13> _backwardNeighbourOffsets;
54 std::vector<unsigned long> _innerMostCellIndices;
55};
56
57template<class CellTemplate>
58void OriginalCellPairTraversal<CellTemplate>::rebuild(std::vector<CellTemplate> &cells,
59 const std::array<unsigned long, 3> &dims, double cellLength[3], double cutoff,
60 struct CellPairTraversalData *data) {
61 if (dynamic_cast<OriginalCellPairTraversalData *>(data)) {
62 CellPairTraversals<CellTemplate>::rebuild(cells, dims, cellLength, cutoff, data);
63 computeNeighbourOffsets();
64
65 _innerMostCellIndices.clear();
66
67 auto maxIndex = 1;
68 for (auto d : dims)
69 maxIndex *= d;
70
71 for (auto i = 0; i < maxIndex; ++i) {
72 if (this->_cells->at(i).isInnerMostCell()){
73 _innerMostCellIndices.push_back(i);
74 }
75 }
76 } else {
77 global_log->error() << "OriginalCellPairTraversalDat::rebuild was called with incompatible Traversal data!" << endl;
79 }
80}
81
82template<class CellTemplate>
84 Log::global_log->debug() << "Setting up cell neighbour index lists." << std::endl;
85
86 std::fill(_forwardNeighbourOffsets.begin(), _forwardNeighbourOffsets.end(), 0);
87 std::fill(_backwardNeighbourOffsets.begin(), _backwardNeighbourOffsets.end(), 0);
88 int forwardNeighbourIndex = 0, backwardNeighbourIndex = 0;
89
90 long maxNeighbourOffset = 0;
91 long minNeighbourOffset = 0;
92
93 std::array<long, 3> dims;
94 for (int d = 0; d < 3; ++d) {
95 dims[d] = static_cast<long>(this->_dims[d]);
96 }
97
98 std::array<long, 3> r;
99 for (r[2] = -1; r[2] <= 1; r[2]++) {
100 for (r[1] = -1; r[1] <= 1; r[1]++) {
101 for (r[0] = -1; r[0] <= 1; r[0]++) {
102
103 long offset = threeDimensionalMapping::threeToOneD(r, dims);
104
105 if (offset > 0) {
106 _forwardNeighbourOffsets[forwardNeighbourIndex] = offset;
107 ++forwardNeighbourIndex;
108 if (offset > maxNeighbourOffset) {
109 maxNeighbourOffset = offset;
110 }
111 }
112 if (offset < 0) {
113 _backwardNeighbourOffsets[backwardNeighbourIndex] = abs(offset);
114 ++backwardNeighbourIndex;
115 if (abs(offset) > minNeighbourOffset) {
116 minNeighbourOffset = abs(offset);
117 }
118 }
119 }
120 }
121 }
122
123 mardyn_assert(forwardNeighbourIndex == 13);
124 mardyn_assert(backwardNeighbourIndex == 13);
125
126 Log::global_log->info() << "Neighbour offsets are bounded by "
127 << minNeighbourOffset << ", " << maxNeighbourOffset << std::endl;
128
129}
130
131template<class CellTemplate>
133 CellProcessor& cellProcessor, unsigned loIndex, unsigned hiIndex,
134 TraverseType type) const {
135 switch(type) {
136 case ALL_CELLS:
137 for (unsigned i = loIndex; i < hiIndex; ++i) {
138 processBaseCell(cellProcessor, i);
139 }
140 break;
141 case INNER_CELLS:
142 for (unsigned i = loIndex; i < hiIndex; ++i) {
143 processBaseCell(cellProcessor, _innerMostCellIndices.at(i));
144 }
145 break;
146 case OUTER_CELLS:
147 for (unsigned i = loIndex; i < hiIndex; ++i) {
148 CellTemplate& baseCell = this->_cells->at(i);
149 if (!baseCell.isInnerMostCell()) {
150 processBaseCell(cellProcessor, i);
151 }
152 }
153 break;
154 }
155}
156
157template<class CellTemplate>
159 unsigned long start = 0ul;
160 unsigned long end = this->_cells->size();
161 traverseCellPairsBackend(cellProcessor, start, end, ALL_CELLS);
162}
163
164template<class CellTemplate>
166 unsigned long start = 0ul;
167 unsigned long end = this->_cells->size();
168 traverseCellPairsBackend(cellProcessor, start, end, OUTER_CELLS);
169}
170
171template<class CellTemplate>
173 unsigned stage,
174 unsigned stageCount) {
175 unsigned long start = _innerMostCellIndices.size() * stage / stageCount;
176 unsigned long end = _innerMostCellIndices.size() * (stage+1) / stageCount;
177 traverseCellPairsBackend(cellProcessor, start, end, INNER_CELLS);
178}
179
180template<class CellTemplate>
182 unsigned long cellIndex) const {
183
184 CellTemplate& currentCell = this->_cells->at(cellIndex);
185
186 if (currentCell.isInnerCell()) {
187 cellProcessor.processCell(currentCell);
188 // loop over all forward neighbours
189 for (auto& neighbourOffset : this->_forwardNeighbourOffsets) {
190 CellTemplate& neighbourCell = this->_cells->at(cellIndex + neighbourOffset);
191 cellProcessor.processCellPair(currentCell, neighbourCell);
192 }
193 } else
194 // loop over all boundary cells and calculate forces to forward and backward neighbours
195 if (currentCell.isBoundaryCell()) {
196 cellProcessor.processCell(currentCell);
197 // loop over all forward neighbours
198 for (auto& neighbourOffset : this->_forwardNeighbourOffsets) {
199 CellTemplate& neighbourCell = this->_cells->at(cellIndex + neighbourOffset);
200 cellProcessor.processCellPair(currentCell, neighbourCell);
201 }
202 // loop over all backward neighbours. calculate only forces
203 // to neighbour cells in the halo region, all others already have been calculated
204 for (auto& neighbourOffset : this->_backwardNeighbourOffsets) {
205 CellTemplate& neighbourCell = this->_cells->at(cellIndex - neighbourOffset);
206 if (neighbourCell.isHaloCell()) {
207 cellProcessor.processCellPair(currentCell, neighbourCell);
208 }
209 }
210 } // if ( isBoundaryCell() )
211}
212
213
214#endif /* SRC_PARTICLECONTAINER_LINKEDCELLTRAVERSALS_ORIGINALCELLPAIRTRAVERSAL_H_ */
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: OriginalCellPairTraversal.h:21
virtual void rebuild(std::vector< CellTemplate > &cells, const std::array< unsigned long, 3 > &dims, double cellLength[3], double cutoff, struct CellPairTraversalData *data)
Definition: OriginalCellPairTraversal.h:58
std::array< long, 13 > _backwardNeighbourOffsets
Neighbours that come in the total ordering before a cell.
Definition: OriginalCellPairTraversal.h:53
std::array< long, 13 > _forwardNeighbourOffsets
Neighbours that come in the total ordering after a cell.
Definition: OriginalCellPairTraversal.h:52
std::vector< unsigned long > _innerMostCellIndices
Vector containing the indices (for the cells vector) of all inner cells (without boundary)
Definition: OriginalCellPairTraversal.h:54
static void exit(int exitcode)
Terminate simulation with given exit code.
Definition: Simulation.cpp:155
Enumeration class corresponding to the type schema type.
Definition: vtk-unstructured.h:1746
Definition: CellPairTraversals.h:16
Definition: OriginalCellPairTraversal.h:17