8#ifndef SRC_PARTICLECONTAINER_LINKEDCELLTRAVERSALS_MIDPOINTTRAVERSAL_H_
9#define SRC_PARTICLECONTAINER_LINKEDCELLTRAVERSALS_MIDPOINTTRAVERSAL_H_
11#include "particleContainer/LinkedCellTraversals/CellPairTraversals.h"
17template <
class CellTemplate>
20 MidpointTraversal(std::vector<CellTemplate>& cells,
const std::array<unsigned long, 3>& dims):
31 virtual void rebuild(std::vector<CellTemplate> &cells,
32 const std::array<unsigned long, 3> &dims,
double cellLength[3],
double cutoff,
CellPairTraversalData *data)
override {
36 _innerMostCellIndices.clear();
37 _notInnerMostCellIndices.clear();
43 for (
auto i = 0; i < maxIndex; ++i) {
44 if (this->_cells->at(i).isInnerMostCell()){
45 _innerMostCellIndices.push_back(i);
47 _notInnerMostCellIndices.push_back(i);
52 virtual void traverseCellPairs(
CellProcessor& cellProcessor)
override;
53 virtual void traverseCellPairsOuter(
CellProcessor& cellProcessor)
override;
54 virtual void traverseCellPairsInner(
CellProcessor& cellProcessor,
unsigned stage,
unsigned stageCount)
override;
57 virtual bool requiresForceExchange()
const override {
return true;}
59 virtual unsigned maxCellsInCutoff()
const override {
return 2;}
62 virtual void processBaseCell(
CellProcessor& cellProcessor,
unsigned long baseIndex)
const;
65 std::array<std::pair<long, long>, 62> _cellPairOffsets;
66 std::array<std::pair<std::array<long, 3>, std::array<long, 3>>, 62> _offsets3D;
71 void computeOffsets();
72 void computeOffsets3D();
75 void pairOriginWithForwardNeighbors(
int& index);
76 void pairCellsWithPlane(std::array<long, 3>& cc,
77 std::array<long, 3>& oc,
int& index);
78 void pairCellsWithAdjacentCorners(std::array<long, 3>& ce,
79 std::array<long, 3>& oe,
int& index);
82 std::array<std::array<long, 3>, 6> _faces;
85 std::array<std::array<long, 3>, 12> _edges;
88 std::array<std::array<long, 3>, 8> _corners;
90 std::vector<unsigned long> _innerMostCellIndices;
91 std::vector<unsigned long> _notInnerMostCellIndices;
94template<
class CellTemplate>
97 _faces[0] = { 1, 0, 0};
98 _faces[1] = { 0, 1, 0};
99 _faces[2] = { 0, 0, 1};
101 _faces[3] = {-1, 0, 0};
102 _faces[4] = { 0,-1, 0};
103 _faces[5] = { 0, 0,-1};
106 _edges[0] = { 1, 1, 0};
107 _edges[1] = { 1, 0, 1};
108 _edges[2] = { 0, 1, 1};
109 _edges[3] = {-1, 1, 0};
110 _edges[4] = {-1, 0, 1};
111 _edges[5] = { 0,-1, 1};
113 _edges[6] = {-1,-1, 0};
114 _edges[7] = {-1, 0,-1};
115 _edges[8] = { 0,-1,-1};
116 _edges[9] = { 1,-1, 0};
117 _edges[10] = { 1, 0,-1};
118 _edges[11] = { 0, 1,-1};
121 _corners[0] = { 1, 1, 1};
122 _corners[1] = { 1, 1,-1};
123 _corners[2] = { 1,-1, 1};
124 _corners[3] = { 1,-1,-1};
126 _corners[4] = {-1,-1,-1};
127 _corners[5] = {-1,-1, 1};
128 _corners[6] = {-1, 1,-1};
129 _corners[7] = {-1, 1, 1};
132template<
class CellTemplate>
144 for(
int i=0; i<3; ++i){
146 _offsets3D[index++] = make_pair(_faces[i], _faces[j]);
149 for(
int i=0; i<6; ++i){
151 _offsets3D[index++] = make_pair(_edges[i], _edges[j]);
154 for(
int i=0; i<4; ++i){
156 _offsets3D[index++] = make_pair(_corners[i], _corners[j]);
159 mardyn_assert(index == 13);
165 pairOriginWithForwardNeighbors(index);
167 mardyn_assert(index == 13+13);
173 for(
int i=0; i<3; ++i){
174 auto oc = _faces[(i+3)%6];
179 pairCellsWithPlane(cc, oc, index);
182 mardyn_assert(index == 13+13+24);
187 for(
int i=0; i<6; ++i){
188 auto oe = _edges[(i+6)%12];
192 pairCellsWithAdjacentCorners(ce, oe, index);
197 mardyn_assert(index == 13+13+24+12);
200template<
class CellTemplate>
202 using threeDimensionalMapping::threeToOneD;
205 std::array<long, 3> dims;
206 for (
int d = 0; d < 3; ++d) {
207 dims[d] =
static_cast<long>(this->_dims[d]);
210 for(
unsigned int i=0; i<_offsets3D.size(); ++i){
212 auto a = _offsets3D[i].first;
213 auto b = _offsets3D[i].second;
215 auto ax = std::get<0>(a);
216 auto ay = std::get<1>(a);
217 auto az = std::get<2>(a);
219 auto bx = std::get<0>(b);
220 auto by = std::get<1>(b);
221 auto bz = std::get<2>(b);
223 mardyn_assert((abs(ax) <= 1) && (abs(ay) <= 1) && (abs(az) <= 1));
224 mardyn_assert((abs(bx) <= 1) && (abs(by) <= 1) && (abs(bz) <= 1));
227 auto aIndex = threeToOneD(ax, ay, az, dims);
228 auto bIndex = threeToOneD(bx, by, bz, dims);
230 auto offsetPair = std::make_pair(aIndex, bIndex);
233 _cellPairOffsets[i] = offsetPair;
238template<
class CellTemplate>
240 using std::make_pair;
242 std::array<long, 3> origin = {0l, 0l, 0l};
244 for(
long y=-1; y<=1; ++y){
245 for(
long x=-1; x<=1; ++x){
246 _offsets3D[index++] = make_pair(origin, std::array<long,3>{x, y, 1l});
249 _offsets3D[index++] = make_pair(origin, std::array<long,3>{1l, y, 0l});
253 _offsets3D[index++] = make_pair(origin, std::array<long,3>{0l, 1l, 0l});
257template<
class CellTemplate>
259 std::array<long, 3>& oc,
int& index){
261 for(
int i=-1; i<=1; ++i){
262 for(
int j=-1; j<=1; ++j){
265 if(i==0 && j==0)
continue;
267 std::array<long, 3> cell;
269 if(std::get<0>(oc) == 0){
270 if(std::get<1>(oc) == 0){
272 cell = {i, j, std::get<2>(oc)};
275 cell = {i, std::get<1>(oc), j};
279 cell = {std::get<0>(oc), i, j};
282 _offsets3D[index++] = std::make_pair(cc, cell);
287template<
class CellTemplate>
289 std::array<long, 3>& oe,
int& index){
291 for(
int i=-1; i<=1; i+=2){
293 std::array<long, 3> cell;
295 if(std::get<0>(oe) == 0) {
297 cell = {i, std::get<1>(oe), std::get<2>(oe)};
298 }
else if(std::get<1>(oe) == 0) {
300 cell = {std::get<0>(oe), i, std::get<2>(oe)};
303 cell = {std::get<0>(oe), std::get<1>(oe), i};
306 _offsets3D[index++] = std::make_pair(ce, cell);
310template<
class CellTemplate>
312 unsigned long start = 0ul;
313 unsigned long end = this->_cells->size();
314 for(
auto i = start; i<end; ++i){
315 processBaseCell(cellProcessor, i);
319template<
class CellTemplate>
322 for(
unsigned long outerCellIndex : _notInnerMostCellIndices){
323 processBaseCell(cellProcessor, outerCellIndex);
327template<
class CellTemplate>
330 unsigned long start = _innerMostCellIndices.size() * stage / stageCount;
331 unsigned long end = _innerMostCellIndices.size() * (stage+1) / stageCount;
332 for (
unsigned long i = start; i < end; ++i) {
333 processBaseCell(cellProcessor, _innerMostCellIndices.at(i));
338template<
class CellTemplate>
341 CellTemplate& baseCell = this->_cells->at(baseIndex);
343 if(!baseCell.isHaloCell()) {
346 for(
auto& current_pair : _cellPairOffsets){
348 unsigned long offset1 = current_pair.first;
349 unsigned long cellIndex1 = baseIndex + offset1;
351 unsigned long offset2 = current_pair.second;
352 unsigned long cellIndex2 = baseIndex + offset2;
354 CellTemplate& cell1 = this->_cells->at(cellIndex1);
355 CellTemplate& cell2 = this->_cells->at(cellIndex2);
357 const bool sumAllMacroscopic =
true;
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: MidpointTraversal.h:18
virtual void rebuild(std::vector< CellTemplate > &cells, const std::array< unsigned long, 3 > &dims, double cellLength[3], double cutoff, CellPairTraversalData *data) override
Definition: MidpointTraversal.h:31
Definition: CellPairTraversals.h:16
Definition: MidpointTraversal.h:14