AutoPas  3.0.0
Loading...
Searching...
No Matches
LCC04Traversal.h
Go to the documentation of this file.
1
8#pragma once
9
16
17namespace autopas {
18
28template <class ParticleCell_T, class Functor_T>
29class LCC04Traversal : public C08BasedTraversal<ParticleCell_T, Functor_T>, public LCTraversalInterface {
30 public:
41 LCC04Traversal(const std::array<unsigned long, 3> &dims, Functor_T &functor, double interactionLength,
42 const std::array<double, 3> &cellLength, DataLayoutOption dataLayout, bool useNewton3)
43 : C08BasedTraversal<ParticleCell_T, Functor_T>(dims, functor, interactionLength, cellLength, dataLayout,
44 useNewton3),
45 _cellOffsets32Pack(computeOffsets32Pack()),
46 _cellHandler(functor, this->_cellsPerDimension, interactionLength, cellLength, this->_overlap, dataLayout,
47 useNewton3),
48 _end(utils::ArrayMath::subScalar(utils::ArrayUtils::static_cast_copy_array<long>(this->_cellsPerDimension),
49 1l)) {}
50
51 void traverseParticles() override;
52
53 [[nodiscard]] TraversalOption getTraversalType() const override { return TraversalOption::lc_c04; }
54
59 [[nodiscard]] bool isApplicableToDomain() const override {
60 // The cellsize cannot be smaller then the cutoff, if OpenMP is used.
61 // Also see: https://github.com/AutoPas/AutoPas/issues/464
62 const double minLength = *std::min_element(this->_cellLength.cbegin(), this->_cellLength.cend());
63 const unsigned long minDim = *std::min_element(this->_cellsPerDimension.cbegin(), this->_cellsPerDimension.cend());
64
65 return minLength >= this->_interactionLength and minDim > 3;
66 }
67
71 void setAoSSortingThresholds(const SortingThresholdInfoInterface &aosSortingThreshold) override {
72 _cellHandler.setAoSSortingThresholds(aosSortingThreshold);
73 }
74
78 void setSoASortingThresholds(const SortingThresholdInfoInterface &soaSortingThreshold) override {
79 _cellHandler.setSoASortingThresholds(soaSortingThreshold);
80 }
81
82 private:
83 void traverseSingleColor(std::vector<ParticleCell_T> &cells, int color);
84
85 void processBasePack32(std::vector<ParticleCell_T> &cells, const std::array<long, 3> &base3DIndex);
86
87 static constexpr auto computeOffsets32Pack();
88
89 [[nodiscard]] constexpr long parity(long x, long y, long z) const { return (x + y + z + 24) % 8; }
90
91 std::array<std::array<long, 3>, 32> _cellOffsets32Pack;
92
93 LCC08CellHandler<ParticleCell_T, Functor_T> _cellHandler;
94
95 std::array<long, 3> _end;
96};
97
104template <class ParticleCell_T, class Functor_T>
105constexpr auto LCC04Traversal<ParticleCell_T, Functor_T>::computeOffsets32Pack() {
106 using std::make_pair;
108
109 std::array<std::array<long, 3>, 32> cellOffsets32Pack = {};
110
111 unsigned int i = 0;
112 long z = 0l;
113 cellOffsets32Pack[i++] = {1l, 1l, z};
114 cellOffsets32Pack[i++] = {1l, 2l, z};
115 cellOffsets32Pack[i++] = {2l, 1l, z};
116 cellOffsets32Pack[i++] = {2l, 2l, z};
117
118 // z = 1ul; z = 2ul
119 for (z = 1l; z < 3l; ++z) {
120 for (long y = 0l; y < 4l; y++) {
121 for (long x = 0l; x < 4l; x++) {
122 if ((x == 0l and y == 0l) or (x == 3l and y == 0l) or (x == 0l and y == 3l) or (x == 3l and y == 3l)) {
123 continue;
124 }
125 cellOffsets32Pack[i++] = {x, y, z};
126 }
127 }
128 }
129
130 z = 3ul;
131 cellOffsets32Pack[i++] = {1l, 1l, z};
132 cellOffsets32Pack[i++] = {1l, 2l, z};
133 cellOffsets32Pack[i++] = {2l, 1l, z};
134 cellOffsets32Pack[i++] = {2l, 2l, z};
135
136 if (i != 32) {
137 utils::ExceptionHandler::exception("Internal error: Wrong number of offsets (expected: 32, actual: {})", i);
138 }
139
140 return cellOffsets32Pack;
141}
142
152template <class ParticleCell_T, class Functor_T>
153void LCC04Traversal<ParticleCell_T, Functor_T>::processBasePack32(std::vector<ParticleCell_T> &cells,
154 const std::array<long, 3> &base3DIndex) {
156 std::array<long, 3> index{};
157 const std::array<long, 3> signedDims = utils::ArrayUtils::static_cast_copy_array<long>(this->_cellsPerDimension);
158
159 for (auto offset32Pack : _cellOffsets32Pack) {
160 // compute 3D index
161 bool isIn = true;
162 for (int d = 0; d < 3; ++d) {
163 index[d] = base3DIndex[d] + offset32Pack[d];
164 isIn &= (index[d] >= 0l) and (index[d] < _end[d]);
165 }
166
167 if (isIn) {
168 const unsigned long ulIndex = threeToOneD(index, signedDims);
169 _cellHandler.processBaseCell(cells, ulIndex);
170 }
171 }
172}
173
181template <class ParticleCell_T, class Functor_T>
183 auto &cells = *(this->_cells);
184 AUTOPAS_OPENMP(parallel) {
185 for (int color = 0; color < 4; ++color) {
186 traverseSingleColor(cells, color);
187
188 if (color < 3) {
189 AUTOPAS_OPENMP(barrier)
190 }
191 }
192 } // close parallel region
193}
194
195template <class ParticleCell_T, class Functor_T>
196void LCC04Traversal<ParticleCell_T, Functor_T>::traverseSingleColor(std::vector<ParticleCell_T> &cells, int color) {
197 // we need to traverse one body-centered cubic (BCC) grid, which consists of two cartesian grids
198
199 // colors 0 and 2 form one cartesian grid
200 // colors 1 and 3 form another cartesian grid, whose origin is shifted by (2,2,2)
201
202 // determine a starting point of one of the grids
203 std::array<long, 3> startOfThisColor{};
204
205 switch (color % 2) {
206 case 0:
207 // colours 0 and 2
208 startOfThisColor = {-2l, -2l, -2l};
209 break;
210 case 1:
211 // colours 1 and 3
212 startOfThisColor = {0l, 0l, 0l};
213 break;
214 }
215
216 // calculate whether the calculated starting point is part of the color
217 long correctParity = parity(startOfThisColor[0], startOfThisColor[1], startOfThisColor[2]);
218 if (color >= 2) {
219 correctParity += 4;
220 }
221
222 // to fix intel64 icpc compiler complaints about perfectly nested loop (tested with version 19.0.4.20190416).
223 const long startX = startOfThisColor[0], endX = _end[0];
224 const long startY = startOfThisColor[1], endY = _end[1];
225 const long startZ = startOfThisColor[2], endZ = _end[2];
226
227 // first cartesian grid
228 // grids are interlinked: one grid fills the gaps in the other grid
229 AUTOPAS_OPENMP(for schedule(dynamic, 1) collapse(3) nowait)
230 for (long z = startZ; z < endZ; z += 4) {
231 for (long y = startY; y < endY; y += 4) {
232 for (long x = startX; x < endX; x += 4) {
233 const long par = parity(x, y, z);
234
235 if (par != correctParity) {
236 continue;
237 }
238
239 const std::array<long, 3> base3DIndex = {x, y, z};
240 processBasePack32(cells, base3DIndex);
241 }
242 }
243 }
244}
245
246} // namespace autopas
#define AUTOPAS_OPENMP(args)
Empty macro to throw away any arguments.
Definition: WrapOpenMP.h:126
This class provides the base for traversals using the c08 base step.
Definition: C08BasedTraversal.h:24
std::array< unsigned long, 3 > _cellsPerDimension
The dimensions of the cellblock.
Definition: CellTraversal.h:70
const double _interactionLength
Interaction length (cutoff + skin).
Definition: ColorBasedTraversal.h:111
std::array< unsigned long, 3 > _overlap
overlap of interacting cells.
Definition: ColorBasedTraversal.h:121
const std::array< double, 3 > _cellLength
cell length in CellBlock3D.
Definition: ColorBasedTraversal.h:116
This class provides the c04 traversal.
Definition: LCC04Traversal.h:29
void setSoASortingThresholds(const SortingThresholdInfoInterface &soaSortingThreshold) override
Set the SoA sorting-threshold for traversals that use the CellFunctor.
Definition: LCC04Traversal.h:78
void setAoSSortingThresholds(const SortingThresholdInfoInterface &aosSortingThreshold) override
Set the aos-sorting-threshold for traversals that use the CellFunctor.
Definition: LCC04Traversal.h:71
LCC04Traversal(const std::array< unsigned long, 3 > &dims, Functor_T &functor, double interactionLength, const std::array< double, 3 > &cellLength, DataLayoutOption dataLayout, bool useNewton3)
Constructor of the c04 traversal.
Definition: LCC04Traversal.h:41
bool isApplicableToDomain() const override
C04 traversals are usable, if cellSizeFactor >= 1.0 and there are at least 3 cells for each dimension...
Definition: LCC04Traversal.h:59
TraversalOption getTraversalType() const override
Return a enum representing the name of the traversal class.
Definition: LCC04Traversal.h:53
void traverseParticles() override
Go through one color and search for blocks belonging to the specified color.
Definition: LCC04Traversal.h:182
Interface for traversals used by the LinkedCell class.
Definition: LCTraversalInterface.h:18
static void exception(const Exception e)
Handle an exception derived by std::exception.
Definition: ExceptionHandler.h:64
constexpr T threeToOneD(T x, T y, T z, const std::array< T, 3 > &dims)
Convert a 3d index to a 1d index.
Definition: ThreeDimensionalMapping.h:29
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:34
Polymorphic base for sorting-threshold storage.
Definition: SortingThresholdInfoInterface.h:18