40template <
class Particle_T>
77 Octree(
const std::array<double, 3> &boxMin,
const std::array<double, 3> &boxMax,
const double cutoff,
78 const double skin,
const double cellSizeFactor,
const size_t aosSortingThresholdFallback,
79 const size_t soaSortingThresholdFallback)
81 soaSortingThresholdFallback) {
82 using namespace autopas::utils::ArrayMath::literals;
84 if (cellSizeFactor != 1.0) {
88 "Trying to construct an Octree with CSF != 1.0! This should never occur as the LogicHandler "
89 "should reject this (as Configuration::hasCompatibleValues should return false).");
93 int unsigned treeSplitThreshold = 16;
102 auto haloBoxMin = boxMin - interactionLength;
103 auto haloBoxMax = boxMax + interactionLength;
113 [[nodiscard]] std::vector<ParticleType>
updateContainer(
bool keepNeighborListValid)
override {
115 std::vector<Particle_T> invalidParticles{};
117 if (keepNeighborListValid) {
127 std::vector<Particle_T *> particleRefs;
128 this->
_cells[CellTypes::OWNED].collectAllParticles(particleRefs);
129 std::vector<Particle_T> particles{};
130 particles.reserve(particleRefs.size());
132 for (
auto *p : particleRefs) {
136 }
else if (
utils::inBox(p->getR(), this->getBoxMin(), this->getBoxMax())) {
137 particles.push_back(*p);
139 invalidParticles.push_back(*p);
147 for (
auto &particle : particles) {
152 return invalidParticles;
157 traversalInterface->setCells(&this->
_cells);
172 [[nodiscard]] ContainerOption
getContainerType()
const override {
return ContainerOption::octree; }
174 void reserve(
size_t numParticles,
size_t numParticlesHaloEstimate)
override {
187 this->
_cells[CellTypes::HALO].addParticle(haloParticle);
200 std::tuple<const Particle_T *, size_t, size_t>
getParticle(
size_t cellIndex,
size_t particleIndex,
201 IteratorBehavior iteratorBehavior,
202 const std::array<double, 3> &boxMin,
203 const std::array<double, 3> &boxMax)
const override {
204 return getParticleImpl<true>(cellIndex, particleIndex, iteratorBehavior, boxMin, boxMax);
206 std::tuple<const Particle_T *, size_t, size_t>
getParticle(
size_t cellIndex,
size_t particleIndex,
207 IteratorBehavior iteratorBehavior)
const override {
209 constexpr std::array<double, 3> boxMin{std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(),
210 std::numeric_limits<double>::lowest()};
212 constexpr std::array<double, 3> boxMax{std::numeric_limits<double>::max(), std::numeric_limits<double>::max(),
213 std::numeric_limits<double>::max()};
214 return getParticleImpl<false>(cellIndex, particleIndex, iteratorBehavior, boxMin, boxMax);
234 template <
bool regionIter>
235 std::tuple<const ParticleType *, size_t, size_t>
getParticleImpl(
size_t cellIndex,
size_t particleIndex,
236 IteratorBehavior iteratorBehavior,
237 const std::array<double, 3> &boxMin,
238 const std::array<double, 3> &boxMax)
const {
239 using namespace autopas::utils::ArrayMath::literals;
243 return {
nullptr, 0, 0};
247 if (cellIndex == 0 and not(iteratorBehavior & IteratorBehavior::owned)) {
252 if (cellIndex < 10 and cellIndex > HALO) {
253 return {
nullptr, 0, 0};
256 std::array<double, 3> boxMinWithSafetyMargin = boxMin;
257 std::array<double, 3> boxMaxWithSafetyMargin = boxMax;
258 if constexpr (regionIter) {
264 std::vector<size_t> currentCellIndex{};
269 if (particleIndex >= currentCellPtr->
size() or
270 not containerIteratorUtils::particleFulfillsIteratorRequirements<regionIter>(
271 (*currentCellPtr)[particleIndex], iteratorBehavior, boxMin, boxMax)) {
273 std::tie(currentCellPtr, particleIndex) =
274 advanceIteratorIndices<regionIter>(currentCellIndex, currentCellPtr, particleIndex, iteratorBehavior, boxMin,
275 boxMax, boxMinWithSafetyMargin, boxMaxWithSafetyMargin);
279 if (currentCellPtr ==
nullptr) {
280 return {
nullptr, 0, 0};
283 const Particle_T *retPtr = &((*currentCellPtr)[particleIndex]);
286 if (currentCellIndex.empty()) {
291 for (
int i =
static_cast<int>(currentCellIndex.size()) - 1; i >= 0; --i) {
293 cellIndex += currentCellIndex[i];
297 return {retPtr, cellIndex, particleIndex};
311 std::vector<size_t> currentCellIndex;
313 currentCellIndex.reserve(10);
314 currentCellIndex.push_back(cellIndex % 10);
319 currentCellIndex.push_back(cellIndex % 10);
321 currentCell = currentCell->
getChild(currentCellIndex.back());
330 if (particle.isOwned()) {
331 return this->
_cells[CellTypes::OWNED].deleteParticle(particle);
332 }
else if (particle.isHalo()) {
333 return this->
_cells[CellTypes::HALO].deleteParticle(particle);
342 auto &particleVec = cell->_particles;
343 auto &particle = particleVec[particleIndex];
345 particle = particleVec.back();
346 particleVec.pop_back();
347 return particleIndex < particleVec.size();
354 IteratorBehavior behavior,
363 IteratorBehavior behavior,
365 std::nullopt)
const override {
373 const std::array<double, 3> &lowerCorner,
const std::array<double, 3> &higherCorner, IteratorBehavior behavior,
375 std::nullopt)
override {
383 const std::array<double, 3> &lowerCorner,
const std::array<double, 3> &higherCorner, IteratorBehavior behavior,
385 std::nullopt)
const override {
393 using namespace autopas::utils::ArrayMath::literals;
396 const std::array<unsigned long, 3> dims = {1, 1, 1};
405 [[nodiscard]]
size_t size()
const override {
406 return this->
_cells[CellTypes::OWNED].size() + this->
_cells[CellTypes::HALO].size();
413 return this->
_cells[CellTypes::OWNED].getNumberOfParticles(behavior) +
414 this->
_cells[CellTypes::HALO].getNumberOfParticles(behavior);
421 throw std::runtime_error(
"[Octree.h]: This cell container (octree) contains only two cells");
423 return i == CellTypes::HALO;
428 throw std::runtime_error(
"[Octree.h]: This cell container (octree) contains only two cells");
430 return i == CellTypes::OWNED;
439 template <
typename Lambda>
440 void forEach(Lambda forEachLambda, IteratorBehavior behavior = IteratorBehavior::ownedOrHalo) {
441 if (behavior & IteratorBehavior::owned) this->
_cells[OWNED].forEach(forEachLambda);
442 if (behavior & IteratorBehavior::halo) this->
_cells[HALO].forEach(forEachLambda);
443 if (not(behavior & IteratorBehavior::ownedOrHalo))
455 template <
typename Lambda,
typename A>
456 void reduce(Lambda reduceLambda, A &result, IteratorBehavior behavior = IteratorBehavior::ownedOrHalo) {
457 if (behavior & IteratorBehavior::owned) this->
_cells[OWNED].reduce(reduceLambda, result);
458 if (behavior & IteratorBehavior::halo) this->
_cells[HALO].reduce(reduceLambda, result);
459 if (not(behavior & IteratorBehavior::ownedOrHalo))
466 template <
typename Lambda>
468 const std::array<double, 3> &higherCorner, IteratorBehavior behavior) {
469 if (behavior & IteratorBehavior::owned)
470 this->
_cells[OWNED].forEachInRegion(forEachLambda, lowerCorner, higherCorner);
471 if (behavior & IteratorBehavior::halo) this->
_cells[HALO].forEachInRegion(forEachLambda, lowerCorner, higherCorner);
472 if (not(behavior & IteratorBehavior::ownedOrHalo))
479 template <
typename Lambda,
typename A>
480 void reduceInRegion(Lambda reduceLambda, A &result,
const std::array<double, 3> &lowerCorner,
481 const std::array<double, 3> &higherCorner, IteratorBehavior behavior) {
482 if (behavior & IteratorBehavior::owned)
483 this->
_cells[OWNED].reduceInRegion(reduceLambda, result, lowerCorner, higherCorner);
484 if (behavior & IteratorBehavior::halo)
485 this->
_cells[HALO].reduceInRegion(reduceLambda, result, lowerCorner, higherCorner);
486 if (not(behavior & IteratorBehavior::ownedOrHalo))
506 template <
bool regionIter>
507 std::tuple<OctreeLeafNode<Particle_T> *,
size_t> advanceIteratorIndices(
509 size_t particleIndex, IteratorBehavior iteratorBehavior,
const std::array<double, 3> &boxMin,
510 const std::array<double, 3> &boxMax,
const std::array<double, 3> &boxMinWithSafetyMargin,
511 const std::array<double, 3> &boxMaxWithSafetyMargin)
const {
513 const size_t minLevel = 0;
523 bool isRelevant = cellPtr->
size() > 0;
524 if constexpr (regionIter) {
525 isRelevant =
utils::boxesOverlap(cellPtr->getBoxMin(), cellPtr->getBoxMax(), boxMinWithSafetyMargin,
526 boxMaxWithSafetyMargin);
538 bool forceJumpToNextCell =
false;
540 while (particleIndex >= currentCellInterfacePtr->
size() or forceJumpToNextCell) {
543 while (currentCellIndex.back() == 7) {
544 currentCellInterfacePtr = currentCellInterfacePtr->
getParent();
545 currentCellIndex.pop_back();
547 if (currentCellIndex.size() < minLevel or currentCellIndex.empty()) {
548 currentCellIndex.clear();
549 return {
nullptr, std::numeric_limits<
decltype(particleIndex)>::max()};
554 ++currentCellIndex.back();
556 if (currentCellIndex.size() == 1) {
558 if (currentCellIndex.back() > HALO) {
559 return {
nullptr, std::numeric_limits<
decltype(particleIndex)>::max()};
562 if ((iteratorBehavior & IteratorBehavior::halo)
564 currentCellInterfacePtr = this->
_cells[HALO].getRaw();
567 currentCellIndex.clear();
568 return {
nullptr, std::numeric_limits<
decltype(particleIndex)>::max()};
571 currentCellInterfacePtr = currentCellInterfacePtr->
getParent()->getChild(currentCellIndex.back());
574 if (not cellIsRelevant(currentCellInterfacePtr)) {
575 forceJumpToNextCell =
true;
579 forceJumpToNextCell =
false;
580 while (currentCellInterfacePtr->
hasChildren() and not forceJumpToNextCell) {
582 size_t firstRelevantChild = 0;
584 const auto *childToCheck = currentCellInterfacePtr->
getChild(firstRelevantChild);
585 while (not cellIsRelevant(childToCheck)) {
586 ++firstRelevantChild;
587 childToCheck = currentCellInterfacePtr->
getChild(firstRelevantChild);
588 if (firstRelevantChild > 7) {
592 forceJumpToNextCell =
true;
596 currentCellIndex.push_back(firstRelevantChild);
597 currentCellInterfacePtr = currentCellInterfacePtr->
getChild(firstRelevantChild);
605 if (currentLeafCellPtr ==
nullptr) {
609 }
while (not containerIteratorUtils::particleFulfillsIteratorRequirements<regionIter>(
610 (*currentLeafCellPtr)[particleIndex], iteratorBehavior, boxMin, boxMax));
611 return {currentLeafCellPtr, particleIndex};
The CellBasedParticleContainer class stores particles in some object and provides methods to iterate ...
Definition: CellBasedParticleContainer.h:28
const std::array< double, 3 > & getBoxMax() const final
Get the upper corner of the container without halo.
Definition: CellBasedParticleContainer.h:79
double getVerletSkin() const final
Returns the verlet Skin length.
Definition: CellBasedParticleContainer.h:104
std::shared_ptr< const SortingThresholdInfoInterface > _soaSortingThresholds
Current AoS pair-sorting threshold, forwarded to freshly generated traversals in prepareTraversal().
Definition: CellBasedParticleContainer.h:192
void deleteAllParticles() override
Deletes all particles from the container.
Definition: CellBasedParticleContainer.h:109
std::shared_ptr< const SortingThresholdInfoInterface > _aosSortingThresholds
Current AoS pair-sorting threshold, forwarded to freshly generated traversals in prepareTraversal().
Definition: CellBasedParticleContainer.h:188
const std::array< double, 3 > & getBoxMin() const final
Get the lower corner of the container without halo.
Definition: CellBasedParticleContainer.h:84
double getInteractionLength() const final
Return the interaction length (cutoff+skin) of the container.
Definition: CellBasedParticleContainer.h:99
std::vector< ParticleCellType > _cells
Vector of particle cells.
Definition: CellBasedParticleContainer.h:181
A cell pair traversal.
Definition: CellTraversal.h:25
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:42
static constexpr size_t invalidCellIndex
A cell index that is definitely always invalid.
Definition: Octree.h:64
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:467
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:309
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:382
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:426
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:362
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:174
void rebuildNeighborLists(TraversalInterface *traversal) override
Rebuilds the neighbor lists for the next traversals.
Definition: Octree.h:198
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:419
void reduce(Lambda reduceLambda, A &result, IteratorBehavior behavior=IteratorBehavior::ownedOrHalo)
Reduce properties of particles as defined by a lambda function.
Definition: Octree.h:456
CellTypes
This particle container contains two cells.
Definition: Octree.h:59
void computeInteractions(TraversalInterface *traversal) override
Iterates over all particle multiples (e.g.
Definition: Octree.h:155
void addHaloParticleImpl(const ParticleType &haloParticle) override
Adds a particle to the container that lies in the halo region of the container.
Definition: Octree.h:186
size_t getNumberOfParticles(IteratorBehavior behavior) const override
Get the number of particles with respect to the specified IteratorBehavior.
Definition: Octree.h:412
bool updateHaloParticle(const ParticleType &haloParticle) override
Update a halo particle of the container with the given haloParticle.
Definition: Octree.h:193
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 aosSortingThresholdFallback, const size_t soaSortingThresholdFallback)
Construct a new octree with two sub-octrees: One for the owned particles and one for the halo particl...
Definition: Octree.h:77
typename ParticleCellType::ParticleType ParticleType
The particle type used in this container.
Definition: Octree.h:52
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:440
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:200
size_t size() const override
Get the total number of particles saved in the container (owned + halo + dummy).
Definition: Octree.h:405
void deleteHaloParticles() override
Deletes all halo particles.
Definition: Octree.h:417
void addParticleImpl(const ParticleType &p) override
Adds a particle to the container.
Definition: Octree.h:181
std::vector< ParticleType > updateContainer(bool keepNeighborListValid) override
Updates the container.
Definition: Octree.h:113
TraversalSelectorInfo getTraversalSelectorInfo() const override
Generates a traversal selector info for this container.
Definition: Octree.h:392
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:235
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:353
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:329
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:372
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:206
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:480
ContainerOption getContainerType() const override
Get the ContainerType.
Definition: Octree.h:172
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:340
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:64
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:34
@ 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