#ifndef TREE_HPP #define TREE_HPP #include <cstdlib> #include <string> #include <vector> #include "Body.hpp" #include "Box.hpp" #include "Node.hpp" namespace nbody { class Simulation; //superclass for Barnes-Hut tree class Tree { friend class Node; protected: Node* nodes; std::size_t maxLeafBodies{ 0 }; std::size_t parallelId{ 0 }; Simulation* simulation{ nullptr }; public: Tree(std::size_t parallelId_); virtual ~Tree(); virtual void clean(); virtual void build(std::vector<Body> bodies) = 0; virtual void build(std::vector<Body> bodies, const Box& domain) = 0; virtual std::size_t numberOfChildren() const = 0; virtual std::size_t numberOfNodes() const; virtual bool isCorrect() const; virtual void accumulateForceOnto(Body& body); virtual void computeForces(); virtual std::vector<Body> extractLocalBodies(); virtual std::vector<Body> copyRefinements(const Box& domain) const; virtual void rebuild(const Box& domain); virtual void rebuild(const Box& domain, const std::vector<Body>& bodies); virtual void rebuild(); virtual Box getRootBB() const; virtual void print(std::size_t parallelId) const; virtual Box advance(); virtual Box getLocalBB() const; protected: // represents a traversable view over nodes->next class NodesView { Tree* tree_; public: NodesView(Tree* tree) : tree_(tree) {}; auto begin() { return Node::NodeIterator{ tree_->nodes->next }; } auto end() { return Node::NodeIterator{ tree_->nodes }; } auto begin() const { return Node::NodeIterator{ tree_->nodes->next }; } auto end() const { return Node::NodeIterator{ tree_->nodes }; } auto rbegin() { return std::make_reverse_iterator(Node::NodeIterator{ tree_->nodes->prev }); } auto rend() { return std::make_reverse_iterator(Node::NodeIterator{ tree_->nodes }); } auto rbegin() const { return std::make_reverse_iterator(Node::NodeIterator{ tree_->nodes->prev }); } auto rend() const { return std::make_reverse_iterator(Node::NodeIterator{ tree_->nodes }); } }; NodesView nodesView; // represents a traversable view over nodes->nextSibling class SiblingNodesView { Node* start_; public: SiblingNodesView(Node* start) : start_(start) {} auto begin() { return Node::SiblingNodeIterator{ start_->next }; } auto end() { return Node::SiblingNodeIterator{ nullptr }; } auto begin() const { return Node::SiblingNodeIterator{ start_->next }; } auto end() const { return Node::SiblingNodeIterator{ nullptr }; } }; SiblingNodesView getSiblingNodesView(Node* start) { return{ start }; } }; } // namespace nbody #endif