AutoPas  3.0.0
Loading...
Searching...
No Matches
LinkedCells.h
Go to the documentation of this file.
1
8#pragma once
9
27#include "autopas/utils/inBox.h"
28
29namespace autopas {
30
39template <class Particle_T>
40class LinkedCells : public CellBasedParticleContainer<FullParticleCell<Particle_T>> {
41 public:
46
50 using ParticleType = Particle_T;
51
66 LinkedCells(const std::array<double, 3> &boxMin, const std::array<double, 3> &boxMax, const double cutoff,
67 const double skin, const double cellSizeFactor = 1.0, const size_t aosSortingThreshold = 8,
68 const size_t soaSortingThreshold = 50,
70 : CellBasedParticleContainer<ParticleCellType>(boxMin, boxMax, cutoff, skin, aosSortingThreshold,
71 soaSortingThreshold),
72 _cellBlock(this->_cells, boxMin, boxMax, cutoff + skin, cellSizeFactor),
73 _loadEstimator(loadEstimator) {}
74
75 [[nodiscard]] ContainerOption getContainerType() const override { return ContainerOption::linkedCells; }
76
77 void reserve(size_t numParticles, size_t numParticlesHaloEstimate) override {
78 _cellBlock.reserve(numParticles + numParticlesHaloEstimate);
79 }
80
84 void addParticleImpl(const Particle_T &p) override {
85 ParticleCellType &cell = _cellBlock.getContainingCell(p.getR());
86 cell.addParticle(p);
87 }
88
92 void addHaloParticleImpl(const Particle_T &haloParticle) override {
93 ParticleCellType &cell = _cellBlock.getContainingCell(haloParticle.getR());
94 cell.addParticle(haloParticle);
95 }
96
100 bool updateHaloParticle(const Particle_T &haloParticle) override {
101 auto cells = _cellBlock.getNearbyHaloCells(haloParticle.getR(), this->getVerletSkin());
102 for (auto cellptr : cells) {
103 bool updated = internal::checkParticleInCellAndUpdateByID(*cellptr, haloParticle);
104 if (updated) {
105 return true;
106 }
107 }
108 AutoPasLog(TRACE, "UpdateHaloParticle was not able to update particle: {}", haloParticle.toString());
109 return false;
110 }
111
115 void deleteHaloParticles() override { _cellBlock.clearHaloCells(); }
116
117 void rebuildNeighborLists(TraversalInterface *traversal) override {
118 // nothing to do.
119 }
120
126 // (Explicit) static cast required for Apple Clang (last tested version: 17.0.0)
127 switch (static_cast<LoadEstimatorOption::Value>(this->_loadEstimator)) {
129 return [&](const std::array<unsigned long, 3> &cellsPerDimension,
130 const std::array<unsigned long, 3> &lowerCorner, const std::array<unsigned long, 3> &upperCorner) {
131 return loadEstimators::squaredParticlesPerCell(this->_cells, cellsPerDimension, lowerCorner, upperCorner);
132 };
133 }
135 [[fallthrough]];
136 default: {
137 return
138 [&](const std::array<unsigned long, 3> &cellsPerDimension, const std::array<unsigned long, 3> &lowerCorner,
139 const std::array<unsigned long, 3> &upperCorner) { return 1; };
140 }
141 }
142 }
143
144 void computeInteractions(TraversalInterface *traversal) override {
145 prepareTraversal(traversal);
146
147 traversal->initTraversal();
148 traversal->traverseParticles();
149 traversal->endTraversal();
150 }
151
152 [[nodiscard]] std::vector<Particle_T> updateContainer(bool keepNeighborListsValid) override {
153 if (keepNeighborListsValid) {
155 }
156
157 this->deleteHaloParticles();
158
159 std::vector<Particle_T> invalidParticles;
160 AUTOPAS_OPENMP(parallel) {
161 // private for each thread!
162 std::vector<Particle_T> myInvalidParticles{}, myInvalidNotOwnedParticles{};
163 // TODO: needs smarter heuristic than this.
164 myInvalidParticles.reserve(128);
165 myInvalidNotOwnedParticles.reserve(128);
166 AUTOPAS_OPENMP(for)
167 for (size_t cellId = 0; cellId < this->getCells().size(); ++cellId) {
168 // Delete dummy particles of each cell.
169 this->getCells()[cellId].deleteDummyParticles();
170
171 // if empty
172 if (this->getCells()[cellId].isEmpty()) continue;
173
174 const auto [cellLowerCorner, cellUpperCorner] = this->getCellBlock().getCellBoundingBox(cellId);
175
176 auto &particleVec = this->getCells()[cellId]._particles;
177 for (auto pIter = particleVec.begin(); pIter < particleVec.end();) {
178 // if not in cell
179 if (utils::notInBox(pIter->getR(), cellLowerCorner, cellUpperCorner)) {
180 myInvalidParticles.push_back(*pIter);
181 // swap-delete
182 *pIter = particleVec.back();
183 particleVec.pop_back();
184 } else {
185 ++pIter;
186 }
187 }
188 }
189 // implicit barrier here
190 // the barrier is needed because iterators are not threadsafe w.r.t. addParticle()
191
192 // this loop is executed for every thread and thus parallel. Don't use #pragma omp for here!
193 for (auto &&p : myInvalidParticles) {
194 // if not in halo
195 if (utils::inBox(p.getR(), this->getBoxMin(), this->getBoxMax())) {
196 this->template addParticle<false>(p);
197 } else {
198 myInvalidNotOwnedParticles.push_back(p);
199 }
200 }
201 AUTOPAS_OPENMP(critical) {
202 // merge private vectors to global one.
203 invalidParticles.insert(invalidParticles.end(), myInvalidNotOwnedParticles.begin(),
204 myInvalidNotOwnedParticles.end());
205 }
206 }
207 return invalidParticles;
208 }
209
210 [[nodiscard]] TraversalSelectorInfo getTraversalSelectorInfo() const override {
211 return TraversalSelectorInfo(this->getCellBlock().getCellsPerDimensionWithHalo(), this->getInteractionLength(),
212 this->getCellBlock().getCellLength(), 0);
213 }
214
215 std::tuple<const Particle_T *, size_t, size_t> getParticle(size_t cellIndex, size_t particleIndex,
216 IteratorBehavior iteratorBehavior,
217 const std::array<double, 3> &boxMin,
218 const std::array<double, 3> &boxMax) const override {
219 return getParticleImpl<true>(cellIndex, particleIndex, iteratorBehavior, boxMin, boxMax);
220 }
221
222 std::tuple<const Particle_T *, size_t, size_t> getParticle(size_t cellIndex, size_t particleIndex,
223 IteratorBehavior iteratorBehavior) const override {
224 // this is not a region iter hence we stretch the bounding box to the numeric max
225 constexpr std::array<double, 3> boxMin{std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(),
226 std::numeric_limits<double>::lowest()};
227
228 constexpr std::array<double, 3> boxMax{std::numeric_limits<double>::max(), std::numeric_limits<double>::max(),
229 std::numeric_limits<double>::max()};
230 return getParticleImpl<false>(cellIndex, particleIndex, iteratorBehavior, boxMin, boxMax);
231 }
232
244 template <bool regionIter>
245 std::tuple<const Particle_T *, size_t, size_t> getParticleImpl(size_t cellIndex, size_t particleIndex,
246 IteratorBehavior iteratorBehavior,
247 const std::array<double, 3> &boxMin,
248 const std::array<double, 3> &boxMax) const {
249 using namespace autopas::utils::ArrayMath::literals;
250
251 std::array<double, 3> boxMinWithSafetyMargin = boxMin;
252 std::array<double, 3> boxMaxWithSafetyMargin = boxMax;
253 if constexpr (regionIter) {
254 // We extend the search box for cells here since particles might have moved
255 boxMinWithSafetyMargin -= this->getVerletSkin();
256 boxMaxWithSafetyMargin += this->getVerletSkin();
257 }
258
259 // first and last relevant cell index
260 const auto [startCellIndex, endCellIndex] = [&]() -> std::tuple<size_t, size_t> {
261 if constexpr (regionIter) {
262 // We extend the search box for cells here since particles might have moved
263 return {_cellBlock.get1DIndexOfPosition(boxMinWithSafetyMargin),
264 _cellBlock.get1DIndexOfPosition(boxMaxWithSafetyMargin)};
265 } else {
266 if (not(iteratorBehavior & IteratorBehavior::halo)) {
267 // only potentially owned region
268 return {_cellBlock.getFirstOwnedCellIndex(), _cellBlock.getLastOwnedCellIndex()};
269 } else {
270 // whole range of cells
271 return {0, this->_cells.size() - 1};
272 }
273 }
274 }();
275
276 // if we are at the start of an iteration ...
277 if (cellIndex == 0 and particleIndex == 0) {
278 cellIndex =
279 startCellIndex + ((iteratorBehavior & IteratorBehavior::forceSequential) ? 0 : autopas_get_thread_num());
280 }
281 // abort if the start index is already out of bounds
282 if (cellIndex >= this->_cells.size()) {
283 return {nullptr, 0, 0};
284 }
285 // check the data behind the indices
286 if (particleIndex >= this->_cells[cellIndex].size() or
287 not containerIteratorUtils::particleFulfillsIteratorRequirements<regionIter>(
288 this->_cells[cellIndex][particleIndex], iteratorBehavior, boxMin, boxMax)) {
289 // either advance them to something interesting or invalidate them.
290 std::tie(cellIndex, particleIndex) =
291 advanceIteratorIndices<regionIter>(cellIndex, particleIndex, iteratorBehavior, boxMin, boxMax,
292 boxMinWithSafetyMargin, boxMaxWithSafetyMargin, endCellIndex);
293 }
294
295 // shortcut if the given index doesn't exist
296 if (cellIndex > endCellIndex) {
297 return {nullptr, 0, 0};
298 }
299 const Particle_T *retPtr = &this->_cells[cellIndex][particleIndex];
300
301 return {retPtr, cellIndex, particleIndex};
302 }
303
307 bool deleteParticle(Particle_T &particle) override {
308 // deduce into which vector the reference points
309 auto &particleVec = _cellBlock.getContainingCell(particle.getR())._particles;
310 const bool isRearParticle = &particle == &particleVec.back();
311 // swap-delete
312 particle = particleVec.back();
313 particleVec.pop_back();
314 return not isRearParticle;
315 }
316
320 bool deleteParticle(size_t cellIndex, size_t particleIndex) override {
321 auto &particleVec = this->_cells[cellIndex]._particles;
322 auto &particle = particleVec[particleIndex];
323 // swap-delete
324 particle = particleVec.back();
325 particleVec.pop_back();
326 return particleIndex < particleVec.size();
327 }
328
333 IteratorBehavior behavior = IteratorBehavior::ownedOrHalo,
335 std::nullopt) override {
336 return ContainerIterator<Particle_T, true, false>(*this, behavior, additionalVectors);
337 }
338
343 IteratorBehavior behavior = IteratorBehavior::ownedOrHalo,
345 std::nullopt) const override {
346 return ContainerIterator<Particle_T, false, false>(*this, behavior, additionalVectors);
347 }
348
355 template <typename Lambda>
356 void forEach(Lambda forEachLambda, IteratorBehavior behavior = IteratorBehavior::ownedOrHalo) {
357 if (behavior == IteratorBehavior::ownedOrHaloOrDummy) {
358 for (auto &cell : getCells()) {
359 cell.forEach(forEachLambda);
360 }
361 } else {
362 for (size_t index = 0; index < getCells().size(); index++) {
363 if (not _cellBlock.ignoreCellForIteration(index, behavior)) {
364 getCells()[index].forEach(forEachLambda, behavior);
365 }
366 }
367 }
368 }
369
378 template <typename Lambda, typename A>
379 void reduce(Lambda reduceLambda, A &result, IteratorBehavior behavior = IteratorBehavior::ownedOrHalo) {
380 if (behavior == IteratorBehavior::ownedOrHaloOrDummy) {
381 for (auto &cell : getCells()) {
382 cell.reduce(reduceLambda, result);
383 }
384 } else {
385 for (size_t index = 0; index < getCells().size(); index++) {
386 if (not _cellBlock.ignoreCellForIteration(index, behavior)) {
387 getCells()[index].reduce(reduceLambda, result, behavior);
388 }
389 }
390 }
391 }
392
397 const std::array<double, 3> &lowerCorner, const std::array<double, 3> &higherCorner, IteratorBehavior behavior,
399 std::nullopt) override {
400 return ContainerIterator<Particle_T, true, true>(*this, behavior, additionalVectors, lowerCorner, higherCorner);
401 }
402
407 const std::array<double, 3> &lowerCorner, const std::array<double, 3> &higherCorner, IteratorBehavior behavior,
409 std::nullopt) const override {
410 return ContainerIterator<Particle_T, false, true>(*this, behavior, additionalVectors, lowerCorner, higherCorner);
411 }
412
421 template <typename Lambda>
422 void forEachInRegion(Lambda forEachLambda, const std::array<double, 3> &lowerCorner,
423 const std::array<double, 3> &higherCorner, IteratorBehavior behavior) {
424 using namespace autopas::utils::ArrayMath::literals;
425
426 const auto startIndex3D = this->_cellBlock.get3DIndexOfPosition(lowerCorner - this->getVerletSkin());
427 const auto stopIndex3D = this->_cellBlock.get3DIndexOfPosition(higherCorner + this->getVerletSkin());
428
429 const size_t numCellsOfInterest = (stopIndex3D[0] - startIndex3D[0] + 1) * (stopIndex3D[1] - startIndex3D[1] + 1) *
430 (stopIndex3D[2] - startIndex3D[2] + 1);
431 std::vector<size_t> cellsOfInterest;
432 cellsOfInterest.reserve(numCellsOfInterest);
433
434 const auto &cellsPerDimensionWithHalo = this->_cellBlock.getCellsPerDimensionWithHalo();
435
436 for (size_t z = startIndex3D[2]; z <= stopIndex3D[2]; ++z) {
437 for (size_t y = startIndex3D[1]; y <= stopIndex3D[1]; ++y) {
438 for (size_t x = startIndex3D[0]; x <= stopIndex3D[0]; ++x) {
439 cellsOfInterest.push_back(utils::ThreeDimensionalMapping::threeToOneD({x, y, z}, cellsPerDimensionWithHalo));
440 }
441 }
442 }
443
444 for (auto cellIndex : cellsOfInterest) {
445 if (not _cellBlock.ignoreCellForIteration(cellIndex, behavior)) {
446 getCells()[cellIndex].forEach(forEachLambda, lowerCorner, higherCorner, behavior);
447 }
448 }
449 }
450
461 template <typename Lambda, typename A>
462 void reduceInRegion(Lambda reduceLambda, A &result, const std::array<double, 3> &lowerCorner,
463 const std::array<double, 3> &higherCorner, IteratorBehavior behavior) {
464 using namespace autopas::utils::ArrayMath::literals;
465 const auto startIndex3D = this->_cellBlock.get3DIndexOfPosition(lowerCorner - this->getVerletSkin());
466 const auto stopIndex3D = this->_cellBlock.get3DIndexOfPosition(higherCorner + this->getVerletSkin());
467
468 const size_t numCellsOfInterest = (stopIndex3D[0] - startIndex3D[0] + 1) * (stopIndex3D[1] - startIndex3D[1] + 1) *
469 (stopIndex3D[2] - startIndex3D[2] + 1);
470 std::vector<size_t> cellsOfInterest;
471 cellsOfInterest.reserve(numCellsOfInterest);
472
473 const auto &cellsPerDimensionWithHalo = this->_cellBlock.getCellsPerDimensionWithHalo();
474
475 for (size_t z = startIndex3D[2]; z <= stopIndex3D[2]; ++z) {
476 for (size_t y = startIndex3D[1]; y <= stopIndex3D[1]; ++y) {
477 for (size_t x = startIndex3D[0]; x <= stopIndex3D[0]; ++x) {
478 cellsOfInterest.push_back(utils::ThreeDimensionalMapping::threeToOneD({x, y, z}, cellsPerDimensionWithHalo));
479 }
480 }
481 }
482
483 for (auto cellIndex : cellsOfInterest) {
484 if (not _cellBlock.ignoreCellForIteration(cellIndex, behavior)) {
485 getCells()[cellIndex].reduce(reduceLambda, result, lowerCorner, higherCorner, behavior);
486 }
487 }
488 }
489
495
501
506 std::vector<ParticleCellType> &getCells() { return this->_cells; }
507
508 protected:
523 template <bool regionIter>
524 std::tuple<size_t, size_t> advanceIteratorIndices(
525 size_t cellIndex, size_t particleIndex, IteratorBehavior iteratorBehavior, const std::array<double, 3> &boxMin,
526 const std::array<double, 3> &boxMax, std::array<double, 3> boxMinWithSafetyMargin,
527 std::array<double, 3> boxMaxWithSafetyMargin, size_t endCellIndex) const {
528 // Finding the indices for the next particle
529 const size_t stride = (iteratorBehavior & IteratorBehavior::forceSequential) ? 1 : autopas_get_num_threads();
530
531 // helper function to determine if the cell can even contain particles of interest to the iterator
532 auto cellIsRelevant = [&]() -> bool {
533 bool isRelevant =
534 // behavior matches possible particle ownership
535 (iteratorBehavior & IteratorBehavior::owned and _cellBlock.cellCanContainOwnedParticles(cellIndex)) or
536 (iteratorBehavior & IteratorBehavior::halo and _cellBlock.cellCanContainHaloParticles(cellIndex));
537 if constexpr (regionIter) {
538 // short circuit if already false
539 if (isRelevant) {
540 // is the cell in the region?
541 const auto [cellLowCorner, cellHighCorner] = _cellBlock.getCellBoundingBox(cellIndex);
542 isRelevant =
543 utils::boxesOverlap(cellLowCorner, cellHighCorner, boxMinWithSafetyMargin, boxMaxWithSafetyMargin);
544 }
545 }
546 return isRelevant;
547 };
548
549 do {
550 // advance to the next particle
551 ++particleIndex;
552 // If this breaches the end of a cell, find the next non-empty cell and reset particleIndex.
553
554 // If cell has wrong type, or there are no more particles in this cell jump to the next
555 while (not cellIsRelevant() or particleIndex >= this->_cells[cellIndex].size()) {
556 // TODO: can this jump be done more efficient if behavior is only halo or owned?
557 // TODO: can this jump be done more efficient for region iters if the cell is outside the region?
558 cellIndex += stride;
559 particleIndex = 0;
560
561 // If we notice that there is nothing else to look at set invalid values, so we get a nullptr next time and
562 // break.
563 if (cellIndex > endCellIndex) {
564 return {std::numeric_limits<decltype(cellIndex)>::max(), std::numeric_limits<decltype(particleIndex)>::max()};
565 }
566 }
567 } while (not containerIteratorUtils::particleFulfillsIteratorRequirements<regionIter>(
568 this->_cells[cellIndex][particleIndex], iteratorBehavior, boxMin, boxMax));
569
570 // the indices returned at this point should always be valid
571 return {cellIndex, particleIndex};
572 }
573
579 template <typename Traversal>
580 void prepareTraversal(Traversal &traversal) {
581 auto *traversalInterface = dynamic_cast<LCTraversalInterface *>(traversal);
582 auto *cellTraversal = dynamic_cast<CellTraversal<ParticleCellType> *>(traversal);
583 if (auto *balancedTraversal = dynamic_cast<BalancedTraversal *>(traversal)) {
584 balancedTraversal->setLoadEstimator(getLoadEstimatorFunction());
585 }
586 if (traversalInterface && cellTraversal) {
587 cellTraversal->setAoSSortingThreshold(this->_aosSortingThreshold);
588 cellTraversal->setSoASortingThreshold(this->_soaSortingThreshold);
589 cellTraversal->setCellsToTraverse(this->_cells);
590 } else {
592 "The selected traversal is not compatible with the LinkedCells container. TraversalID: {}",
593 traversal->getTraversalType());
594 }
595 }
596
601
606};
607
608} // namespace autopas
#define AutoPasLog(lvl, fmt,...)
Macro for logging providing common meta information without filename.
Definition: Logger.h:24
#define AUTOPAS_OPENMP(args)
Empty macro to throw away any arguments.
Definition: WrapOpenMP.h:126
Base class for traversals utilising load balancing.
Definition: BalancedTraversal.h:19
std::function< unsigned long(const std::array< unsigned long, 3 > &, const std::array< unsigned long, 3 > &, const std::array< unsigned long, 3 > &)> EstimatorFunction
Type signature for load estimators.
Definition: BalancedTraversal.h:26
The CellBasedParticleContainer class stores particles in some object and provides methods to iterate ...
Definition: CellBasedParticleContainer.h:25
size_t size() const override
Get the total number of particles saved in the container (owned + halo + dummy).
Definition: CellBasedParticleContainer.h:136
double getVerletSkin() const final
Returns the verlet Skin length.
Definition: CellBasedParticleContainer.h:99
size_t _aosSortingThreshold
If the number of particles in a cell or cell pair exceeds this threshold, the particles will be sorte...
Definition: CellBasedParticleContainer.h:167
size_t _soaSortingThreshold
If the sum of the SoA buffer sizes of two cells exceeds this threshold, SoAFunctorPairSorted is used.
Definition: CellBasedParticleContainer.h:171
double getInteractionLength() const final
Return the interaction length (cutoff+skin) of the container.
Definition: CellBasedParticleContainer.h:94
std::vector< ParticleCellType > _cells
Vector of particle cells.
Definition: CellBasedParticleContainer.h:162
A cell pair traversal.
Definition: CellTraversal.h:23
virtual void setAoSSortingThreshold(size_t aosSortingThreshold)=0
Set the aos-sorting-threshold for traversals that use the CellFunctor If the sum of the number of par...
Public iterator class that iterates over a particle container and additional vectors (which are typic...
Definition: ContainerIterator.h:95
std::conditional_t< modifiable, std::vector< std::vector< Particle_T > * >, std::vector< std::vector< Particle_T > const * > > ParticleVecType
Type of the additional vector collection.
Definition: ContainerIterator.h:108
This class handles the storage of particles in their full form.
Definition: FullParticleCell.h:26
void addParticle(const Particle_T &p) override
Adds a Particle to the cell.
Definition: FullParticleCell.h:51
Interface for traversals used by the LinkedCell class.
Definition: LCTraversalInterface.h:18
LinkedCells class.
Definition: LinkedCells.h:40
bool deleteParticle(size_t cellIndex, size_t particleIndex) override
Deletes the particle at the given index positions as long as this does not compromise the validity of...
Definition: LinkedCells.h:320
std::tuple< const Particle_T *, size_t, size_t > getParticleImpl(size_t cellIndex, size_t particleIndex, IteratorBehavior iteratorBehavior, const std::array< double, 3 > &boxMin, const std::array< double, 3 > &boxMax) const
Container specific implementation for getParticle.
Definition: LinkedCells.h:245
internal::CellBlock3D< ParticleCellType > & getCellBlock()
Get the cell block, not supposed to be used except by verlet lists.
Definition: LinkedCells.h:494
BalancedTraversal::EstimatorFunction getLoadEstimatorFunction()
Generates the load estimation function depending on _loadEstimator.
Definition: LinkedCells.h:125
void forEachInRegion(Lambda forEachLambda, const std::array< double, 3 > &lowerCorner, const std::array< double, 3 > &higherCorner, IteratorBehavior behavior)
Execute code on all particles in this container in a certain region as defined by a lambda function.
Definition: LinkedCells.h:422
void addParticleImpl(const Particle_T &p) override
Adds a particle to the container.
Definition: LinkedCells.h:84
void deleteHaloParticles() override
Deletes all halo particles.
Definition: LinkedCells.h:115
ContainerIterator< Particle_T, true, false > begin(IteratorBehavior behavior=IteratorBehavior::ownedOrHalo, utils::optRef< typename ContainerIterator< Particle_T, true, false >::ParticleVecType > additionalVectors=std::nullopt) override
Iterate over all particles using for(auto iter = container.begin(); iter.isValid(); ++iter) .
Definition: LinkedCells.h:332
bool updateHaloParticle(const Particle_T &haloParticle) override
Update a halo particle of the container with the given haloParticle.
Definition: LinkedCells.h:100
void addHaloParticleImpl(const Particle_T &haloParticle) override
Adds a particle to the container that lies in the halo region of the container.
Definition: LinkedCells.h:92
LoadEstimatorOption _loadEstimator
load estimation algorithm for balanced traversals.
Definition: LinkedCells.h:605
void prepareTraversal(Traversal &traversal)
Checks if a given traversal is allowed for LinkedCells and sets it up for the force interactions.
Definition: LinkedCells.h:580
std::vector< Particle_T > updateContainer(bool keepNeighborListsValid) override
Updates the container.
Definition: LinkedCells.h:152
void reduceInRegion(Lambda reduceLambda, A &result, const std::array< double, 3 > &lowerCorner, const std::array< double, 3 > &higherCorner, IteratorBehavior behavior)
Execute code on all particles in this container in a certain region as defined by a lambda function.
Definition: LinkedCells.h:462
ContainerIterator< Particle_T, true, true > getRegionIterator(const std::array< double, 3 > &lowerCorner, const std::array< double, 3 > &higherCorner, IteratorBehavior behavior, utils::optRef< typename ContainerIterator< Particle_T, true, true >::ParticleVecType > additionalVectors=std::nullopt) override
Iterate over all particles in a specified region for(auto iter = container.getRegionIterator(lowCorne...
Definition: LinkedCells.h:396
ContainerIterator< Particle_T, false, true > getRegionIterator(const std::array< double, 3 > &lowerCorner, const std::array< double, 3 > &higherCorner, IteratorBehavior behavior, utils::optRef< typename ContainerIterator< Particle_T, false, true >::ParticleVecType > additionalVectors=std::nullopt) const override
Iterate over all particles in a specified region for(auto iter = container.getRegionIterator(lowCorne...
Definition: LinkedCells.h:406
void reduce(Lambda reduceLambda, A &result, IteratorBehavior behavior=IteratorBehavior::ownedOrHalo)
Reduce properties of particles as defined by a lambda function.
Definition: LinkedCells.h:379
std::vector< ParticleCellType > & getCells()
Returns a non-const reference to the cell data structure.
Definition: LinkedCells.h:506
const internal::CellBlock3D< ParticleCellType > & getCellBlock() const
Get the cell block, not supposed to be used except by verlet lists.
Definition: LinkedCells.h:500
Particle_T ParticleType
Type of the Particle.
Definition: LinkedCells.h:50
bool deleteParticle(Particle_T &particle) override
Deletes the given particle as long as this does not compromise the validity of the container.
Definition: LinkedCells.h:307
TraversalSelectorInfo getTraversalSelectorInfo() const override
Generates a traversal selector info for this container.
Definition: LinkedCells.h:210
void computeInteractions(TraversalInterface *traversal) override
Iterates over all particle multiples (e.g.
Definition: LinkedCells.h:144
void reserve(size_t numParticles, size_t numParticlesHaloEstimate) override
Reserve memory for a given number of particles in the container and logic layers.
Definition: LinkedCells.h:77
void rebuildNeighborLists(TraversalInterface *traversal) override
Rebuilds the neighbor lists for the next traversals.
Definition: LinkedCells.h:117
ContainerIterator< Particle_T, false, false > begin(IteratorBehavior behavior=IteratorBehavior::ownedOrHalo, utils::optRef< typename ContainerIterator< Particle_T, false, false >::ParticleVecType > additionalVectors=std::nullopt) const override
Iterate over all particles using for(auto iter = container.begin(); iter.isValid(); ++iter) .
Definition: LinkedCells.h:342
std::tuple< size_t, size_t > advanceIteratorIndices(size_t cellIndex, size_t particleIndex, IteratorBehavior iteratorBehavior, const std::array< double, 3 > &boxMin, const std::array< double, 3 > &boxMax, std::array< double, 3 > boxMinWithSafetyMargin, std::array< double, 3 > boxMaxWithSafetyMargin, size_t endCellIndex) const
Given a pair of cell-/particleIndex and iterator restrictions either returns the next indices that ma...
Definition: LinkedCells.h:524
void forEach(Lambda forEachLambda, IteratorBehavior behavior=IteratorBehavior::ownedOrHalo)
Execute code on all particles in this container as defined by a lambda function.
Definition: LinkedCells.h:356
std::tuple< const Particle_T *, size_t, size_t > getParticle(size_t cellIndex, size_t particleIndex, IteratorBehavior iteratorBehavior, const std::array< double, 3 > &boxMin, const std::array< double, 3 > &boxMax) const override
Fetch the pointer to a particle, identified via a cell and particle index.
Definition: LinkedCells.h:215
ContainerOption getContainerType() const override
Get the ContainerType.
Definition: LinkedCells.h:75
std::tuple< const Particle_T *, size_t, size_t > getParticle(size_t cellIndex, size_t particleIndex, IteratorBehavior iteratorBehavior) const override
Fetch the pointer to a particle, identified via a cell and particle index.
Definition: LinkedCells.h:222
LinkedCells(const std::array< double, 3 > &boxMin, const std::array< double, 3 > &boxMax, const double cutoff, const double skin, const double cellSizeFactor=1.0, const size_t aosSortingThreshold=8, const size_t soaSortingThreshold=50, LoadEstimatorOption loadEstimator=LoadEstimatorOption::squaredParticlesPerCell)
Constructor of the LinkedCells class.
Definition: LinkedCells.h:66
internal::CellBlock3D< ParticleCellType > _cellBlock
object to manage the block of cells.
Definition: LinkedCells.h:600
Class representing the load estimator choices.
Definition: LoadEstimatorOption.h:18
Value
Possible choices for the load estimation algorithm.
Definition: LoadEstimatorOption.h:23
@ squaredParticlesPerCell
Number of particles per cell squared.
Definition: LoadEstimatorOption.h:31
@ none
No load estimator.
Definition: LoadEstimatorOption.h:27
This interface serves as a common parent class for all traversals.
Definition: TraversalInterface.h:18
virtual void endTraversal()=0
Finalizes the traversal.
virtual void traverseParticles()=0
Traverse the particles by pairs, triplets etc.
virtual void initTraversal()=0
Initializes the traversal.
Info for traversals of a specific container.
Definition: TraversalSelectorInfo.h:14
Class that manages a block of ParticleCells.
Definition: CellBlock3D.h:30
static void exception(const Exception e)
Handle an exception derived by std::exception.
Definition: ExceptionHandler.h:64
std::vector< typename ContainerType::ParticleType > collectParticlesAndMarkNonOwnedAsDummy(ContainerType &container)
Collects leaving particles and marks halo particles as dummy.
Definition: LeavingParticleCollector.h:85
static bool checkParticleInCellAndUpdateByID(CellType &cell, const typename CellType::ParticleType &particle)
Updates a found particle within cellI to the values of particleI.
Definition: ParticleCellHelpers.h:21
unsigned long squaredParticlesPerCell(const std::vector< ParticleCell > &cells, const std::array< unsigned long, 3 > &cellsPerDimension, const std::array< unsigned long, 3 > &lowerCorner, const std::array< unsigned long, 3 > &upperCorner)
Sums up the squared number of particles for all cells within region.
Definition: LoadEstimators.h:31
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
bool boxesOverlap(const std::array< T, 3 > &boxALow, const std::array< T, 3 > &boxAHigh, const std::array< T, 3 > &boxBLow, const std::array< T, 3 > &boxBHigh)
Checks if two boxes have overlap.
Definition: inBox.h:67
bool notInBox(const std::array< T, 3 > &position, const std::array< T, 3 > &low, const std::array< T, 3 > &high)
Checks if position is not inside of a box defined by low and high.
Definition: inBox.h:50
bool inBox(const std::array< T, 3 > &position, const std::array< T, 3 > &low, const std::array< T, 3 > &high)
Checks if position is inside of a box defined by low and high.
Definition: inBox.h:26
std::optional< std::reference_wrapper< T > > optRef
Short alias for std::optional<std::reference_wrapper<T>>
Definition: optRef.h:16
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:34
int autopas_get_num_threads()
Dummy for omp_get_num_threads() when no OpenMP is available.
Definition: WrapOpenMP.h:138
int autopas_get_thread_num()
Dummy for omp_set_lock() when no OpenMP is available.
Definition: WrapOpenMP.h:132