AutoPas  3.0.0
Loading...
Searching...
No Matches
Octree.h
Go to the documentation of this file.
1
8#pragma once
9
10#include <cstdio>
11#include <list>
12#include <stack>
13
24#include "autopas/utils/inBox.h"
26
27namespace autopas {
28
39template <class Particle_T>
40class Octree : public CellBasedParticleContainer<OctreeNodeWrapper<Particle_T>>,
42 public:
47
52
58 enum CellTypes : int { OWNED = 0, HALO = 1 };
59
63 constexpr static size_t invalidCellIndex = 9;
64
74 Octree(const std::array<double, 3> &boxMin, const std::array<double, 3> &boxMax, const double cutoff,
75 const double skin, const double cellSizeFactor, const size_t sortingThreshold)
76 : CellBasedParticleContainer<ParticleCellType>(boxMin, boxMax, cutoff, skin, sortingThreshold) {
77 using namespace autopas::utils::ArrayMath::literals;
78
79 // @todo Obtain this from a configuration, reported in https://github.com/AutoPas/AutoPas/issues/624
80 int unsigned treeSplitThreshold = 16;
81
82 double interactionLength = this->getInteractionLength();
83
84 // Create the octree for the owned particles
85 this->_cells.push_back(
86 OctreeNodeWrapper<Particle_T>(boxMin, boxMax, treeSplitThreshold, interactionLength, cellSizeFactor));
87
88 // Extend the halo region with cutoff + skin in all dimensions
89 auto haloBoxMin = boxMin - interactionLength;
90 auto haloBoxMax = boxMax + interactionLength;
91 // Create the octree for the halo particles
92 this->_cells.push_back(
93 OctreeNodeWrapper<Particle_T>(haloBoxMin, haloBoxMax, treeSplitThreshold, interactionLength, cellSizeFactor));
94
95 // set type of particles in the two cells
96 this->_cells[CellTypes::OWNED].setPossibleParticleOwnerships(OwnershipState::owned);
97 this->_cells[CellTypes::HALO].setPossibleParticleOwnerships(OwnershipState::halo);
98 }
99
100 [[nodiscard]] std::vector<ParticleType> updateContainer(bool keepNeighborListValid) override {
101 // invalidParticles: all outside boxMin/Max
102 std::vector<Particle_T> invalidParticles{};
103
104 if (keepNeighborListValid) {
106 } else {
107 // This is a very primitive and inefficient way to rebuild the container:
108
109 // @todo Make this less indirect. (Find a better way to iterate all particles inside the octree to change
110 // this function back to a function that actually copies all particles out of the octree.)
111 // The problem is captured by https://github.com/AutoPas/AutoPas/issues/622
112
113 // 1. Copy all particles out of the container
114 std::vector<Particle_T *> particleRefs;
115 this->_cells[CellTypes::OWNED].collectAllParticles(particleRefs);
116 std::vector<Particle_T> particles{};
117 particles.reserve(particleRefs.size());
118
119 for (auto *p : particleRefs) {
120 if (p->isDummy()) {
121 // don't do anything with dummies. They will just be dropped when the container is rebuilt.
122 continue;
123 } else if (utils::inBox(p->getR(), this->getBoxMin(), this->getBoxMax())) {
124 particles.push_back(*p);
125 } else {
126 invalidParticles.push_back(*p);
127 }
128 }
129
130 // 2. Clear the container
131 this->deleteAllParticles();
132
133 // 3. Insert the particles back into the container
134 for (auto &particle : particles) {
135 addParticleImpl(particle);
136 }
137 }
138
139 return invalidParticles;
140 }
141
142 void computeInteractions(TraversalInterface *traversal) override {
143 if (auto *traversalInterface = dynamic_cast<OTTraversalInterface<ParticleCellType> *>(traversal)) {
144 traversalInterface->setCells(&this->_cells);
145 }
146
147 traversal->initTraversal();
148 traversal->traverseParticles();
149 traversal->endTraversal();
150 }
151
155 [[nodiscard]] ContainerOption getContainerType() const override { return ContainerOption::octree; }
156
157 void reserve(size_t numParticles, size_t numParticlesHaloEstimate) override {
158 // TODO create a balanced tree and reserve space in the leaves.
159 }
160
164 void addParticleImpl(const ParticleType &p) override { this->_cells[CellTypes::OWNED].addParticle(p); }
165
169 void addHaloParticleImpl(const ParticleType &haloParticle) override {
170 this->_cells[CellTypes::HALO].addParticle(haloParticle);
171 }
172
176 bool updateHaloParticle(const ParticleType &haloParticle) override {
177 return internal::checkParticleInCellAndUpdateByIDAndPosition(this->_cells[CellTypes::HALO], haloParticle,
178 this->getVerletSkin());
179 }
180
181 void rebuildNeighborLists(TraversalInterface *traversal) override {}
182
183 std::tuple<const Particle_T *, size_t, size_t> getParticle(size_t cellIndex, size_t particleIndex,
184 IteratorBehavior iteratorBehavior,
185 const std::array<double, 3> &boxMin,
186 const std::array<double, 3> &boxMax) const override {
187 return getParticleImpl<true>(cellIndex, particleIndex, iteratorBehavior, boxMin, boxMax);
188 }
189 std::tuple<const Particle_T *, size_t, size_t> getParticle(size_t cellIndex, size_t particleIndex,
190 IteratorBehavior iteratorBehavior) const override {
191 // this is not a region iter hence we stretch the bounding box to the numeric max
192 constexpr std::array<double, 3> boxMin{std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(),
193 std::numeric_limits<double>::lowest()};
194
195 constexpr std::array<double, 3> boxMax{std::numeric_limits<double>::max(), std::numeric_limits<double>::max(),
196 std::numeric_limits<double>::max()};
197 return getParticleImpl<false>(cellIndex, particleIndex, iteratorBehavior, boxMin, boxMax);
198 }
199
217 template <bool regionIter>
218 std::tuple<const ParticleType *, size_t, size_t> getParticleImpl(size_t cellIndex, size_t particleIndex,
219 IteratorBehavior iteratorBehavior,
220 const std::array<double, 3> &boxMin,
221 const std::array<double, 3> &boxMax) const {
222 using namespace autopas::utils::ArrayMath::literals;
223 // FIXME think about parallelism.
224 // This `if` currently disables it but should be replaced with logic that determines the start index.
225 if (autopas_get_thread_num() > 0 and not(iteratorBehavior & IteratorBehavior::forceSequential)) {
226 return {nullptr, 0, 0};
227 }
228 // if owned particles are not interesting jump directly to the halo tree
229 // FIXME: with num threads > 1 the start cell IDs will have to be set to more complicated values here
230 if (cellIndex == 0 and not(iteratorBehavior & IteratorBehavior::owned)) {
231 cellIndex = HALO;
232 }
233
234 // shortcut if the given index doesn't exist
235 if (cellIndex < 10 and cellIndex > HALO) {
236 return {nullptr, 0, 0};
237 }
238
239 std::array<double, 3> boxMinWithSafetyMargin = boxMin;
240 std::array<double, 3> boxMaxWithSafetyMargin = boxMax;
241 if constexpr (regionIter) {
242 // We extend the search box for cells here since particles might have moved
243 boxMinWithSafetyMargin -= 0.5 * this->getVerletSkin();
244 boxMaxWithSafetyMargin += 0.5 * this->getVerletSkin();
245 }
246
247 std::vector<size_t> currentCellIndex{};
248 OctreeLeafNode<Particle_T> *currentCellPtr = nullptr;
249
250 std::tie(currentCellIndex, currentCellPtr) = getLeafCellByIndex(cellIndex);
251 // check the data behind the indices
252 if (particleIndex >= currentCellPtr->size() or
253 not containerIteratorUtils::particleFulfillsIteratorRequirements<regionIter>(
254 (*currentCellPtr)[particleIndex], iteratorBehavior, boxMin, boxMax)) {
255 // either advance them to something interesting or invalidate them.
256 std::tie(currentCellPtr, particleIndex) =
257 advanceIteratorIndices<regionIter>(currentCellIndex, currentCellPtr, particleIndex, iteratorBehavior, boxMin,
258 boxMax, boxMinWithSafetyMargin, boxMaxWithSafetyMargin);
259 }
260
261 // shortcut if the given index doesn't exist
262 if (currentCellPtr == nullptr) {
263 return {nullptr, 0, 0};
264 }
265 // parse cellIndex and get referenced cell and particle
266 const Particle_T *retPtr = &((*currentCellPtr)[particleIndex]);
267
268 // if no err value was set, convert cell index from vec to integer
269 if (currentCellIndex.empty()) {
270 cellIndex = invalidCellIndex;
271 } else {
272 cellIndex = 0;
273 // needs signed int to prevent underflow
274 for (int i = static_cast<int>(currentCellIndex.size()) - 1; i >= 0; --i) {
275 cellIndex *= 10;
276 cellIndex += currentCellIndex[i];
277 }
278 }
279
280 return {retPtr, cellIndex, particleIndex};
281 }
282
292 std::tuple<std::vector<size_t>, OctreeLeafNode<Particle_T> *> getLeafCellByIndex(size_t cellIndex) const {
293 // parse cellIndex and get referenced cell and particle
294 std::vector<size_t> currentCellIndex;
295 // constant heuristic for the tree depth
296 currentCellIndex.reserve(10);
297 currentCellIndex.push_back(cellIndex % 10);
298 cellIndex /= 10;
299 OctreeNodeInterface<Particle_T> *currentCell = this->_cells[currentCellIndex.back()].getRaw();
300 // don't restrict loop via cellIndex because it might have "hidden" leading 0
301 while (currentCell->hasChildren()) {
302 currentCellIndex.push_back(cellIndex % 10);
303 cellIndex /= 10;
304 currentCell = currentCell->getChild(currentCellIndex.back());
305 }
306 return {currentCellIndex, dynamic_cast<OctreeLeafNode<Particle_T> *>(currentCell)};
307 }
308
312 bool deleteParticle(Particle_T &particle) override {
313 if (particle.isOwned()) {
314 return this->_cells[CellTypes::OWNED].deleteParticle(particle);
315 } else if (particle.isHalo()) {
316 return this->_cells[CellTypes::HALO].deleteParticle(particle);
317 } else {
318 utils::ExceptionHandler::exception("Particle to be deleted is neither owned nor halo!\n" + particle.toString());
319 return false;
320 }
321 }
322
323 bool deleteParticle(size_t cellIndex, size_t particleIndex) override {
324 auto [cellIndexVector, cell] = getLeafCellByIndex(cellIndex);
325 auto &particleVec = cell->_particles;
326 auto &particle = particleVec[particleIndex];
327 // swap-delete
328 particle = particleVec.back();
329 particleVec.pop_back();
330 return particleIndex < particleVec.size();
331 }
332
337 IteratorBehavior behavior,
339 return ContainerIterator<Particle_T, true, false>(*this, behavior, additionalVectors);
340 }
341
346 IteratorBehavior behavior,
348 std::nullopt) const override {
349 return ContainerIterator<Particle_T, false, false>(*this, behavior, additionalVectors);
350 }
351
356 const std::array<double, 3> &lowerCorner, const std::array<double, 3> &higherCorner, IteratorBehavior behavior,
358 std::nullopt) override {
359 return ContainerIterator<Particle_T, true, true>(*this, behavior, additionalVectors, lowerCorner, higherCorner);
360 }
361
366 const std::array<double, 3> &lowerCorner, const std::array<double, 3> &higherCorner, IteratorBehavior behavior,
368 std::nullopt) const override {
369 return ContainerIterator<Particle_T, false, true>(*this, behavior, additionalVectors, lowerCorner, higherCorner);
370 }
371
375 [[nodiscard]] TraversalSelectorInfo getTraversalSelectorInfo() const override {
376 using namespace autopas::utils::ArrayMath::literals;
377
378 // this is a dummy since it is not actually used
379 const std::array<unsigned long, 3> dims = {1, 1, 1};
380 const std::array<double, 3> cellLength = this->getBoxMax() - this->getBoxMin();
381 return TraversalSelectorInfo(dims, this->getInteractionLength(), cellLength, 0);
382 }
383
388 [[nodiscard]] size_t size() const override {
389 return this->_cells[CellTypes::OWNED].size() + this->_cells[CellTypes::HALO].size();
390 }
391
395 [[nodiscard]] size_t getNumberOfParticles(IteratorBehavior behavior) const override {
396 return this->_cells[CellTypes::OWNED].getNumberOfParticles(behavior) +
397 this->_cells[CellTypes::HALO].getNumberOfParticles(behavior);
398 }
399
400 void deleteHaloParticles() override { this->_cells[CellTypes::HALO].clear(); }
401
402 [[nodiscard]] bool cellCanContainHaloParticles(std::size_t i) const override {
403 if (i > 1) {
404 throw std::runtime_error("[Octree.h]: This cell container (octree) contains only two cells");
405 }
406 return i == CellTypes::HALO;
407 }
408
409 [[nodiscard]] bool cellCanContainOwnedParticles(std::size_t i) const override {
410 if (i > 1) {
411 throw std::runtime_error("[Octree.h]: This cell container (octree) contains only two cells");
412 }
413 return i == CellTypes::OWNED;
414 }
415
422 template <typename Lambda>
423 void forEach(Lambda forEachLambda, IteratorBehavior behavior = IteratorBehavior::ownedOrHalo) {
424 if (behavior & IteratorBehavior::owned) this->_cells[OWNED].forEach(forEachLambda);
425 if (behavior & IteratorBehavior::halo) this->_cells[HALO].forEach(forEachLambda);
426 if (not(behavior & IteratorBehavior::ownedOrHalo))
427 utils::ExceptionHandler::exception("Encountered invalid iterator behavior!");
428 }
429
438 template <typename Lambda, typename A>
439 void reduce(Lambda reduceLambda, A &result, IteratorBehavior behavior = IteratorBehavior::ownedOrHalo) {
440 if (behavior & IteratorBehavior::owned) this->_cells[OWNED].reduce(reduceLambda, result);
441 if (behavior & IteratorBehavior::halo) this->_cells[HALO].reduce(reduceLambda, result);
442 if (not(behavior & IteratorBehavior::ownedOrHalo))
443 utils::ExceptionHandler::exception("Encountered invalid iterator behavior!");
444 }
445
449 template <typename Lambda>
450 void forEachInRegion(Lambda forEachLambda, const std::array<double, 3> &lowerCorner,
451 const std::array<double, 3> &higherCorner, IteratorBehavior behavior) {
452 if (behavior & IteratorBehavior::owned)
453 this->_cells[OWNED].forEachInRegion(forEachLambda, lowerCorner, higherCorner);
454 if (behavior & IteratorBehavior::halo) this->_cells[HALO].forEachInRegion(forEachLambda, lowerCorner, higherCorner);
455 if (not(behavior & IteratorBehavior::ownedOrHalo))
456 utils::ExceptionHandler::exception("Encountered invalid iterator behavior!");
457 }
458
462 template <typename Lambda, typename A>
463 void reduceInRegion(Lambda reduceLambda, A &result, const std::array<double, 3> &lowerCorner,
464 const std::array<double, 3> &higherCorner, IteratorBehavior behavior) {
465 if (behavior & IteratorBehavior::owned)
466 this->_cells[OWNED].reduceInRegion(reduceLambda, result, lowerCorner, higherCorner);
467 if (behavior & IteratorBehavior::halo)
468 this->_cells[HALO].reduceInRegion(reduceLambda, result, lowerCorner, higherCorner);
469 if (not(behavior & IteratorBehavior::ownedOrHalo))
470 utils::ExceptionHandler::exception("Encountered invalid iterator behavior!");
471 }
472
473 private:
489 template <bool regionIter>
490 std::tuple<OctreeLeafNode<Particle_T> *, size_t> advanceIteratorIndices(
491 std::vector<size_t> &currentCellIndex, OctreeNodeInterface<Particle_T> *const currentCellPtr,
492 size_t particleIndex, IteratorBehavior iteratorBehavior, const std::array<double, 3> &boxMin,
493 const std::array<double, 3> &boxMax, const std::array<double, 3> &boxMinWithSafetyMargin,
494 const std::array<double, 3> &boxMaxWithSafetyMargin) const {
495 // TODO: parallelize at the higher tree levels. Choose tree level to parallelize via log_8(numThreads)
496 const size_t minLevel = 0;
497 // (iteratorBehavior & IteratorBehavior::forceSequential) or autopas_get_num_threads() == 1
498 // ? 0
499 // : static_cast<size_t>(std::ceil(std::log(static_cast<double>(autopas_get_num_threads())) /
500 // std::log(8.)));
501 OctreeNodeInterface<Particle_T> *currentCellInterfacePtr = currentCellPtr;
502 OctreeLeafNode<Particle_T> *currentLeafCellPtr = nullptr;
503
504 // helper function:
505 auto cellIsRelevant = [&](const OctreeNodeInterface<Particle_T> *const cellPtr) {
506 bool isRelevant = cellPtr->size() > 0;
507 if constexpr (regionIter) {
508 isRelevant = utils::boxesOverlap(cellPtr->getBoxMin(), cellPtr->getBoxMax(), boxMinWithSafetyMargin,
509 boxMaxWithSafetyMargin);
510 }
511 return isRelevant;
512 };
513
514 // find the next particle of interest which might be in a different cell
515 do {
516 // advance to the next particle
517 ++particleIndex;
518
519 // this loop finds the next relevant leaf cell or triggers a return
520 // flag for weird corner cases. See further down.
521 bool forceJumpToNextCell = false;
522 // If this breaches the end of a cell, find the next non-empty cell and reset particleIndex.
523 while (particleIndex >= currentCellInterfacePtr->size() or forceJumpToNextCell) {
524 // CASE: we are at the end of a branch
525 // => Move up until there are siblings that were not touched yet
526 while (currentCellIndex.back() == 7) {
527 currentCellInterfacePtr = currentCellInterfacePtr->getParent();
528 currentCellIndex.pop_back();
529 // If there are no more cells in the branch that we are responsible for set invalid parameters and return.
530 if (currentCellIndex.size() < minLevel or currentCellIndex.empty()) {
531 currentCellIndex.clear();
532 return {nullptr, std::numeric_limits<decltype(particleIndex)>::max()};
533 }
534 }
535
536 // Switch to the next child of the same parent
537 ++currentCellIndex.back();
538 // Identify the next (inner) cell pointer
539 if (currentCellIndex.size() == 1) {
540 // if we are already beyond everything
541 if (currentCellIndex.back() > HALO) {
542 return {nullptr, std::numeric_limits<decltype(particleIndex)>::max()};
543 }
544 // special case: the current thread should ALSO iterate halo particles
545 if ((iteratorBehavior & IteratorBehavior::halo)
546 /* FIXME: for parallelization: and ((iteratorBehavior & IteratorBehavior::forceSequential) or autopas_get_num_threads() == 1) */) {
547 currentCellInterfacePtr = this->_cells[HALO].getRaw();
548 } else {
549 // don't jump to the halo tree -> set invalid parameters and return
550 currentCellIndex.clear();
551 return {nullptr, std::numeric_limits<decltype(particleIndex)>::max()};
552 }
553 } else {
554 currentCellInterfacePtr = currentCellInterfacePtr->getParent()->getChild(currentCellIndex.back());
555 }
556 // check that the inner cell is actually interesting, otherwise skip it.
557 if (not cellIsRelevant(currentCellInterfacePtr)) {
558 forceJumpToNextCell = true;
559 continue;
560 }
561 // The inner cell is relevant so descend to its first relevant leaf
562 forceJumpToNextCell = false;
563 while (currentCellInterfacePtr->hasChildren() and not forceJumpToNextCell) {
564 // find the first child in the relevant region
565 size_t firstRelevantChild = 0;
566 // if the child is irrelevant (empty or outside the region) skip it
567 const auto *childToCheck = currentCellInterfacePtr->getChild(firstRelevantChild);
568 while (not cellIsRelevant(childToCheck)) {
569 ++firstRelevantChild;
570 childToCheck = currentCellInterfacePtr->getChild(firstRelevantChild);
571 if (firstRelevantChild > 7) {
572 // weird corner case: we descended into this branch because it overlaps with the region and has particles
573 // BUT the particles are not inside the children which are in the region,
574 // hence no child fulfills both requirements and all are irrelevant.
575 forceJumpToNextCell = true;
576 break;
577 }
578 }
579 currentCellIndex.push_back(firstRelevantChild);
580 currentCellInterfacePtr = currentCellInterfacePtr->getChild(firstRelevantChild);
581 }
582 particleIndex = 0;
583 }
584
585 // at this point we should point to a leaf. All other cases should have hit a return earlier.
586 currentLeafCellPtr = dynamic_cast<OctreeLeafNode<Particle_T> *>(currentCellInterfacePtr);
587 // sanity check
588 if (currentLeafCellPtr == nullptr) {
589 utils::ExceptionHandler::exception("Expected a leaf node but didn't get one!");
590 }
591
592 } while (not containerIteratorUtils::particleFulfillsIteratorRequirements<regionIter>(
593 (*currentLeafCellPtr)[particleIndex], iteratorBehavior, boxMin, boxMax));
594 return {currentLeafCellPtr, particleIndex};
595 }
596
601};
602
603} // namespace autopas
The CellBasedParticleContainer class stores particles in some object and provides methods to iterate ...
Definition: CellBasedParticleContainer.h:25
const std::array< double, 3 > & getBoxMax() const final
Get the upper corner of the container without halo.
Definition: CellBasedParticleContainer.h:71
double getVerletSkin() const final
Returns the verlet Skin length.
Definition: CellBasedParticleContainer.h:96
void deleteAllParticles() override
Deletes all particles from the container.
Definition: CellBasedParticleContainer.h:101
const std::array< double, 3 > & getBoxMin() const final
Get the lower corner of the container without halo.
Definition: CellBasedParticleContainer.h:76
double getInteractionLength() const final
Return the interaction length (cutoff+skin) of the container.
Definition: CellBasedParticleContainer.h:91
std::vector< ParticleCellType > _cells
Vector of particle cells.
Definition: CellBasedParticleContainer.h:159
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 interface exists to provide a row interface for octree to add its cells.
Definition: OTTraversalInterface.h:22
An octree leaf node.
Definition: OctreeLeafNode.h:27
size_t size() const override
Get the total number of particles saved in the container (owned + halo + dummy).
Definition: OctreeLeafNode.h:147
Log an octree to a .vtk file.
Definition: OctreeLogger.h:25
The base class that provides the necessary function definitions that can be applied to an octree.
Definition: OctreeNodeInterface.h:32
virtual OctreeNodeInterface< Particle_T > * getChild(int index)=0
Get a child by its index from the node.
OctreeNodeInterface< Particle_T > * getParent() const
Get the parent node of this node.
Definition: OctreeNodeInterface.h:376
virtual size_t size() const =0
Get the total number of particles saved in the container (owned + halo + dummy).
virtual bool hasChildren()=0
Check if the node is a leaf or an inner node.
This class wraps the functionality provided by the octree leaves and inner nodes in a structure that ...
Definition: OctreeNodeWrapper.h:37
typename ParticleCell::ParticleType ParticleType
The contained particle type.
Definition: OctreeNodeWrapper.h:46
The octree is a CellBasedParticleContainer that consists internally of two octrees.
Definition: Octree.h:41
static constexpr size_t invalidCellIndex
A cell index that is definitely always invalid.
Definition: Octree.h:63
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: Octree.h:450
std::tuple< std::vector< size_t >, OctreeLeafNode< Particle_T > * > getLeafCellByIndex(size_t cellIndex) const
Helper function to retrieve the pointer to a leaf cell as well as properly parse the cell index.
Definition: Octree.h:292
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: Octree.h:365
bool cellCanContainOwnedParticles(std::size_t i) const override
Checks if the cell with the one-dimensional index index1d can contain owned particles.
Definition: Octree.h:409
ContainerIterator< Particle_T, false, false > begin(IteratorBehavior behavior, 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: Octree.h:345
void reserve(size_t numParticles, size_t numParticlesHaloEstimate) override
Reserve memory for a given number of particles in the container and logic layers.
Definition: Octree.h:157
void rebuildNeighborLists(TraversalInterface *traversal) override
Rebuilds the neighbor lists for the next traversals.
Definition: Octree.h:181
bool cellCanContainHaloParticles(std::size_t i) const override
Checks if the cell with the one-dimensional index index1d can contain halo particles.
Definition: Octree.h:402
void reduce(Lambda reduceLambda, A &result, IteratorBehavior behavior=IteratorBehavior::ownedOrHalo)
Reduce properties of particles as defined by a lambda function.
Definition: Octree.h:439
CellTypes
This particle container contains two cells.
Definition: Octree.h:58
void computeInteractions(TraversalInterface *traversal) override
Iterates over all particle multiples (e.g.
Definition: Octree.h:142
void addHaloParticleImpl(const ParticleType &haloParticle) override
Adds a particle to the container that lies in the halo region of the container.
Definition: Octree.h:169
size_t getNumberOfParticles(IteratorBehavior behavior) const override
Get the number of particles with respect to the specified IteratorBehavior.
Definition: Octree.h:395
bool updateHaloParticle(const ParticleType &haloParticle) override
Update a halo particle of the container with the given haloParticle.
Definition: Octree.h:176
typename ParticleCellType::ParticleType ParticleType
The particle type used in this container.
Definition: Octree.h:51
void forEach(Lambda forEachLambda, IteratorBehavior behavior=IteratorBehavior::ownedOrHalo)
Execute code on all particles in this container as defined by a lambda function.
Definition: Octree.h:423
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: Octree.h:183
size_t size() const override
Get the total number of particles saved in the container (owned + halo + dummy).
Definition: Octree.h:388
void deleteHaloParticles() override
Deletes all halo particles.
Definition: Octree.h:400
void addParticleImpl(const ParticleType &p) override
Adds a particle to the container.
Definition: Octree.h:164
std::vector< ParticleType > updateContainer(bool keepNeighborListValid) override
Updates the container.
Definition: Octree.h:100
TraversalSelectorInfo getTraversalSelectorInfo() const override
Generates a traversal selector info for this container.
Definition: Octree.h:375
std::tuple< const ParticleType *, 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: Octree.h:218
Octree(const std::array< double, 3 > &boxMin, const std::array< double, 3 > &boxMax, const double cutoff, const double skin, const double cellSizeFactor, const size_t sortingThreshold)
Construct a new octree with two sub-octrees: One for the owned particles and one for the halo particl...
Definition: Octree.h:74
ContainerIterator< Particle_T, true, false > begin(IteratorBehavior behavior, utils::optRef< typename ContainerIterator< Particle_T, true, false >::ParticleVecType > additionalVectors) override
Iterate over all particles using for(auto iter = container.begin(); iter.isValid(); ++iter) .
Definition: Octree.h:336
bool deleteParticle(Particle_T &particle) override
Deletes the given particle as long as this does not compromise the validity of the container.
Definition: Octree.h:312
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: Octree.h:355
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: Octree.h:189
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: Octree.h:463
ContainerOption getContainerType() const override
Get the ContainerType.
Definition: Octree.h:155
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: Octree.h:323
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
Interface class to handle cell borders and cell types of cells.
Definition: CellBorderAndFlagManager.h:17
static void exception(const Exception e)
Handle an exception derived by std::exception.
Definition: ExceptionHandler.h:63
std::vector< typename ContainerType::ParticleType > collectParticlesAndMarkNonOwnedAsDummy(ContainerType &container)
Collects leaving particles and marks halo particles as dummy.
Definition: LeavingParticleCollector.h:85
static bool checkParticleInCellAndUpdateByIDAndPosition(CellType &cell, const typename CellType::ParticleType &particle, double absError)
Same as checkParticleInCellAndUpdateByID(CellType, ParticleType), but additionally checks whether the...
Definition: ParticleCellHelpers.h:39
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 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:32
@ halo
Halo state, a particle with this state is an actual particle, but not owned by the current AutoPas ob...
@ owned
Owned state, a particle with this state is an actual particle and owned by the current AutoPas object...
int autopas_get_thread_num()
Dummy for omp_set_lock() when no OpenMP is available.
Definition: WrapOpenMP.h:132