From 76bda61d66d8d1e9cdb432d5b8ef3ca01fc39c44 Mon Sep 17 00:00:00 2001 From: "armindamon.riess" <armindamon.riess@uzh.ch> Date: Wed, 7 Dec 2022 11:43:40 +0100 Subject: [PATCH] nodes can access masses, copy constructor done --- lib/nBodySim.cpp | 6 ++++-- lib/node.cpp | 44 +++++++++++++++++++++++++++++++++++++++++++- lib/node.hpp | 12 +++++++++++- lib/tree.cpp | 9 +++++++-- lib/tree.hpp | 5 ++++- 5 files changed, 69 insertions(+), 7 deletions(-) diff --git a/lib/nBodySim.cpp b/lib/nBodySim.cpp index 93d225b..181ca15 100644 --- a/lib/nBodySim.cpp +++ b/lib/nBodySim.cpp @@ -49,7 +49,7 @@ nBodySim::nBodySim(std::string datafile) { file.close(); - tree_ = new Tree(positions_, forces_, nParticles_, 4*maxCoord, new double[3]{0, 0, 0}); + tree_ = new Tree(masses_, positions_, forces_, nParticles_, 4*maxCoord, new double[3]{0, 0, 0}); } nBodySim::~nBodySim() { @@ -112,7 +112,9 @@ void nBodySim::calculateForces() { } void nBodySim::treeCalculateForces() { - // TODO + for (unsigned i=0; i < nParticles_; ++i) { + tree_->calculateForce(i); + } } double nBodySim::calculateMeanInterparticleDistance() { diff --git a/lib/node.cpp b/lib/node.cpp index bada192..6d80492 100644 --- a/lib/node.cpp +++ b/lib/node.cpp @@ -1,5 +1,7 @@ #include "node.hpp" +#include <cmath> + /* Node::Node() { root_ = nullptr; @@ -15,15 +17,24 @@ Node::Node() { } */ -Node::Node(Node* parent, double* particles, unsigned nParticles, unsigned depth, double size, double center[3], unsigned* localParticles, unsigned nLocalParticles) { +Node::Node(Node* parent, double* masses, double* particles, unsigned nParticles, unsigned depth, double size, double center[3], unsigned* localParticles, unsigned nLocalParticles) { parent_ = parent; particles_ = particles; nParticles_ = nParticles; + depth_ = depth; size_ = size; + for (unsigned i=0; i<3; ++i) center_[i] = center[i]; + localParticles_ = localParticles; nLocalParticles_ = nLocalParticles; + + mass_ = 0; + for (unsigned i=0; i<nLocalParticles; ++i) { + mass_ += masses_[localParticles_[i]]; + } + // allocate children // TODO } @@ -33,4 +44,35 @@ Node::~Node() { delete children_[i]; } delete[] localParticles_; +} + +Node& Node::operator=(const Node& other) { + root_ = other.root_; + parent_ = other.parent_; + particles_ = other.particles_; + nParticles_ = other.nParticles_; + depth_ = other.depth_; + size_ = other.size_; + for (unsigned i=0; i<3; ++i) center_[i] = other.center_[i]; + localParticles_ = other.localParticles_; + nLocalParticles_ = other.nLocalParticles_; + mass_ = other.mass_; + for (unsigned i=0; i<8; ++i) children_[i] = other.children_[i]; + return *this; +} + +double* Node::calculateForce(unsigned particle) { + // calculate theta + double lambda = std::sqrt((center_[0] - particles_[3*particle + 0])*(center_[0] - particles_[3*particle + 0]) + + (center_[1] - particles_[3*particle + 1])*(center_[1] - particles_[3*particle + 1]) + + (center_[2] - particles_[3*particle + 2])*(center_[2] - particles_[3*particle + 2])); + double theta = size_/lambda; + // if angle too large, calculate force on particle from children + // else calculate force on particle from particles in this node + if (theta > theta0_) { + // TODO + } else { + // TODO + } + return nullptr; } \ No newline at end of file diff --git a/lib/node.hpp b/lib/node.hpp index 9d078fd..9150a8e 100644 --- a/lib/node.hpp +++ b/lib/node.hpp @@ -7,12 +7,20 @@ public: Node() = default; // whoever creates the node is responsible for deciding which particles are in which octant and for allocating the localParticles array // node will write to localParticles array - Node(Node* parent, double* particles, unsigned nParticles, unsigned depth, double size, double center[3], unsigned* localParticles, unsigned nLocalParticles); + Node(Node* parent, double* masses, double* particles, unsigned nParticles, unsigned depth, double size, double center[3], unsigned* localParticles, unsigned nLocalParticles); + // destuctor ~Node(); + // copy constructor + Node(const Node&) = default; + // copy assignment + Node& operator=(const Node&); + // calculate force on a particle recursively + double* calculateForce(unsigned particle); private: Node* root_; Node* parent_; Node* children_[8]; + double* masses_; double* particles_; unsigned nParticles_; unsigned depth_; @@ -20,6 +28,8 @@ private: double center_[3]; unsigned* localParticles_; unsigned nLocalParticles_; + double mass_; + const double theta0_ = 0.4; }; #endif /* NODE_HPP */ \ No newline at end of file diff --git a/lib/tree.cpp b/lib/tree.cpp index 75b9257..22f0d38 100644 --- a/lib/tree.cpp +++ b/lib/tree.cpp @@ -1,7 +1,7 @@ #include "tree.hpp" #include "node.hpp" -Tree::Tree(double* particles, double* forces, unsigned nParticles, double size, double* center) { +Tree::Tree(double* masses, double* particles, double* forces, unsigned nParticles, double size, double* center) { particles_ = particles; forces_ = forces; nParticles_ = nParticles; @@ -13,13 +13,18 @@ Tree::Tree(double* particles, double* forces, unsigned nParticles, double size, for (unsigned i=0; i < nParticles_; ++i) localParticles_[i] = i; root_ = new Node(); - *root_ = Node(root_, particles_, nParticles_, 0, size_, center_, localParticles_, nParticles_); + *root_ = Node(root_, masses_, particles_, nParticles_, 0, size_, center_, localParticles_, nParticles_); } Tree::~Tree() { delete root_; } +void Tree::calculateForce(unsigned particle) { + double* force = root_->calculateForce(particle); + for (unsigned i=0; i < 3; ++i) forces_[3*particle + i] = force[i]; +} + void Tree::update() { // TODO } diff --git a/lib/tree.hpp b/lib/tree.hpp index 38cca7a..261647d 100644 --- a/lib/tree.hpp +++ b/lib/tree.hpp @@ -7,9 +7,11 @@ class Tree { public: // constructor Tree() = delete; - Tree(double* particles, double* forces_, unsigned nParticles, double size, double* center); + Tree(double* masses, double* particles, double* forces_, unsigned nParticles, double size, double* center); // destructor ~Tree(); + // calculate force on a particle + void calculateForce(unsigned particle); // update tree: visit each node, check if it needs to be split or merged (for example if a particle has left the region) void update(); // drift tree: visit each node, update positions @@ -18,6 +20,7 @@ public: void kick(double dt); private: Node* root_; + double* masses_; double* particles_; double* forces_; unsigned nParticles_; -- GitLab