Orrery
A GPU-accelerated N-body gravitational simulator
Loading...
Searching...
No Matches
morton.hpp
Go to the documentation of this file.
1#pragma once
2
52
53#include <cstdint>
54#include <span>
55#include <vector>
56
58#include "orrery/core/types.hpp"
59#include "orrery/core/vec3.hpp"
61
62namespace orrery::solvers {
63
70using MortonCode = std::uint64_t;
71
73inline constexpr unsigned kMortonBitsPerAxis = 21;
74
76inline constexpr std::uint32_t kMortonGridSize = std::uint32_t{1} << kMortonBitsPerAxis;
77
88
91 core::Real size{};
92
93 [[nodiscard]] core::Vec3 centre() const noexcept {
94 return origin + core::Vec3{size / 2, size / 2, size / 2};
95 }
96};
97
110
121[[nodiscard]] MortonCode spread_bits(std::uint32_t value) noexcept;
122
130[[nodiscard]] MortonCode morton_code(std::uint32_t x, std::uint32_t y, std::uint32_t z) noexcept;
131
139[[nodiscard]] MortonCode morton_code(core::Vec3 position, const BoundingCube& cube) noexcept;
140
146[[nodiscard]] unsigned morton_octant(MortonCode code, unsigned level) noexcept;
147
155struct MortonKey {
156 MortonCode code{};
157 core::Index index{};
158
173 [[nodiscard]] friend constexpr auto operator<=>(const MortonKey&,
174 const MortonKey&) noexcept = default;
175};
176
183public:
192
194 [[nodiscard]] std::span<const MortonKey> keys() const noexcept { return keys_; }
195
197 [[nodiscard]] const BoundingCube& cube() const noexcept { return cube_; }
198
199private:
205 void sort(backend::Executor* executor);
206
207 std::vector<MortonKey> keys_;
208 std::vector<MortonKey> scratch_;
209 BoundingCube cube_;
210};
211
212} // namespace orrery::solvers
Something that can run a loop body over a range, possibly in parallel.
Definition executor.hpp:52
The particles of a configuration, in the order the tree wants them.
Definition morton.hpp:182
void build(core::Vec3Span< const core::Real > positions, backend::Executor *executor)
Compute and sort the codes of positions.
std::span< const MortonKey > keys() const noexcept
The keys, ascending. Empty until build has been called.
Definition morton.hpp:194
const BoundingCube & cube() const noexcept
The cube the codes were computed in.
Definition morton.hpp:197
How a kernel asks for a loop to be run in parallel.
std::uint64_t MortonCode
A position on the space-filling curve.
Definition morton.hpp:70
constexpr std::uint32_t kMortonGridSize
The number of grid cells along one side of the bounding cube.
Definition morton.hpp:76
MortonCode morton_code(std::uint32_t x, std::uint32_t y, std::uint32_t z) noexcept
The code of a point at integer grid coordinates.
MortonCode spread_bits(std::uint32_t value) noexcept
Spread the low 21 bits of value out to every third bit.
constexpr unsigned kMortonBitsPerAxis
Bits of code per axis, and so the number of levels of subdivision available.
Definition morton.hpp:73
unsigned morton_octant(MortonCode code, unsigned level) noexcept
The octant, 0 to 7, that code occupies at level.
BoundingCube bounding_cube(core::Vec3Span< const core::Real > positions) noexcept
The smallest cube containing every position, centred on their bounding box.
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
core::Real size
The length of one side.
Definition morton.hpp:91
core::Vec3 origin
The corner with the lowest coordinate on every axis.
Definition morton.hpp:87
One particle's place on the curve.
Definition morton.hpp:155
friend constexpr auto operator<=>(const MortonKey &, const MortonKey &) noexcept=default
Ordered by code, and by index where two codes are equal.
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.