ls1-MarDyn
ls1-MarDyn molecular dynamics code
NeutralTerritoryTraversal.h
1/*
2 * NeutralTerritoryTraversal.h
3 *
4 * Created on: 25.11.2020
5 * Author: seckler
6 */
7
8#pragma once
9
10#include <array>
11#include "particleContainer/LinkedCellTraversals/CellPairTraversals.h"
12
14
24template <class CellTemplate>
25class NeutralTerritoryTraversal : public CellPairTraversals<CellTemplate> {
26public:
27 NeutralTerritoryTraversal(std::vector<CellTemplate>& cells, const std::array<unsigned long, 3>& dims,
28 double cellLength[3], double cutoff)
30 computeOffsets3D(cellLength, cutoff);
31 computeOffsets();
32 }
33 ~~NeutralTerritoryTraversal() override = default;
34
38 void rebuild(std::vector<CellTemplate>& cells, const std::array<unsigned long, 3>& dims, double cellLength[3],
39 double cutoff, CellPairTraversalData* data) override {
40 CellPairTraversals<CellTemplate>::rebuild(cells, dims, cellLength, cutoff, data);
41 computeOffsets3D(cellLength, cutoff);
42 computeOffsets();
43 }
44
45 void traverseCellPairs(CellProcessor& cellProcessor) override;
46 void traverseCellPairsOuter(CellProcessor& cellProcessor) override;
47 void traverseCellPairsInner(CellProcessor& cellProcessor, unsigned stage, unsigned stageCount) override;
48
49 // NT traversal requires force exchange!
50 bool requiresForceExchange() const override { return true; }
51
52 // NT has no upper limit for number of cells in cutoff!
53 unsigned maxCellsInCutoff() const override { return std::numeric_limits<unsigned>::max(); }
54
55protected:
56 void processBaseCell(CellProcessor& cellProcessor, unsigned long baseIndex) const;
57
58 // All pairs that have to be processed when calculating the forces (excluding self)
59 std::vector<std::pair<long, long>> _cellPairOffsets;
60 std::vector<std::pair<std::array<long, 3>, std::array<long, 3>>> _offsets3D;
61
62private:
63 void computeOffsets();
64 void computeOffsets3D(const double cellLength[3], double cutoff);
65};
66
67template <class CellTemplate>
68void NeutralTerritoryTraversal<CellTemplate>::computeOffsets3D(const double cellLength[3], const double cutoff) {
69 _offsets3D.clear();
70 _cellPairOffsets.clear();
71 long num_x = std::ceil(cutoff / cellLength[0]);
72 long num_y = std::ceil(cutoff / cellLength[1]);
73 long num_z = std::ceil(cutoff / cellLength[2]);
74 for (long plate_x = 0; plate_x <= num_x; ++plate_x) {
75 // Start plate_y at 0, iff plate_x == 0.
76 long start_plate_y = plate_x == 0 ? 0 : -num_y;
77 for (long plate_y = start_plate_y; plate_y <= num_y; ++plate_y) {
78 // Start tower_z at 1, iff plate_x == 0 and plate_y == 0.
79 // This also prevents both tower and plate to be {0,0,0}.
80 long start_tower_z = (plate_x == 0 and plate_y == 0) ? 1 : -num_z;
81 for (long tower_z = start_tower_z; tower_z <= num_z; ++tower_z) {
82 std::array<long, 3> plate{plate_x, plate_y, 0};
83 std::array<long, 3> tower{0, 0, tower_z};
84 _offsets3D.emplace_back(tower, plate);
85 }
86 }
87 }
88}
89
90template <class CellTemplate>
92 // Clear _cellPairOffsets!
93 _cellPairOffsets.clear();
94
95 using threeDimensionalMapping::threeToOneD;
96
97 // Dim array is int but we need it as long for some reason (copied from C08BasedTraversal)
98 std::array<long, 3> dims{};
99 for (int d = 0; d < 3; ++d) {
100 dims[d] = static_cast<long>(this->_dims[d]);
101 }
102
103 for (const auto& [firstOffset, secondOffset] : _offsets3D) {
104 auto [firstOffsetX, firstOffsetY, firstOffsetZ] = firstOffset;
105 auto [secondOffsetX, secondOffsetY, secondOffsetZ] = secondOffset;
106
107 // convert 3d index to 1d
108 auto aIndex = threeToOneD(firstOffsetX, firstOffsetY, firstOffsetZ, dims);
109 auto bIndex = threeToOneD(secondOffsetX, secondOffsetY, secondOffsetZ, dims);
110
111 // store offset pair
112 _cellPairOffsets.emplace_back(aIndex, bIndex);
113 }
114}
115
116template <class CellTemplate>
118 unsigned long start = 0ul;
119 unsigned long end = this->_cells->size();
120 for (auto i = start; i < end; ++i) {
121 processBaseCell(cellProcessor, i);
122 }
123}
124
125template <class CellTemplate>
127 global_log->error() << "NT: overlapping Comm not implemented." << std::endl;
129}
130
131template <class CellTemplate>
133 unsigned stageCount) {
134 global_log->error() << "NT: overlapping Comm not implemented." << std::endl;
136}
137
138template <class CellTemplate>
140 unsigned long baseIndex) const {
141 CellTemplate& baseCell = this->_cells->at(baseIndex);
142
143 if (not baseCell.isHaloCell()) {
144 // Process all cell pairs for this cell
145 for (const auto& [offset1, offset2] : _cellPairOffsets) {
146 unsigned long cellIndex1 = baseIndex + offset1;
147 unsigned long cellIndex2 = baseIndex + offset2;
148
149 CellTemplate& cell1 = this->_cells->at(cellIndex1);
150 CellTemplate& cell2 = this->_cells->at(cellIndex2);
151
152 const bool sumAllMacroscopic = true;
153 cellProcessor.processCellPair(cell1, cell2, sumAllMacroscopic);
154 }
155
156 // Process base cell itself
157 cellProcessor.processCell(baseCell);
158 }
159}
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: NeutralTerritoryTraversal.h:25
void rebuild(std::vector< CellTemplate > &cells, const std::array< unsigned long, 3 > &dims, double cellLength[3], double cutoff, CellPairTraversalData *data) override
Definition: NeutralTerritoryTraversal.h:38
static void exit(int exitcode)
Terminate simulation with given exit code.
Definition: Simulation.cpp:155
Definition: CellPairTraversals.h:16
Definition: NeutralTerritoryTraversal.h:13