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
63 [[nodiscard]] bool isApplicable() const override {
64 auto minSliceThickness = _overlapLongestAxis + 1;
65 auto maxNumSlices = this->_cellsPerDimension[_dimsSortedByLength[0]] / minSliceThickness;
66 return maxNumSlices > 0;
67 }
68
73 virtual void initSliceThickness(unsigned long minSliceThickness) {
74 auto numSlices = this->_cellsPerDimension[_dimsSortedByLength[0]] / minSliceThickness;
75 _sliceThickness.clear();
76
77 // abort if domain is too small -> cleared _sliceThickness array indicates non applicability
78 if (numSlices < 1) return;
79
80 _sliceThickness.insert(_sliceThickness.begin(), numSlices, minSliceThickness);
81 auto rest = this->_cellsPerDimension[_dimsSortedByLength[0]] - _sliceThickness[0] * numSlices;
82 // remaining slices to distribute the remaining layers on
83 auto remSlices = std::min(rest, numSlices);
84 for (size_t i = 0; i < remSlices; ++i) {
85 _sliceThickness[i] += rest / (remSlices - i);
86 rest -= rest / (remSlices - i);
87 }
89 // decreases last _sliceThickness by _overlapLongestAxis to account for the way we handle base cells
91 }
92 }
93
97 void initTraversal() override {
99 // split domain across its longest dimension
100 auto minSliceThickness = _overlapLongestAxis + 1;
101 initSliceThickness(minSliceThickness);
102 }
103
107 void endTraversal() override {
108 if (this->_cells) {
109 auto &cells = *(this->_cells);
111 AUTOPAS_OPENMP(parallel for)
112 for (size_t i = 0; i < cells.size(); ++i) {
113 _dataLayoutConverter.storeDataLayout(cells[i]);
114 }
115 }
116 }
117
118 protected:
122 void init();
123
127 virtual void loadDataLayout() {
128 if (this->_cells) {
129 auto &cells = *(this->_cells);
131 AUTOPAS_OPENMP(parallel for)
132 for (size_t i = 0; i < cells.size(); ++i) {
133 _dataLayoutConverter.loadDataLayout(cells[i]);
134 }
135 }
136 }
137
143 // Reinitialize the sliced traversal with up to date tower information
144 const auto towerSideLength = vcl->getTowerSideLength();
145 this->_cellLength = {towerSideLength[0], towerSideLength[1], vcl->getBoxMax()[2] - vcl->getBoxMin()[2]};
146 const auto towersPerDim = vcl->getTowersPerDimension();
147 this->_cellsPerDimension = {towersPerDim[0], towersPerDim[1], 1};
148
149 // reinitialize
150 init();
151 }
152
156 std::array<unsigned long, 3> _overlap;
157
161 std::array<int, 3> _dimsSortedByLength;
162
166 unsigned long _overlapLongestAxis;
167
171 std::vector<unsigned long> _sliceThickness;
172
177
181 std::array<double, 3> _cellLength;
182
183 private:
187 double _interactionLength;
188
192 utils::DataLayoutConverter<Functor> _dataLayoutConverter;
193};
194
195template <class ParticleCell, class Functor>
197 for (unsigned int d = 0; d < 3; d++) {
198 _overlap[d] = std::ceil(_interactionLength / _cellLength[d]);
199 if (not _spaciallyForward) {
200 // there is potentially overlap in both directions.
201 _overlap[d] *= 2;
202 }
203 }
204
205 // find longest dimension
206 auto minMaxElem = std::minmax_element(this->_cellsPerDimension.begin(), this->_cellsPerDimension.end());
207 _dimsSortedByLength[0] = (int)std::distance(this->_cellsPerDimension.begin(), minMaxElem.second);
208 _dimsSortedByLength[2] = (int)std::distance(this->_cellsPerDimension.begin(), minMaxElem.first);
209 _dimsSortedByLength[1] = 3 - (_dimsSortedByLength[0] + _dimsSortedByLength[2]);
210
211 _overlapLongestAxis = _overlap[_dimsSortedByLength[0]];
212}
213
214} // 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:40
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:97
std::array< unsigned long, 3 > _overlap
Overlap of interacting cells.
Definition: SlicedBasedTraversal.h:156
std::array< double, 3 > _cellLength
Cell length in CellBlock3D.
Definition: SlicedBasedTraversal.h:181
std::vector< unsigned long > _sliceThickness
The number of cells per slice in the dimension that was sliced.
Definition: SlicedBasedTraversal.h:171
virtual void loadDataLayout()
Load Data Layouts required for this Traversal if cells have been set through setCellsToTraverse().
Definition: SlicedBasedTraversal.h:127
void init()
Resets the cell structure of the traversal.
Definition: SlicedBasedTraversal.h:196
virtual void initSliceThickness(unsigned long minSliceThickness)
Sets up the slice thicknesses to create as many slices as possible while respecting minSliceThickness...
Definition: SlicedBasedTraversal.h:73
bool _spaciallyForward
Whether the base step only covers neigboring cells tha are spacially forward (for example c08).
Definition: SlicedBasedTraversal.h:176
void reinitForVCL(const VerletClusterLists< typename ParticleCell::ParticleType > *vcl)
Update cell information based on VerletClusterLists.
Definition: SlicedBasedTraversal.h:142
unsigned long _overlapLongestAxis
Overlap of interacting cells along the longest axis.
Definition: SlicedBasedTraversal.h:166
bool isApplicable() const override
Checks if the traversal is applicable to the current state of the domain.
Definition: SlicedBasedTraversal.h:63
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:161
void endTraversal() override
Write Data to AoS if cells have been set through setCellsToTraverse().
Definition: SlicedBasedTraversal.h:107
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
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:871
const std::array< double, 3 > & getBoxMin() const override
Get the lower corner of the container without halo.
Definition: VerletClusterLists.h:942
auto getTowerSideLength() const
Returns the grid side length of the grids in the container.
Definition: VerletClusterLists.h:865
const std::array< double, 3 > & getBoxMax() const override
Get the upper corner of the container without halo.
Definition: VerletClusterLists.h:934
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:32