13 "Invalid size of BarnesHut nodes");
15 "Invalid alignment of BarnesHut nodes");
21 const Float gravityConstant)
22 : kdTree(leafSize, maxDepth)
23 , thetaInv(1._f / theta)
26 , gravityConstant(gravityConstant) {
39 const Float gravityConstant)
40 : kdTree(leafSize, maxDepth)
41 , kernel(
std::move(kernel))
42 , thetaInv(1._f / theta)
45 , gravityConstant(gravityConstant) {
70 SPH_ASSERT(left ==
nullptr && right ==
nullptr);
74 SPH_ASSERT(left !=
nullptr && right !=
nullptr);
89 this->
evalNode(scheduler, dv, 0, std::move(data), result);
113 auto lambda = [
this, &r0, &f, idx](
123 if (!node.box.contains(r0) && boxSizeSqr > 0._f &&
164 , scheduler(scheduler)
167 , data(
std::move(data))
171 bh.
evalNode(scheduler, dv, nodeIdx, std::move(data), result);
187 const Size evaluatedNodeIdx,
192 const Box& box = evaluatedNode.
box;
205 const Size idx = *iter;
207 if (node.
r_open == 0._f) {
247 if (evaluatedNode.
isLeaf()) {
269 auto task = makeShared<NodeTask>(*
this, scheduler, dv, inner.
left, std::move(childData), result);
276 scheduler.
submit(std::move(task));
284 this->
evalNode(scheduler, dv, inner.
right, std::move(data), result);
296 for (
Size idx : particleList) {
303 for (
Size i : seq1) {
305 for (
Size j : seq2) {
308 dv[i] +=
m[j] * grad;
313 for (
Size i : seq1) {
314 for (
Size j : seq1) {
320 dv[i] +=
m[j] * grad;
330 for (
Size idx : nodeList) {
333 for (
Size i : seq1) {
342 for (
Size i : sequence) {
354 switch (leaf.
size()) {
358 leaf.moments.order<0>() = 0._f;
368 leaf.box.extend(
r[i]);
369 leaf.moments.order<0>() =
m[i];
380 for (
Size i : sequence) {
381 leaf.com +=
m[i] *
r[i];
385 leaf.box.extend(
r[i]);
392 const Vector r_max =
max(leaf.com - leaf.box.lower(), leaf.box.upper() - leaf.com);
398 SPH_ASSERT(computeMultipole<0>(
r,
m, leaf.com, sequence).value() == m_leaf);
399 const Multipole<2> m2 = computeMultipole<2>(
r,
m, leaf.com, sequence);
400 const Multipole<3> m3 = computeMultipole<3>(
r,
m, leaf.com, sequence);
407 leaf.moments.order<0>() = m_leaf;
409 leaf.moments.order<2>() = q2;
410 leaf.moments.order<3>() = q3;
418 inner.box.extend(left.
box);
419 inner.box.extend(right.
box);
426 if (ml + mr == 0._f) {
429 inner.moments.order<0>() = 0._f;
437 inner.com = (ml * left.
com + mr * right.
com) / (ml + mr);
441 const Vector r_max =
max(inner.com - inner.box.lower(), inner.box.upper() - inner.com);
445 inner.moments.order<0>() = ml + mr;
456 d = right.
com - inner.com;
INLINE bool isReal(const AntisymmetricTensor &t)
INLINE Float minElement(const AntisymmetricTensor &t)
Returns the minimal element of the tensor.
Utilities to simplify working with arrays.
bool areElementsUnique(const TStorage &container)
#define SPH_ASSERT(x,...)
#define NOT_IMPLEMENTED
Helper macro marking missing implementation.
Barnes-Hut algorithm for computation of gravitational acceleration.
uint32_t Size
Integral type used to index arrays (by default).
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
#define VERBOSE_LOG
Helper macro, creating.
constexpr INLINE T max(const T &f1, const T &f2)
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
INLINE T sqrt(const T f)
Return a squared root of a value.
INLINE TracelessMultipole< 1 > parallelAxisTheorem(const TracelessMultipole< 1 > &Qi, const Float Q, const Vector &d)
TracelessMultipole< N > computeReducedMultipole(const Multipole< N > &m)
Vector evaluateGravity(const Vector &dr, const MultipoleExpansion< N > &ms, const MultipoleOrder maxOrder)
@ SKIP_RANK
The rank of particles is not created. 'Dummy' option that can be used to improve readability.
#define NAMESPACE_SPH_END
Tool to measure time spent in functions and profile the code.
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
@ MASS
Paricles masses, always a scalar quantity.
SequentialScheduler SEQUENTIAL
Global instance of the sequential scheduler.
Interface for executing tasks (potentially) asynchronously.
Object representing a three-dimensional sphere.
@ BOX_INSIDE_SPHERE
Sphere contains the whole box.
@ BOX_OUTSIDE_SPHERE
Sphere has no intersection with the box.
Statistics gathered and periodically displayed during the run.
@ GRAVITY_NODES_APPROX
Number of tree nodes evaluated using multipole approximation.
@ GRAVITY_NODE_COUNT
Number of nodes in used gravity tree.
@ GRAVITY_NODES_EXACT
Number of tree nodes evaluated by pair-wise interacting.
Container for storing particle quantities and materials.
INLINE Float getLength(const Vector &v)
Returns the length of the vector. Enabled only for vectors of floating-point precision.
INLINE Float getSqrLength(const Vector &v)
BasicVector< Float > Vector
void resize(const TCounter newSize)
Resizes the array to new size.
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
INLINE TCounter size() const noexcept
Array clone() const
Performs a deep copy of all elements of the array.
NodeTask(const BarnesHut &bh, IScheduler &scheduler, ArrayView< Vector > dv, const Size nodeIdx, BarnesHut::TreeWalkState &&data, BarnesHut::TreeWalkResult &result)
Multipole approximation of distance particle.
virtual void evalAll(IScheduler &pool, ArrayView< Vector > dv, Statistics &stats) const override
Evaluates the gravitational acceleration concurrently.
void evalNode(IScheduler &scheduler, ArrayView< Vector > dv, const Size nodeIdx, TreeWalkState data, TreeWalkResult &result) const
Performs a recursive treewalk evaluating gravity for all particles.
ArrayView< const Vector > r
View of a position buffer in the storage.
MultipoleOrder order
Order of multipole approximation.
GravityLutKernel kernel
Kernel used to evaluate gravity of close particles.
BarnesHut(const Float theta, const MultipoleOrder order, const Size leafSize=25, const Size maxDepth=50, const Float gravityConstant=Constants::gravity)
Constructs the Barnes-Hut gravity assuming point-like particles (with zero radius).
virtual Vector eval(const Vector &r0) const override
Evaluates the gravitational acceleration at given point.
MultipoleExpansion< 3 > getMoments() const
Returns the multipole moments computed from root node.
void buildInner(BarnesHutNode &node, BarnesHutNode &left, BarnesHutNode &right)
Vector evalExact(const LeafNode< BarnesHutNode > &node, const Vector &r0, const Size idx) const
Size maxDepth
Maximum depth at which the nodes evaluation is parallelized.
Vector evalImpl(const Vector &r0, const Size idx) const
Evaluates the gravity at a single point in space.
void evalParticleList(const LeafNode< BarnesHutNode > &leaf, ArrayView< Size > particleList, ArrayView< Vector > dv) const
virtual RawPtr< const IBasicFinder > getFinder() const override
Optionally returns a finder used by the gravity implementation.
Array< Float > m
Particle masses multiplied by gravitational constant.
void evalNodeList(const LeafNode< BarnesHutNode > &leaf, ArrayView< Size > nodeList, ArrayView< Vector > dv) const
void buildLeaf(BarnesHutNode &node)
KdTree< BarnesHutNode > kdTree
K-d tree storing gravitational moments.
virtual Float evalEnergy(IScheduler &scheduler, Statistics &stats) const override
Computes the total potential energy of the particles.
Float gravityConstant
Gravitational constant in the selected unit system.
Float thetaInv
Inverted value of the opening angle for multipole approximation (in radians)
virtual void build(IScheduler &pool, const Storage &storage) override
Masses of particles must be strictly positive, otherwise center of mass would be undefined.
Helper object defining three-dimensional interval (box).
static Box EMPTY()
Syntactic sugar, returns a default-constructed (empty) box.
Gravitational kernel approximated by LUT for close particles.
INLINE Vector grad(const Vector &r, const Float h) const
INLINE Float radius() const
Interface that allows unified implementation of sequential and parallelized versions of algorithms.
virtual SharedPtr< ITask > submit(const Function< void()> &task)=0
Submits a task to be potentially executed asynchronously.
void build(IScheduler &scheduler, ArrayView< const Vector > points, Flags< FinderFlag > flags=FinderFlag::MAKE_RANK)
Constructs the struct with an array of vectors.
INLINE TNode & getNode(const Size nodeIdx)
Returns the node with given index.
INLINE LeafIndexSequence getLeafIndices(const LeafNode< TNode > &leaf) const
Returns the sequence of particles indices belonging to given leaf.
Outcome sanityCheck() const
Performs some checks of KdTree consistency, returns SUCCESS if everything is OK.
INLINE Size getNodeCnt() const
Returns the number of nodes in the tree.
Helper index sequence to iterate over particle indices of a leaf node.
INLINE LeafIndexIterator begin() const
ListIterator< T > end()
Returns a bidirectional iterator pointing to the one-past-last element of the list.
INLINE bool empty() const
Returns true if there are no elements in the list.
List clone() const
Creates a copy of the list.
void pushBack(U &&value)
Adds a new element to the back of the list.
ListIterator< T > erase(const ListIterator< T > iter)
Removes an element given by the iterator.
ListIterator< T > begin()
Returns a bidirectional iterator pointing to the first element of the list.
Non-owning wrapper of pointer.
INLINE IntersectResult intersectsBox(const Box &box) const
Checks the intersection of the sphere with a box.
Object holding various statistics about current run.
Statistics & set(const StatisticsId idx, TValue &&value)
Sets new values of a statistic.
Container storing all quantities used within the simulations.
Array< TValue > & getValue(const QuantityId key)
Retrieves a quantity values from the storage, given its key and value type.
INLINE Vector grad(const Vector &r1, const Vector &r2) const
Overload of std::swap for Sph::Array.
MultipoleExpansion< 3 > moments
Gravitational moments with a respect to the center of mass, using expansion to octupole order.
Vector com
Center of mass of contained particles.
std::atomic_int approximatedNodes
Number of nodes approximated using multipole expansion.
std::atomic_int exactNodes
Number of opened leafs where exact (pair-wise) solution has been used.
Data passed into each node during treewalk.
TreeWalkState clone() const
Clones all lists in the state object.
Array< Size > nodeList
Indices of nodes that shall be evaluated using multipole approximation.
Size depth
Current depth in the tree; root node has depth equal to zero.
Array< Size > particleList
Indices of nodes where the exact (pair-wise) gravity solution have to be used.
Size right
Index of right child node.
Size left
Index of left child node.
INLINE bool isLeaf() const
Box box
Bounding box of particles in the node.
Leaf (bucket) node of K-d tree.
INLINE Size size() const
Returns the number of points in the leaf. Can be zero.
INLINE std::enable_if_t< M !=N, TracelessMultipole< M > & > order()
MultipoleExpansion multiply(const Float factor) const
Object with deleted copy constructor and copy operator.