Newer
Older
#include <cmath>
#include <iostream>
#include "Node.hpp"
namespace nbody {
Node::Node(Tree* _tree):tree(_tree) {}
void Node::setBB(const Box& bb_) {
bb = bb_;
//check if node needs to be splitted during tree build
if (bodies.size() <= tree->maxLeafBodies) {
//this is to prevent errors with collocated particles
if (bb.volume() <= std::numeric_limits<float>::epsilon()) {
result = false;
}
return result;
}
void Node::extendBBforBodies() {
bb.extendForBodies(bodies);
}
void Node::extendBBtoCube() {
bb.extendToCube();
std::vector<Body> Node::getBodies() const {
}
void Node::insertBefore(Node* node) {
node->next = this;
node->prev = this->prev;
this->prev->next = node;
this->prev = node;
}
void Node::insertAfter(Node* node) {
this->next->insertBefore(node);
}
void Node::unlink() {
this->next->prev = this->prev;
this->prev->next = this->next;
this->next = this;
this->prev = this;
}
if (afterSubtree == nullptr) {
if (!bb.isCorrectBox()) {
for (std::size_t i = 0; i < 3; i++) {
if (bb.min[i] > bb.max[i]) {
std::cerr << "bb " << i << " min " << bb.min[i] << " max " << bb.max[i] << '\n';
if (std::any_of(std::begin(bodies), std::end(bodies), [&](const Body& b) {return !isContained(b, bb); })) {
std::cerr << "bb out of bounds\n";
return false;
if (!leaf) {
Node* current = next;
std::size_t children = 0;
while (current != nullptr && current != afterSubtree) {
current = current->afterSubtree;
children++;
}
if (children != tree->numberOfChildren()) {
std::cerr << "wrong number of children " << children << '\n';
current = next;
for (std::size_t i = 0; i < tree->numberOfChildren(); i++) {
current = current->afterSubtree;
}
if (current != afterSubtree) {
std::cerr << "last sibling afterSubtree inconsistent\n";
return false;
}
}
if (!leaf && !bodies.empty()) {
if (leaf && nextSibling != nullptr && next != nextSibling) {
return false;
}
return true;
}
void Node::update() {
double position[3] = {0.0, 0.0, 0.0};
double mass = 0.0;
for (const auto& body : bodies) {
for (std::size_t i = 0; i < 3; i++) {
position[i] += body.position[i] * body.mass;
for (Node* node = next; node != nullptr; node = node->nextSibling) {
mass += node->representative.mass;
}
}
for (std::size_t i = 0; i < 3; i++) {
representative.position[i] = position[i] / mass;
representative.mass = mass;
//get criterion to check if node is sufficient for force evaluation
return bb.maxSidelength();
void Node::print(std::size_t parallelId) const {
bb.printBB(parallelId);
for (const auto& body : bodies) {
//check if node is sufficient for force evaluation
bool Node::sufficientForBody(const Body& body) const {
double distance = 0.0;
for (std::size_t i = 0; i < 3; i++) {
distance += (representative.position[i] - body.position[i]) * (representative.position[i] - body.position[i]);
//check if node is sufficient for force evaluation for all bodies in box
bool Node::sufficientForBox(const Box& box) const {
return bb.distanceToBox(box) > getL();
void Node::setBodies(const std::vector<Body>& bodies_) {
bodies = bodies_;
void Node::setBodies(std::vector<Body>&& bodies_) {
bodies = std::move(bodies_);
void Node::extractLocalBodiesTo(std::vector<Body>& result) {
std::copy_if(std::begin(bodies), std::end(bodies), std::back_inserter(result), [](const Body& b) {return !b.refinement; });
bodies.clear();