26 template<
class Tvec,
class Umorton, u32 moment_order>
27 inline shamtree::KarrasRadixTreeFieldMultiVar<shambase::VecComponent<Tvec>>
28 compute_tree_mass_moments(
29 shamtree::CompressedLeafBVH<Umorton, Tvec, 3> &bvh,
30 const sham::DeviceBuffer<Tvec> &xyz,
31 shambase::VecComponent<Tvec> gpart_mass) {
35 using Tscal = shambase::VecComponent<Tvec>;
36 using MassMoments = shammath::SymTensorCollection<Tscal, 0, moment_order>;
37 static constexpr u32 mass_moment_terms = MassMoments::num_component;
39 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
40 sham::DeviceQueue &q = shamsys::instance::get_compute_scheduler().
get_queue();
43 auto mass_moments_tree = shamtree::prepare_karras_radix_tree_field_multi_var<Tscal>(
45 shamtree::new_empty_karras_radix_tree_field_multi_var<Tscal>(mass_moment_terms));
50 = [&](shamtree::KarrasRadixTreeFieldMultiVar<Tscal> &tree_field,
u32 leaf_offset) {
53 sham::MultiRef{
xyz, cell_it, bvh.
aabbs.buf_aabb_min, bvh.
aabbs.buf_aabb_max},
56 [leaf_offset, gpart_mass](
62 Tscal *mass_moments_scal) {
64 MassMoments Q_n_B = MassMoments::zeros();
66 u32 cell_id = i + leaf_offset;
67 shammath::AABB<Tvec> cell_aabb
68 = shammath::AABB<Tvec>{aabb_min[cell_id], aabb_max[cell_id]};
72 cell_iter.for_each_in_leaf_cell(i, [&](
u32 j) {
73 Q_n_B += MassMoments::from_vec(xyz[j] - s_B);
79 = mass_moments_scal + (i + leaf_offset) * MassMoments::num_component;
80 Q_n_B.store(ptr_store, 0);
89 if (int_cell_count == 0) {
90 return mass_moments_tree;
94 auto traverser = bvh.
structure.get_structure_traverser();
98 sham::MultiRef{traverser, bvh.
aabbs.buf_aabb_min, bvh.
aabbs.buf_aabb_max},
99 sham::MultiRef{mass_moments_tree.buf_field},
103 const Tvec *aabb_min,
104 const Tvec *aabb_max,
105 Tscal *__restrict moments) {
106 u32 left_child = tree_traverser.get_left_child(gid);
107 u32 right_child = tree_traverser.get_right_child(gid);
109 Tscal *ptr_left = moments + left_child * MassMoments::num_component;
110 Tscal *ptr_right = moments + right_child * MassMoments::num_component;
113 = shammath::AABB<Tvec>{aabb_min[left_child], aabb_max[left_child]}
116 = shammath::AABB<Tvec>{aabb_min[right_child], aabb_max[right_child]}
119 = shammath::AABB<Tvec>{aabb_min[gid], aabb_max[gid]}.get_center();
121 MassMoments Q_n_B_left = MassMoments::load(ptr_left, 0);
122 MassMoments Q_n_B_right = MassMoments::load(ptr_right, 0);
125 MassMoments Q_n_B_combined = MassMoments::zeros();
127 += shamphys::offset_multipole(Q_n_B_left, left_center, new_center);
129 += shamphys::offset_multipole(Q_n_B_right, right_center, new_center);
131 Tscal *ptr_store = moments + gid * MassMoments::num_component;
132 Q_n_B_combined.store(ptr_store, 0);
140 return mass_moments_tree;
constexpr const char * xyz
Position field (3D coordinates).
std::uint32_t u32
32 bit unsigned integer
DeviceQueue & get_queue(u32 id=0)
Get a reference to a DeviceQueue.
KarrasRadixTreeAABB< Tvec > aabbs
The bounding box of the tree cells.
MortonReducedSet< Tmorton, Tvec, dim > reduced_morton_set
The reduced set of Morton codes.
KarrasRadixTree structure
The tree structure.
sham::DeviceBuffer< T > buf_field
field data (size = total_cell_count * nvar)
u32 get_leaf_count() const
Get leaf count.
u32 get_internal_cell_count() const
Get internal cell count.
void kernel_call(sham::DeviceQueue &q, RefIn in, RefOut in_out, u32 n, Functor &&func, SourceLocation &&callsite=SourceLocation{})
Submit a kernel to a SYCL queue.
namespace for the sph model modules
#define __shamrock_stack_entry()
Macro to create a stack entry.
T get_center() const noexcept
Returns the center of the AABB.