AutoPas  3.0.0
Loading...
Searching...
No Matches
SlicedBasedTraversal.h
Go to the documentation of this file.
1
8#pragma once
9
15
16namespace autopas {
17
28template <class ParticleCell, class Functor>
29class SlicedBasedTraversal : public CellTraversal<ParticleCell>, public TraversalInterface {
30 public:
43 explicit SlicedBasedTraversal(const std::array<unsigned long, 3> &dims, Functor &functor,
44 const double interactionLength, const std::array<double, 3> &cellLength,
45 DataLayoutOption dataLayout, bool useNewton3, bool spaciallyForward)
47 TraversalInterface(dataLayout, useNewton3),
48 _overlap{},
50 _interactionLength(interactionLength),
51 _cellLength(cellLength),
54 _spaciallyForward(spaciallyForward),
55 _dataLayoutConverter(functor, dataLayout) {
56 this->init();
57 }
58
62 [[nodiscard]] bool isApplicableToDomain() const override {
63 auto minSliceThickness = _overlapLongestAxis + 1;
64 auto maxNumSlices = this->_cellsPerDimension[_dimsSortedByLength[0]] / minSliceThickness;
65 return maxNumSlices > 0;
66 }
67
72 virtual void initSliceThickness(unsigned long minSliceThickness) {
73 auto numSlices = this->_cellsPerDimension[_dimsSortedByLength[0]] / minSliceThickness;
74 _sliceThickness.clear();
75
76 // abort if domain is too small -> cleared _sliceThickness array indicates non applicability
77 if (numSlices < 1) return;
78
79 _sliceThickness.insert(_sliceThickness.begin(), numSlices, minSliceThickness);
80 auto rest = this->_cellsPerDimension[_dimsSortedByLength[0]] - _sliceThickness[0] * numSlices;
81 // remaining slices to distribute the remaining layers on
82 auto remSlices = std::min(rest, numSlices);
83 for (size_t i = 0; i < remSlices; ++i) {
84 _sliceThickness[i] += rest / (remSlices - i);
85 rest -= rest / (remSlices - i);
86 }
88 // decreases last _sliceThickness by _overlapLongestAxis to account for the way we handle base cells
90 }
91 }
92
96 void initTraversal() override {
98 // split domain across its longest dimension
99 auto minSliceThickness = _overlapLongestAxis + 1;
100 initSliceThickness(minSliceThickness);
101 }
102
106 void endTraversal() override {
107 if (this->_cells) {
108 auto &cells = *(this->_cells);
110 AUTOPAS_OPENMP(parallel for)
111 for (size_t i = 0; i < cells.size(); ++i) {
112 _dataLayoutConverter.storeDataLayout(cells[i]);
113 }
114 }
115 }
116
117 protected:
121 void init();
122
126 virtual void loadDataLayout() {
127 if (this->_cells) {
128 auto &cells = *(this->_cells);
130 AUTOPAS_OPENMP(parallel for)
131 for (size_t i = 0; i < cells.size(); ++i) {
132 _dataLayoutConverter.loadDataLayout(cells[i]);
133 }
134 }
135 }
136
142 // Reinitialize the sliced traversal with up to date tower information
143 const auto towerSideLength = vcl->getTowerSideLength();
144 this->_cellLength = {towerSideLength[0], towerSideLength[1], vcl->getBoxMax()[2] - vcl->getBoxMin()[2]};
145 const auto towersPerDim = vcl->getTowersPerDimension();
146 this->_cellsPerDimension = {towersPerDim[0], towersPerDim[1], 1};
147
148 // reinitialize
149 init();
150 }
151
155 std::array<unsigned long, 3> _overlap;
156
160 std::array<int, 3> _dimsSortedByLength;
161
165 unsigned long _overlapLongestAxis;
166
170 std::vector<unsigned long> _sliceThickness;
171
176
180 std::array<double, 3> _cellLength;
181
182 private:
186 double _interactionLength;
187
191 utils::DataLayoutConverter<Functor> _dataLayoutConverter;
192};
193
194template <class ParticleCell, class Functor>
196 for (unsigned int d = 0; d < 3; d++) {
197 _overlap[d] = std::ceil(_interactionLength / _cellLength[d]);
198 if (not _spaciallyForward) {
199 // there is potentially overlap in both directions.
200 _overlap[d] *= 2;
201 }
202 }
203
204 // find longest dimension
205 auto minMaxElem = std::minmax_element(this->_cellsPerDimension.begin(), this->_cellsPerDimension.end());
206 _dimsSortedByLength[0] = (int)std::distance(this->_cellsPerDimension.begin(), minMaxElem.second);
207 _dimsSortedByLength[2] = (int)std::distance(this->_cellsPerDimension.begin(), minMaxElem.first);
208 _dimsSortedByLength[1] = 3 - (_dimsSortedByLength[0] + _dimsSortedByLength[2]);
209
210 _overlapLongestAxis = _overlap[_dimsSortedByLength[0]];
211}
212
213} // namespace autopas
#define AUTOPAS_OPENMP(args)
Empty macro to throw away any arguments.
Definition: WrapOpenMP.h:126
A cell pair traversal.
Definition: CellTraversal.h:23
std::vector< ParticleCell > * _cells
The cells to traverse.
Definition: CellTraversal.h:60
std::array< unsigned long, 3 > _cellsPerDimension
The dimensions of the cellblock.
Definition: CellTraversal.h:55
Functor base class.
Definition: Functor.h:41
Class for Cells of Particles.
Definition: ParticleCell.h:49
This class provides base for locked- and colored sliced traversals.
Definition: SlicedBasedTraversal.h:29
void initTraversal() override
Load Data Layouts and sets up slice thicknesses.
Definition: SlicedBasedTraversal.h:96
std::array< unsigned long, 3 > _overlap
Overlap of interacting cells.
Definition: SlicedBasedTraversal.h:155
std::array< double, 3 > _cellLength
Cell length in CellBlock3D.
Definition: SlicedBasedTraversal.h:180
SlicedBasedTraversal(const std::array< unsigned long, 3 > &dims, Functor &functor, const double interactionLength, const std::array< double, 3 > &cellLength, DataLayoutOption dataLayout, bool useNewton3, bool spaciallyForward)
Constructor of the sliced traversal.
Definition: SlicedBasedTraversal.h:43
std::vector< unsigned long > _sliceThickness
The number of cells per slice in the dimension that was sliced.
Definition: SlicedBasedTraversal.h:170
virtual void loadDataLayout()
Load Data Layouts required for this Traversal if cells have been set through setCellsToTraverse().
Definition: SlicedBasedTraversal.h:126
void init()
Resets the cell structure of the traversal.
Definition: SlicedBasedTraversal.h:195
virtual void initSliceThickness(unsigned long minSliceThickness)
Sets up the slice thicknesses to create as many slices as possible while respecting minSliceThickness...
Definition: SlicedBasedTraversal.h:72
bool _spaciallyForward
Whether the base step only covers neigboring cells tha are spacially forward (for example c08).
Definition: SlicedBasedTraversal.h:175
void reinitForVCL(const VerletClusterLists< typename ParticleCell::ParticleType > *vcl)
Update cell information based on VerletClusterLists.
Definition: SlicedBasedTraversal.h:141
unsigned long _overlapLongestAxis
Overlap of interacting cells along the longest axis.
Definition: SlicedBasedTraversal.h:165
std::array< int, 3 > _dimsSortedByLength
Store ids of dimensions (0, 1, 2 = x, y, z) sorted by in decreasing order of number of cells in that ...
Definition: SlicedBasedTraversal.h:160
void endTraversal() override
Write Data to AoS if cells have been set through setCellsToTraverse().
Definition: SlicedBasedTraversal.h:106
bool isApplicableToDomain() const override
Checks if the traversal is applicable to the current state of the domain.
Definition: SlicedBasedTraversal.h:62
This interface serves as a common parent class for all traversals.
Definition: TraversalInterface.h:18
Particles are divided into clusters.
Definition: VerletClusterLists.h:56
auto getTowersPerDimension() const
Returns the number of grids per dimension on the container.
Definition: VerletClusterLists.h:873
const std::array< double, 3 > & getBoxMin() const override
Get the lower corner of the container without halo.
Definition: VerletClusterLists.h:944
auto getTowerSideLength() const
Returns the grid side length of the grids in the container.
Definition: VerletClusterLists.h:867
const std::array< double, 3 > & getBoxMax() const override
Get the upper corner of the container without halo.
Definition: VerletClusterLists.h:936
This converts cells to the target data Layout using the given functor.
Definition: DataLayoutConverter.h:19
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:34