Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
GridRender.cpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
21#include "shambackends/vec.hpp"
22#include "shamcomm/logs.hpp"
23#include "shammath/AABB.hpp"
28
29namespace shammodels::ramses::modules {
30
31 // implement render slice function
32 template<class Tvec, class TgridVec, class Tfield>
33 sham::DeviceBuffer<Tfield> GridRender<Tvec, TgridVec, Tfield>::compute_slice(
34 std::function<field_getter_t> field_getter, const sham::DeviceBuffer<Tvec> &positions) {
35
36 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
37 auto &q = shambase::get_check_ref(dev_sched).get_queue();
38
39 sham::DeviceBuffer<Tfield> ret{positions.get_size(), dev_sched};
41
42 using u_morton = u64;
44
46 = scheduler().get_sim_box().template get_patch_transform<TgridVec>();
47
48 scheduler().for_each_patchdata_nonempty([&](const shamrock::patch::Patch cur_p,
50 shammath::CoordRange<TgridVec> box = transf.to_obj_coord(cur_p);
51
52 PatchDataField<TgridVec> &block_min = pdat.get_field<TgridVec>(0);
53 PatchDataField<TgridVec> &block_max = pdat.get_field<TgridVec>(1);
54
55 auto &buf_block_min = block_min.get_buf();
56 auto &buf_block_max = block_max.get_buf();
57
58 using Block = typename Config::AMRBlock;
59 u32 block_size = Block::block_size;
60
61 u64 num_obj = block_min.get_obj_cnt();
62
63 sham::DeviceBuffer<Tvec> pos_max_cell(num_obj * block_size, dev_sched);
64 sham::DeviceBuffer<Tvec> pos_min_cell(num_obj * block_size, dev_sched);
65
66 Tscal dxfact = solver_config.grid_coord_to_pos_fact;
67
69 q,
70 sham::MultiRef{buf_block_min, buf_block_max},
71 sham::MultiRef{pos_min_cell, pos_max_cell},
72 num_obj,
73 [dxfact](
74 u32 id_a,
75 const TgridVec *__restrict ptr_block_min,
76 const TgridVec *__restrict ptr_block_max,
77 Tvec *cell_min,
78 Tvec *cell_max) {
79 Tvec block_min = ptr_block_min[id_a].template convert<Tscal>() * dxfact;
80 Tvec block_max = ptr_block_max[id_a].template convert<Tscal>() * dxfact;
81
82 Tvec delta_cell = (block_max - block_min) / Block::side_size;
83 for (u32 ix = 0; ix < Block::side_size; ix++) {
84 for (u32 iy = 0; iy < Block::side_size; iy++) {
85 for (u32 iz = 0; iz < Block::side_size; iz++) {
86 u32 i = Block::get_index({ix, iy, iz});
87 Tvec delta_val = delta_cell * Tvec{ix, iy, iz};
88 cell_min[id_a * Block::block_size + i] = block_min + delta_val;
89 cell_max[id_a * Block::block_size + i]
90 = block_min + (delta_cell) + delta_val;
91 }
92 }
93 }
94 });
95
96 Tvec min_pos
97 = shamalgs::primitives::min(dev_sched, pos_min_cell, 0, num_obj * block_size);
98 Tvec max_pos
99 = shamalgs::primitives::max(dev_sched, pos_max_cell, 0, num_obj * block_size);
100
101 auto &buf_field_to_render = field_getter(cur_p, pdat);
102
103 shammath::AABB<Tvec> tree_box(min_pos, max_pos);
104 u32 reduction_level = 0;
105
106 RTree tree = RTree::make_empty(dev_sched);
107 tree.rebuild_from_position_range(pos_min_cell, pos_max_cell, tree_box, reduction_level);
108
109 auto leaf_iterator = tree.get_object_iterator();
110
112 q,
114 positions, pos_min_cell, pos_max_cell, leaf_iterator, buf_field_to_render},
115 sham::MultiRef{ret},
116 positions.get_size(),
117 [](u32 id_a,
118 const Tvec *positions,
119 const Tvec *min_pos,
120 const Tvec *max_pos,
121 auto cell_finder,
122 const Tfield *buf_field_to_render,
123 Tfield *ret) {
124 Tvec pos_a = positions[id_a];
125
126 Tfield accumulator = {};
127
128 cell_finder.rtree_for(
129 [&](u32 node_id, shammath::AABB<Tvec> node_aabb) -> bool {
130 return node_aabb.contains_asymmetric(pos_a);
131 },
132 [&](u32 id_b) {
133 shammath::AABB<Tvec> cell_b = {min_pos[id_b], max_pos[id_b]};
134
135 if (cell_b.contains_asymmetric(pos_a)) {
136 Tfield val_cell = buf_field_to_render[id_b];
137 accumulator += val_cell;
138 }
139 });
140
141 ret[id_a] += accumulator;
142 });
143 });
144
145 shamalgs::collective::reduce_buffer_in_place_sum(ret, MPI_COMM_WORLD);
146
147 return ret;
148 }
149
150 // implement render slice function
151 template<class Tvec, class TgridVec, class Tfield>
152 sham::DeviceBuffer<Tfield> GridRender<Tvec, TgridVec, Tfield>::compute_slice(
153 std::string field_name, const sham::DeviceBuffer<Tvec> &positions) {
154 auto field_source_getter
155 = [&](const shamrock::patch::Patch cur_p,
157 return pdat.get_field<Tfield>(pdat.pdl().get_field_idx<Tfield>(field_name)).get_buf();
158 };
159 return compute_slice(field_source_getter, positions);
160 }
161} // namespace shammodels::ramses::modules
162
163using namespace shammath;
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
A buffer allocated in USM (Unified Shared Memory)
size_t get_size() const
Gets the number of elements in the buffer.
u32 get_field_idx(const std::string &field_name) const
Get the field id if matching name & type.
PatchDataLayer container class, the layout is described in patchdata_layout.
A Compressed Leaf Bounding Volume Hierarchy (CLBVH) for neighborhood queries.
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.
T min(const sham::DeviceScheduler_ptr &sched, const sham::DeviceBuffer< T > &buf1, u32 start_id, u32 end_id)
Find the minimum element in a device buffer within a specified range.
T max(const sham::DeviceScheduler_ptr &sched, const sham::DeviceBuffer< T > &buf1, u32 start_id, u32 end_id)
Find the maximum element in a device buffer within a specified range.
T & get_check_ref(const std::unique_ptr< T > &ptr, SourceLocation loc=SourceLocation())
Takes a std::unique_ptr and returns a reference to the object it holds. It throws a std::runtime_erro...
Definition memory.hpp:110
namespace for math utility
Definition AABB.hpp:26
A class that references multiple buffers or similar objects.
Axis-Aligned bounding box.
Definition AABB.hpp:99
bool contains_asymmetric(T point) const noexcept
Check if point is in AABB using half-open interval [lower, upper)
Definition AABB.hpp:256
Patch object that contain generic patch information.
Definition Patch.hpp:33