22template <
class Particle_T>
34 OctreeInnerNode(
const std::array<double, 3> &boxMin,
const std::array<double, 3> &boxMax,
36 double cellSizeFactor)
37 :
OctreeNodeInterface<Particle_T>(boxMin, boxMax, parent, treeSplitThreshold, interactionLength, cellSizeFactor) {
39 using namespace autopas::utils::ArrayMath::literals;
42 const auto center = (boxMin + boxMax) * 0.5;
43 for (
auto i = 0; i < _children.size(); ++i) {
45 std::array<double, 3> newBoxMin = {};
46 std::array<double, 3> newBoxMax = {};
47 for (
auto d = 0; d < 3; ++d) {
66 const auto mask = 4 >> d;
67 newBoxMin[d] = (not(i & mask)) ? boxMin[d] : center[d];
68 newBoxMax[d] = (not(i & mask)) ? center[d] : boxMax[d];
72 _children[i] = std::make_unique<OctreeLeafNode<Particle_T>>(newBoxMin, newBoxMax,
this, treeSplitThreshold,
73 interactionLength, cellSizeFactor);
84 for (
auto i = 0; i < other._children.size(); ++i) {
85 auto *otherChild = other._children[i].get();
86 if (otherChild->hasChildren()) {
98 std::unique_ptr<OctreeNodeInterface<Particle_T>>
insert(
const Particle_T &p)
override {
100 for (
auto &child : _children) {
101 if (child->isInside(p.getR())) {
102 auto ret = child->insert(p);
103 if (ret) child = std::move(ret);
112 for (
auto &child : _children) {
113 if (child->isInside(particle.getR())) {
114 return child->deleteParticle(particle);
119 "Particle not found in this node!"
122 "\n" + particle.toString());
132 for (
auto &child : _children) {
133 child->collectAllParticles(ps);
140 void appendAllLeafBoxes(std::vector<std::pair<std::array<double, 3>, std::array<double, 3>>> &boxes)
const override {
141 for (
auto &child : _children) {
142 child->appendAllLeafBoxes(boxes);
150 for (
auto &child : _children) {
151 child->clearChildren(child);
154 std::unique_ptr<OctreeLeafNode<Particle_T>> newLeaf = std::make_unique<OctreeLeafNode<Particle_T>>(
157 ref = std::move(newLeaf);
164 unsigned int result = 0;
165 for (
const auto &child : _children) {
166 result += child->size();
175 unsigned int result = 0;
176 for (
const auto &child : _children) {
177 result += child->getNumberOfParticles(behavior);
193 const std::vector<octree::Vertex> &directions)
override {
194 std::vector<OctreeLeafNode<Particle_T> *> result;
196 for (
auto d : directions) {
197 int childIndex = vertexToIndex(d);
198 if (childIndex < 0) {
199 throw std::runtime_error(
"[OctreeInnerNode::getLeavesFromDirections()] Calculated invalid child index");
203 auto childLeaves = child->getLeavesFromDirections(directions);
204 result.insert(result.end(), childLeaves.begin(), childLeaves.end());
211 auto flat = vertexToIndex(octant);
212 return _children[flat].get();
216 for (
auto &child : _children) {
217 child->appendAllLeaves(leaves);
222 const std::array<double, 3> &max)
override {
223 std::set<OctreeLeafNode<Particle_T> *> result;
224 for (
auto &child : _children) {
225 double vol = child->getEnclosedVolumeWith(min, max);
228 auto leaves = child->getLeavesInRange(min, max);
229 result.insert(leaves.begin(), leaves.end());
238 template <
typename Lambda>
240 for (
auto &child : _children) {
248 template <
typename Lambda,
typename A>
249 void reduce(Lambda reduceLambda, A &result) {
250 for (
auto &child : _children) {
251 withStaticNodeType(child, [&](
auto nodePtr) { nodePtr->reduce(reduceLambda, result); });
265 template <
typename Lambda>
266 void forEach(Lambda forEachLambda,
const std::array<double, 3> &lowerCorner,
267 const std::array<double, 3> &higherCorner, IteratorBehavior behavior) {
268 for (
auto &child : _children) {
269 double vol = child->getEnclosedVolumeWith(lowerCorner, higherCorner);
272 [&](
auto nodePtr) { nodePtr->forEach(forEachLambda, lowerCorner, higherCorner, behavior); });
288 template <
typename Lambda,
typename A>
289 void reduce(Lambda reduceLambda, A &result,
const std::array<double, 3> &lowerCorner,
290 const std::array<double, 3> &higherCorner, IteratorBehavior behavior) {
291 for (
auto &child : _children) {
292 double vol = child->getEnclosedVolumeWith(lowerCorner, higherCorner);
295 child, [&](
auto nodePtr) { nodePtr->reduce(reduceLambda, result, lowerCorner, higherCorner, behavior); });
303 std::array<std::unique_ptr<OctreeNodeInterface<Particle_T>>, 8> _children;
Inner nodes of the octree data structure.
Definition: OctreeInnerNode.h:23
void clearChildren(std::unique_ptr< OctreeNodeInterface< Particle_T > > &ref) override
Delete the entire tree below this node.
Definition: OctreeInnerNode.h:149
size_t getNumberOfParticles(IteratorBehavior behavior) const override
Get the number of particles with respect to the specified IteratorBehavior.
Definition: OctreeInnerNode.h:174
bool deleteParticle(Particle_T &particle) override
Delete the given particle from the data structure.
Definition: OctreeInnerNode.h:111
void forEach(Lambda forEachLambda)
Apply the forEach lambda to each particle.
Definition: OctreeInnerNode.h:239
void appendAllLeaves(std::vector< OctreeLeafNode< Particle_T > * > &leaves) const override
Put all leaves below this subtree into a given list.
Definition: OctreeInnerNode.h:215
OctreeNodeInterface< Particle_T > * SON(octree::Octant octant) override
Get a child node of this node (if there are children) given a specific octant using the spacial struc...
Definition: OctreeInnerNode.h:209
void reduce(Lambda reduceLambda, A &result)
Apply the reduce lambda to each particle.
Definition: OctreeInnerNode.h:249
bool hasChildren() override
Check if the node is a leaf or an inner node.
Definition: OctreeInnerNode.h:185
void reduce(Lambda reduceLambda, A &result, const std::array< double, 3 > &lowerCorner, const std::array< double, 3 > &higherCorner, IteratorBehavior behavior)
Apply the reduce lambda to each particle in the region.
Definition: OctreeInnerNode.h:289
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: OctreeInnerNode.h:221
std::vector< OctreeLeafNode< Particle_T > * > getLeavesFromDirections(const std::vector< octree::Vertex > &directions) override
Find all leaf nodes along a list of given directions.
Definition: OctreeInnerNode.h:192
void collectAllParticles(std::vector< Particle_T * > &ps) const override
Put all particles that are below this node into the vector.
Definition: OctreeInnerNode.h:130
size_t size() const override
Get the total number of particles saved in the container (owned + halo + dummy).
Definition: OctreeInnerNode.h:163
OctreeInnerNode(const std::array< double, 3 > &boxMin, const std::array< double, 3 > &boxMax, OctreeNodeInterface< Particle_T > *parent, int unsigned treeSplitThreshold, double interactionLength, double cellSizeFactor)
Create an octree inner node that points to eight leaves.
Definition: OctreeInnerNode.h:34
void forEach(Lambda forEachLambda, const std::array< double, 3 > &lowerCorner, const std::array< double, 3 > &higherCorner, IteratorBehavior behavior)
Apply the forEach lambda to each particle in the region.
Definition: OctreeInnerNode.h:266
OctreeNodeInterface< Particle_T > * getChild(int index) override
Get a child by its index from the node.
Definition: OctreeInnerNode.h:190
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: OctreeInnerNode.h:140
std::unique_ptr< OctreeNodeInterface< Particle_T > > insert(const Particle_T &p) override
Insert a particle into the octree.
Definition: OctreeInnerNode.h:98
OctreeInnerNode(const OctreeInnerNode< Particle_T > &other)
Copy all children from the other octree into this octree.
Definition: OctreeInnerNode.h:81
An octree leaf node.
Definition: OctreeLeafNode.h:27
The base class that provides the necessary function definitions that can be applied to an octree.
Definition: OctreeNodeInterface.h:32
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
void to_string(std::ostream &os, const Container &container, const std::string &delimiter, const std::array< std::string, 2 > &surround, Fun elemToString)
Generates a string representation of a container which fulfills the Container requirement (provide cb...
Definition: ArrayUtils.h:102
In this namespace some helper classes and functions can be found used inside of AutoPas.
Definition: namespaces.h:44
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:32
decltype(auto) withStaticNodeType(const std::unique_ptr< OctreeNodeInterface< Particle_T > > &root, FunctionType &&function)
Will execute the passed function on the given root node.
Definition: OctreeStaticNodeSelector.h:29