AutoPas  3.0.0
Loading...
Searching...
No Matches
OctreeLeafNode.h
Go to the documentation of this file.
1
8#pragma once
9
10#include <optional>
11
16
17namespace autopas {
18template <typename Particle_T>
19class OctreeInnerNode;
20
26template <typename Particle_T>
27class OctreeLeafNode : public OctreeNodeInterface<Particle_T>, public FullParticleCell<Particle_T> {
28 public:
38 OctreeLeafNode(const std::array<double, 3> &boxMin, const std::array<double, 3> &boxMax,
39 OctreeNodeInterface<Particle_T> *parent, const int unsigned treeSplitThreshold,
40 const double interactionLength, const double cellSizeFactor)
41 : OctreeNodeInterface<Particle_T>(boxMin, boxMax, parent, treeSplitThreshold, interactionLength, cellSizeFactor),
42 FullParticleCell<Particle_T>(utils::ArrayMath::sub(boxMax, boxMin)) {}
43
49 : OctreeNodeInterface<Particle_T>(other._boxMin, other._boxMax, other._parent, other._treeSplitThreshold,
50 other._interactionLength),
51 FullParticleCell<Particle_T>(utils::ArrayMath::sub(other._boxMax, other._boxMin)),
52 _id(other.getID()) {
53 this->_particles.reserve(other._particles.size());
54 for (auto &p : other._particles) {
55 this->_particles.push_back(p);
56 }
57 }
58
62 std::unique_ptr<OctreeNodeInterface<Particle_T>> insert(const Particle_T &p) override {
63 using namespace autopas::utils::ArrayMath::literals;
64
65 // Check if the size of the new leaves would become smaller than cellSizeFactor*interactionLength
66 std::array<double, 3> splitLeafDimensions = this->getBoxMax() - this->getBoxMin();
67 splitLeafDimensions *= 0.5;
68 bool anyNewDimSmallerThanMinSize = false;
69 for (auto d = 0; d < 3; ++d) {
70 // auto cellSizeFactor = 1.0;
71 // @todo The condition below should actually be
72 // splitLeafDimensions[d] < (this->_cellSizeFactor * this->_interactionLength)
73 // But with this condition, the TraversalComparison test fails for cell size factor 0.5. Find out why the octree
74 // cannot handle this value. This problem is addressed in https://github.com/AutoPas/AutoPas/issues/658.
75 if (splitLeafDimensions[d] < this->_interactionLength) {
76 anyNewDimSmallerThanMinSize = true;
77 break;
78 }
79 }
80
81 if ((this->_particles.size() < this->_treeSplitThreshold) or anyNewDimSmallerThanMinSize) {
82 // sanity check that ensures that only particles of the cells OwnershipState can be added. Note: if a cell is a
83 // dummy-cell, only dummies can be added, otherwise dummies can always be added
84 if ((not toInt64(p.getOwnershipState() & this->_ownershipState)) and
85 p.getOwnershipState() != OwnershipState::dummy) {
87 "OctreeLeafNode::insert() can not add a particle with OwnershipState {} to a cell with "
88 "OwnershipState {}",
89 p.getOwnershipState(), this->_ownershipState);
90 }
91
92 this->_particles.push_back(p);
93
94 return nullptr;
95 } else {
96 std::unique_ptr<OctreeNodeInterface<Particle_T>> newInner = std::make_unique<OctreeInnerNode<Particle_T>>(
97 this->getBoxMin(), this->getBoxMax(), this->_parent, this->_treeSplitThreshold, this->_interactionLength,
98 this->_cellSizeFactor);
99 auto ret = newInner->insert(p);
100 if (ret) newInner = std::move(ret);
101 for (auto cachedParticle : this->_particles) {
102 ret = newInner->insert(cachedParticle);
103 if (ret) newInner = std::move(ret);
104 }
105
106 return newInner;
107 }
108 }
109
110 bool deleteParticle(Particle_T &particle) override {
111 const bool isRearParticle = &particle == &this->_particles.back();
112 // WARNING no runtime check that this particle is actually within the node!
113 particle = this->_particles.back();
114
115 this->_particles.pop_back();
116 return not isRearParticle;
117 }
118
122 void collectAllParticles(std::vector<Particle_T *> &ps) const override {
123 ps.reserve(ps.size() + this->_particles.size());
124 for (auto &particle : this->_particles) {
125 // The cast here is required to remove the `const` modifier from the `Particle_T const &`. The particle should be
126 // modifiable outside the octree and should therefore not be marked `const`, which requires the cast.
127 ps.push_back((Particle_T *)&particle);
128 }
129 }
130
134 void appendAllLeafBoxes(std::vector<std::pair<std::array<double, 3>, std::array<double, 3>>> &boxes) const override {
135 auto minMax = std::make_pair(this->getBoxMin(), this->getBoxMax());
136 boxes.push_back(minMax);
137 }
138
142 void clearChildren(std::unique_ptr<OctreeNodeInterface<Particle_T>> &ref) override { this->_particles.clear(); }
143
147 size_t size() const override { return this->_particles.size(); }
148
152 [[nodiscard]] size_t getNumberOfParticles(IteratorBehavior behavior) const override {
153 return std::count_if(this->_particles.begin(), this->_particles.end(),
154 [&behavior](auto p) { return behavior.contains(p); });
155 }
156
160 bool hasChildren() override { return false; }
161
166 throw std::runtime_error("[OctreeLeafNode::getChild()] Unable to return child by index in leaf");
167 }
168
169 std::vector<OctreeLeafNode<Particle_T> *> getLeavesFromDirections(
170 const std::vector<octree::Vertex> &directions) override {
171 return {this};
172 }
173
175 throw std::runtime_error("Unable to get SON of leaf node");
176 }
177
178 void appendAllLeaves(std::vector<OctreeLeafNode<Particle_T> *> &leaves) const override {
179 leaves.push_back((OctreeLeafNode<Particle_T> *)this);
180 }
181
182 std::set<OctreeLeafNode<Particle_T> *> getLeavesInRange(const std::array<double, 3> &min,
183 const std::array<double, 3> &max) override {
184 if (this->getEnclosedVolumeWith(min, max) > 0.0) {
185 return {this};
186 } else {
187 return {};
188 }
189 }
190
195 int getID() { return _id; }
196
201 void setID(int id) { this->_id = id; }
202
203 private:
207 int _id{-1};
208};
209} // namespace autopas
This class handles the storage of particles in their full form.
Definition: FullParticleCell.h:26
StorageType _particles
Storage of the molecules of the cell.
Definition: FullParticleCell.h:274
An octree leaf node.
Definition: OctreeLeafNode.h:27
OctreeLeafNode(OctreeLeafNode< Particle_T > const &other)
Copy a leaf by copying all particles from the other leaf to this leaf.
Definition: OctreeLeafNode.h:48
void setID(int id)
Set the ID of this node.
Definition: OctreeLeafNode.h:201
size_t getNumberOfParticles(IteratorBehavior behavior) const override
Get the number of particles with respect to the specified IteratorBehavior.
Definition: OctreeLeafNode.h:152
void collectAllParticles(std::vector< Particle_T * > &ps) const override
Put all particles that are below this node into the vector.
Definition: OctreeLeafNode.h:122
bool deleteParticle(Particle_T &particle) override
Delete the given particle from the data structure.
Definition: OctreeLeafNode.h:110
int getID()
Get the assigned id of this leaf node.
Definition: OctreeLeafNode.h:195
void appendAllLeafBoxes(std::vector< std::pair< std::array< double, 3 >, std::array< double, 3 > > > &boxes) const override
Put the min/max corner coordinates of every leaf into the vector.
Definition: OctreeLeafNode.h:134
void appendAllLeaves(std::vector< OctreeLeafNode< Particle_T > * > &leaves) const override
Put all leaves below this subtree into a given list.
Definition: OctreeLeafNode.h:178
OctreeNodeInterface< Particle_T > * SON(octree::Octant O) override
Get a child node of this node (if there are children) given a specific octant using the spacial struc...
Definition: OctreeLeafNode.h:174
std::unique_ptr< OctreeNodeInterface< Particle_T > > insert(const Particle_T &p) override
Insert a particle into the octree.
Definition: OctreeLeafNode.h:62
std::set< OctreeLeafNode< Particle_T > * > getLeavesInRange(const std::array< double, 3 > &min, const std::array< double, 3 > &max) override
Find all leaves below this subtree that are in the given range.
Definition: OctreeLeafNode.h:182
std::vector< OctreeLeafNode< Particle_T > * > getLeavesFromDirections(const std::vector< octree::Vertex > &directions) override
Find all leaf nodes along a list of given directions.
Definition: OctreeLeafNode.h:169
void clearChildren(std::unique_ptr< OctreeNodeInterface< Particle_T > > &ref) override
Delete the entire tree below this node.
Definition: OctreeLeafNode.h:142
size_t size() const override
Get the total number of particles saved in the container (owned + halo + dummy).
Definition: OctreeLeafNode.h:147
OctreeLeafNode(const std::array< double, 3 > &boxMin, const std::array< double, 3 > &boxMax, OctreeNodeInterface< Particle_T > *parent, const int unsigned treeSplitThreshold, const double interactionLength, const double cellSizeFactor)
Create an empty octree leaf node.
Definition: OctreeLeafNode.h:38
bool hasChildren() override
Check if the node is a leaf or an inner node.
Definition: OctreeLeafNode.h:160
OctreeNodeInterface< Particle_T > * getChild(int index) override
Get a child by its index from the node.
Definition: OctreeLeafNode.h:165
The base class that provides the necessary function definitions that can be applied to an octree.
Definition: OctreeNodeInterface.h:32
static double getEnclosedVolumeWith(const std::array< double, 3 > &aMin, const std::array< double, 3 > &aMax, const std::array< double, 3 > &bMin, const std::array< double, 3 > &bMax)
Get the enclosed volume between two boxes a and b.
Definition: OctreeNodeInterface.h:196
std::array< double, 3 > _boxMin
The min coordinate of the enclosed volume.
Definition: OctreeNodeInterface.h:393
const std::array< double, 3 > & getBoxMax() const
Get the maximum coordinate of the enclosing box.
Definition: OctreeNodeInterface.h:370
std::array< double, 3 > _boxMax
The max coordinate of the enclosed volume.
Definition: OctreeNodeInterface.h:398
const std::array< double, 3 > & getBoxMin() const
Get the minimum coordinate of the enclosing box.
Definition: OctreeNodeInterface.h:364
double _interactionLength
The minimum distance at which a force is considered nonzero, cutoff+skin.
Definition: OctreeNodeInterface.h:408
int unsigned _treeSplitThreshold
Maximum number of particles inside a leaf node before the leaf tries to split itself.
Definition: OctreeNodeInterface.h:403
OctreeNodeInterface< Particle_T > * _parent
A pointer to the parent node.
Definition: OctreeNodeInterface.h:388
double _cellSizeFactor
The cell size factor for this node.
Definition: OctreeNodeInterface.h:413
static void exception(const Exception e)
Handle an exception derived by std::exception.
Definition: ExceptionHandler.h:63
Vertex
This enum can be used to index all vertices of a cube including an "invalid" vertex.
Definition: OctreeDirection.h:79
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:32
constexpr int64_t toInt64(const OwnershipState a)
Returns the int64_t value of a given OwnershipState.
Definition: OwnershipState.h:56
@ dummy
Dummy or deleted state, a particle with this state is not an actual particle!