#include <string> #include <sstream> #include <iostream> #include <fstream> #include "Tree.hpp" #include "Node.hpp" namespace nbody { using namespace std; Tree::Tree() { //insert dummy root node this->nodes = new Node(this); } Tree::~Tree() { this->clean(); delete this->nodes; } void Tree::clean() { //remove all nodes; refresh root node while (this->nodes->next != this->nodes) { Node* node = this->nodes->next; node->unlink(); delete node; } delete this->nodes; this->nodes = new Node(this); } bool Tree::isCorrect() { Node* current = this->nodes->next; while (current != this->nodes) { if (!current->isCorrect()) { return false; } current = current->next; } return true; } unsigned long Tree::numberOfNodes() { unsigned long nodes = 0; for (Node* node = this->nodes->next; node != this->nodes; node = node->next) { nodes++; } return nodes; } void Tree::accumulateForceOnto(Body& body) { Node* n = this->nodes->next; body.resetAcceleration(); while (n != this->nodes) { if (n->sufficientForBody(body)) { n->representative.accumulateForceOnto(body); } else if (n->leaf) { for (vector<Body>::iterator it = n->bodies.begin(); it != n->bodies.end(); it++) { it->accumulateForceOnto(body); } } n = n->afterSubtree; } } void Tree::computeForces() { for (Node* n = this->nodes->next; n != this->nodes; n = n->next) { if (n->leaf) { for (vector<Body>::iterator it = n->bodies.begin(); it != n->bodies.end(); it++) { this->accumulateForceOnto(*it); } } } } vector<Body> Tree::dubinskiParse(string filename) { vector<Body> result; string line; ifstream infile(filename.c_str(), ifstream::in); double mass, px, py, pz, vx, vy, vz; while (infile >> mass >> px >> py >> pz >> vx >> vy >> vz) { Body b(px, py, pz, vx, vy, vz, mass); result.push_back(b); } infile.close(); return result; } void Tree::moveBodies() { for (Node* n = this->nodes->next; n != this->nodes; n = n->next) { if (n->leaf) { for (vector<Body>::iterator it = n->bodies.begin(); it != n->bodies.end(); it++) { it->integrate(); } } } } vector<Body> Tree::extractBodies() { vector<Body> result; while (this->nodes->next != this->nodes) { if (this->nodes->next->leaf) { result.insert(result.end(), nodes->next->bodies.begin(), nodes->next->bodies.end()); } Node* h = this->nodes->next; this->nodes->next->unlink(); delete(h); } this->clean(); return result; } void Tree::rebuildTree() { this->build(this->extractBodies()); } }