Orrery
A GPU-accelerated N-body gravitational simulator
Loading...
Searching...
No Matches
octree.hpp
Go to the documentation of this file.
1#pragma once
2
61
62#include <cstdint>
63#include <span>
64#include <vector>
65
67#include "orrery/core/types.hpp"
68#include "orrery/core/vec3.hpp"
71
72namespace orrery::solvers {
73
89struct Quadrupole {
90 core::Real xx{};
91 core::Real xy{};
92 core::Real xz{};
93 core::Real yy{};
94 core::Real yz{};
95 core::Real zz{};
96};
97
104struct TreeNode {
106 core::Real mass{};
107
110
127
131
134
137
138 [[nodiscard]] constexpr bool leaf() const noexcept { return particle_count > 0; }
139};
140
163 core::Real opening_angle{static_cast<core::Real>(0.5)};
164
179
190 bool quadrupole{false};
191};
192
199[[nodiscard]] TreeParameters corrected_parameters(TreeParameters parameters) noexcept;
200
208class Octree {
209public:
220 void build(core::Vec3Span<const core::Real> positions, std::span<const core::Real> masses,
221 std::span<const MortonKey> keys, const BoundingCube& cube,
223
226 [[nodiscard]] std::span<const TreeNode> nodes() const noexcept { return nodes_; }
227
232 [[nodiscard]] std::span<const Quadrupole> quadrupoles() const noexcept { return quadrupoles_; }
233
234 [[nodiscard]] bool empty() const noexcept { return nodes_.empty(); }
235
238 [[nodiscard]] const TreeParameters& parameters() const noexcept { return parameters_; }
239
245 [[nodiscard]] core::Index leaf_count() const noexcept { return leaf_count_; }
246
248 [[nodiscard]] unsigned depth() const noexcept { return depth_; }
249
250private:
259 struct Subtree {
260 core::Index begin{};
261 core::Index end{};
262 core::Index top_index{};
263 unsigned level{};
264 core::Vec3 centre;
265 core::Real size{};
266 std::vector<TreeNode> nodes;
267 std::vector<Quadrupole> quadrupoles;
268
275 core::Index leaves{};
276 unsigned depth{};
277 };
278
281 struct BuildInput {
282 core::Vec3Span<const core::Real> positions;
283 std::span<const core::Real> masses;
284 std::span<const MortonKey> keys;
285 };
286
295 struct TopCell {
296 core::Vec3 centre;
297 core::Real size{};
298 };
299
302 void descend(const BuildInput& input, core::Index begin, core::Index end, unsigned level,
303 core::Vec3 centre, core::Real size, core::Index threshold);
304
306 void build_subtree(const BuildInput& input, Subtree& subtree) const;
307
317 void emit(const BuildInput& input, Subtree& sink, core::Index begin, core::Index end,
318 unsigned level, core::Vec3 centre, core::Real size) const;
319
322 [[nodiscard]] Subtree& next_subtree();
323
326 [[nodiscard]] core::Real acceptance_radius_squared(core::Real size,
327 core::Real offset) const noexcept;
328
330 void assemble();
331
332 std::vector<TreeNode> nodes_;
333 std::vector<Quadrupole> quadrupoles_;
334
335 // The five members below hold nothing between builds except their storage,
336 // which is the point of them. A solver evaluates millions of times on
337 // configurations of one size, so a tree that allocated its working buffers
338 // on every build would spend a measurable part of every force evaluation in
339 // the allocator and would return the same pages to it immediately
340 // afterwards.
341
344 std::vector<Subtree> subtrees_;
345
347 core::Index subtree_count_{};
348
352 std::vector<TreeNode> assembled_;
353 std::vector<Quadrupole> assembled_quadrupoles_;
354
357 std::vector<core::Index> shift_;
358
360 std::vector<TopCell> top_cells_;
361
362 TreeParameters parameters_;
363 core::Index leaf_count_{};
364 unsigned depth_{};
365};
366
367} // namespace orrery::solvers
Something that can run a loop body over a range, possibly in parallel.
Definition executor.hpp:52
The octree of one configuration, built from Morton-sorted particles.
Definition octree.hpp:208
std::span< const TreeNode > nodes() const noexcept
The nodes, in depth-first order.
Definition octree.hpp:226
std::span< const Quadrupole > quadrupoles() const noexcept
The quadrupole moment of each node, or an empty span when the moments were not asked for.
Definition octree.hpp:232
const TreeParameters & parameters() const noexcept
The parameters the last build used, after the corrections described on TreeParameters.
Definition octree.hpp:238
unsigned depth() const noexcept
The depth of the deepest leaf, counting the root as depth zero.
Definition octree.hpp:248
core::Index leaf_count() const noexcept
How many nodes are leaves.
Definition octree.hpp:245
void build(core::Vec3Span< const core::Real > positions, std::span< const core::Real > masses, std::span< const MortonKey > keys, const BoundingCube &cube, const TreeParameters &parameters, backend::Executor *executor)
Build the tree over particles already sorted by Morton code.
How a kernel asks for a loop to be run in parallel.
The order the tree solver reads particles in, and the reason it is not the order they arrived in.
TreeParameters corrected_parameters(TreeParameters parameters) noexcept
parameters with the corrections its own documentation describes: the opening angle brought into [0,...
A view of three component arrays of equal length.
Definition vec3_span.hpp:33
A vector in three-dimensional Euclidean space.
Definition vec3.hpp:26
The cube that encloses a configuration.
Definition morton.hpp:85
The traceless second moment of a cell about its centre of mass.
Definition octree.hpp:89
One cell of the tree.
Definition octree.hpp:104
core::Index first_particle
The first particle of a leaf, in the sorted order.
Definition octree.hpp:133
core::Real mass
The total mass of everything below this node.
Definition octree.hpp:106
core::Real acceptance_radius_squared
The squared distance from the centre of mass beyond which this node may be treated as a single mass.
Definition octree.hpp:126
core::Index next
The index just past this node's subtree, which is where a walk that does not descend into it continue...
Definition octree.hpp:130
core::Vec3 centre_of_mass
The mass-weighted mean position of everything below this node.
Definition octree.hpp:109
core::Index particle_count
How many particles a leaf holds, and zero for an internal node.
Definition octree.hpp:136
The choices that decide what the tree costs and how accurate it is.
Definition octree.hpp:147
bool quadrupole
Whether to compute and use the quadrupole moment of each cell.
Definition octree.hpp:190
core::Index leaf_capacity
The most particles a cell may hold and still be a leaf.
Definition octree.hpp:178
core::Real opening_angle
The opening angle, in the sense of the criterion in octree.hpp's acceptance radius: a cell of size s ...
Definition octree.hpp:163
The scalar and index types that every layer of the project agrees on.
std::size_t Index
The type of a particle index and of any count of particles.
Definition types.hpp:45
A three-component vector for interfaces, not for storage.
Three parallel component arrays, viewed as one sequence of 3-vectors.