39 auto edges = get_edges();
41 edges.field_axyz_ext.ensure_sizes(edges.sizes.indexes);
43 if (edges.sizes.indexes.get_ids().size() != 1) {
45 "Self gravity FMM mode only supports one patch so far, current number "
47 + std::to_string(edges.sizes.indexes.get_ids().size()));
50 Tscal G = edges.constant_G.data;
51 Tscal gpart_mass = edges.gpart_mass.data;
53 Tscal gravitational_softening = epsilon * epsilon;
56 static constexpr u32 mass_moment_terms = MassMoments::num_component;
58 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
63 [&](
u64 id,
const u64 &n) {
67 Tvec bmax = xyz.compute_max();
68 Tvec bmin = xyz.compute_min();
72 auto bvh = RTree::make_empty(dev_sched);
73 bvh.rebuild_from_positions(
74 xyz.get_buf(), xyz.get_obj_cnt(), aabb, reduction_level);
77 auto mass_moments_tree = compute_tree_mass_moments<Tvec, Umorton, mm_order - 1>(
78 bvh, xyz.get_buf(), gpart_mass);
81 auto obj_it = bvh.get_object_iterator();
84 sham::MultiRef{xyz.get_buf(), obj_it, mass_moments_tree.buf_field},
86 bvh.structure.get_leaf_count(),
87 [theta_crit = theta_crit, gravitational_softening, gpart_mass, G](
91 const Tscal *mass_moments_scal,
93 auto &tree_traverser = particle_looper.tree_traverser;
94 auto &cell_iterator = particle_looper.cell_iterator;
96 u32 leaf_id_tree = ileaf + tree_traverser.tree_traverser.offset_leaf;
98 tree_traverser.aabb_min[leaf_id_tree],
99 tree_traverser.aabb_max[leaf_id_tree]};
102 Tvec delta_A = box_A_AABB.
delt();
103 Tscal sz_A = sham::max_component(delta_A) / 2;
109 [&](
u32 node_id) ->
bool {
113 tree_traverser.aabb_min[node_id],
114 tree_traverser.aabb_max[node_id]};
117 Tvec delta_B = node_aabb.
delt();
118 Tscal sz_B = sham::max_component(delta_B) / 2;
121 Tscal r_sq = r.x() * r.x() + r.y() * r.y() + r.z() * r.z();
123 Tscal theta = (r_sq == 0)
125 : (sz_B + sz_A) * sycl::rsqrt(r_sq);
127 return theta > theta_crit;
131 = node_id - tree_traverser.tree_traverser.offset_leaf;
133 cell_iterator.for_each_in_leaf_cell(leaf_id, [&](
u32 j) {
134 cell_iterator.for_each_in_leaf_cell(ileaf, [&](
u32 i) {
135 Tvec R = xyz[j] - xyz[i];
136 const Tscal r_inv = sycl::rsqrt(
137 R.x() * R.x() + R.y() * R.y() + R.z() * R.z()
138 + gravitational_softening);
140 += G * gpart_mass * r_inv * r_inv * r_inv * R;
149 Tvec r_fmm = s_B - s_A;
151 MassMoments Q_n_B = MassMoments::load(
153 + node_id * MassMoments::num_component,
160 dM_k += shamphys::get_dM_mat(D_n, Q_n_B);
164 cell_iterator.for_each_in_leaf_cell(ileaf, [&](
u32 i) {
165 Tvec a_i = xyz[i] - s_A;
172 * shamphys::contract_grav_moment_to_force<Tscal, mm_order>(