Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
smoothing_lenght.hpp
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
10//%Impl status : Good
11
12#pragma once
13
20
22#include "shamrock/legacy/patch/interfaces/interface_handler.hpp"
23#include "shamrock/legacy/patch/interfaces/interface_selector.hpp"
25// #include "shamrock/legacy/patch/patchdata_buffer.hpp"
26#include "shammodels/sph/legacy/algs/smoothing_length_impl.hpp"
27#include "shamrock/legacy/patch/utility/merged_patch.hpp"
30#include "shamrock/sph/kernels.hpp"
31#include "shamrock/sph/sphpart.hpp"
34
35namespace models::sph {
36 namespace algs {
37
38 template<class flt, class morton_prec, class Kernel>
39 class SmoothinglengthCompute {
40
41 using vec = sycl::vec<flt, 3>;
42
43 using Rtree = RadixTree<morton_prec, vec>;
45
46 flt htol_up_tol;
47 flt htol_up_iter;
48
49 u32 ihpart;
50 u32 ixyz;
51
52 public:
53 SmoothinglengthCompute(
54 shamrock::patch::PatchDataLayerLayout &pdl, f32 htol_up_tol, f32 htol_up_iter) {
55
56 ixyz = pdl.get_field_idx<vec>("xyz");
57 ihpart = pdl.get_field_idx<flt>("hpart");
58
59 this->htol_up_tol = htol_up_tol;
60 this->htol_up_iter = htol_up_iter;
61 }
62
63 inline void iterate_smoothing_length(
64 sycl::queue &queue,
65 u32 or_element_cnt,
66
67 flt gpart_mass,
68
69 Rtree &radix_t,
70 RadixTreeField<flt> &int_rad,
71
72 shamrock::patch::PatchData &pdat_merge,
73 sycl::buffer<flt> &hnew,
74 sycl::buffer<flt> &omega,
75 sycl::buffer<flt> &eps_h) {
76
77 StackEntry stack_loc{};
78
79 impl::sycl_init_h_iter_bufs(
80 queue, or_element_cnt, ihpart, pdat_merge, hnew, omega, eps_h);
81
82 for (u32 it_num = 0; it_num < 30; it_num++) {
83
85 flt>(
86 queue,
87 or_element_cnt,
88 ihpart,
89 ixyz,
90 gpart_mass,
91 htol_up_tol,
92 htol_up_iter,
93 radix_t,
94 int_rad,
95 pdat_merge,
96 hnew,
97 omega,
98 eps_h);
99
100 //{
101 // sycl::host_accessor acc {eps_h};
102 //
103 // logger::raw_ln("------eps_h-----");
104 // for (u32 i = 0; i < eps_h.size(); i ++) {
105 // logger::raw(acc[i],",");
106 // }
107 // logger::raw_ln("----------------");
108 //}
109 }
110
112 flt>(
113 queue,
114 or_element_cnt,
115 ihpart,
116 ixyz,
117 gpart_mass,
118 htol_up_tol,
119 htol_up_iter,
120 radix_t,
121 int_rad,
122 pdat_merge,
123 hnew,
124 omega,
125 eps_h);
126 }
127
128#if false
129 [[deprecated]]
130 inline void iterate_smoothing_length(
131 sycl::queue & queue,
132 u32 or_element_cnt,
133
134 flt gpart_mass,
135
136 Rtree & radix_t,
137
138 PatchDataBuffer & pdat_buf_merge,
139 sycl::buffer<flt> & hnew,
140 sycl::buffer<flt> & omega,
141 sycl::buffer<flt> & eps_h){
142
143 auto timer = timings::start_timer("iterate_smoothing_length",timings::function);
144
145 impl::sycl_init_h_iter_bufs(queue, or_element_cnt,ihpart, pdat_buf_merge, hnew, omega, eps_h);
146
147 for (u32 it_num = 0 ; it_num < 30; it_num++) {
148
150 or_element_cnt,
151 ihpart,
152 ixyz,
153 gpart_mass,
154 htol_up_tol,
155 htol_up_iter,
156 radix_t,
157 pdat_buf_merge,
158 hnew,
159 omega,
160 eps_h);
161
162 //{
163 // sycl::host_accessor acc {eps_h};
164 //
165 // logger::raw_ln("------eps_h-----");
166 // for (u32 i = 0; i < eps_h.size(); i ++) {
167 // logger::raw(acc[i],",");
168 // }
169 // logger::raw_ln("----------------");
170 //}
171 }
172
174 or_element_cnt,
175 ihpart,
176 ixyz,
177 gpart_mass,
178 htol_up_tol,
179 htol_up_iter,
180 radix_t,
181 pdat_buf_merge,
182 hnew,
183 omega,
184 eps_h);
185
186 timer.stop();
187
188 }
189
190#endif
191 };
192
193 template<class flt, class u_morton, class Kernel>
194 inline void compute_smoothing_length(
195 PatchScheduler &sched,
196 bool periodic_mode,
197 flt htol_up_tol,
198 flt htol_up_iter,
199 flt sph_gpart_mass) {
200
201 using namespace shamrock::patch;
202
203 using vec = sycl::vec<flt, 3>;
204 using Rtree = RadixTree<u_morton, vec>;
206
207 const flt loc_htol_up_tol = htol_up_tol;
208 const flt loc_htol_up_iter = htol_up_iter;
209
210 const u32 ixyz = sched.pdl.get_field_idx<vec>("xyz");
211 const u32 ihpart = sched.pdl.get_field_idx<flt>("hpart");
212
213 // Init serial patch tree
215 sched.patch_tree, sched.get_sim_box().get_patch_transform<vec>());
216 sptree.attach_buf();
217
218 // compute hmax
220 sched.compute_patch_field(
221 h_field,
222 get_mpi_type<flt>(),
223 [loc_htol_up_tol](sycl::queue &queue, Patch &p, PatchData &pdat) {
224 return patchdata::sph::get_h_max<flt>(pdat.pdl, queue, pdat) * loc_htol_up_tol
225 * Kernel::Rkern;
226 });
227
228 // make interfaces
229 LegacyInterfacehandler<vec, flt> interface_hndl;
230 interface_hndl.template compute_interface_list<InterfaceSelector_SPH<vec, flt>>(
231 sched, sptree, h_field, periodic_mode);
232 interface_hndl.comm_interfaces(sched, periodic_mode);
233
234 // merging strategy
235 std::unordered_map<u64, MergedPatchData<flt>> merge_pdat
236 = MergedPatchData<flt>::merge_patches(sched, interface_hndl);
237
238 // make trees
239 std::unordered_map<u64, std::unique_ptr<RadixTree<u_morton, vec>>> radix_trees;
240 std::unordered_map<u64, std::unique_ptr<RadixTreeField<flt>>> cell_int_rads;
241
242 constexpr u32 reduc_level = 5;
243
244 sched.for_each_patch([&](u64 id_patch, const Patch & /*cur_p*/) {
245 shamlog_debug_ln("SPHLeapfrog", "patch : n", id_patch, "->", "making Radix Tree");
246
247 if (merge_pdat.at(id_patch).or_element_cnt == 0)
248 shamlog_debug_ln(
249 "SPHLeapfrog", "patch : n", id_patch, "->", "is empty skipping tree build");
250
251 // PatchDataBuffer &mpdat_buf = *merge_pdat_buf.at(id_patch).data;
252 PatchData &mpdat = merge_pdat.at(id_patch).data;
253
254 auto &buf_xyz = mpdat.get_field<vec>(ixyz).get_buf();
255
256 std::tuple<vec, vec> &box = merge_pdat.at(id_patch).box;
257
258 // radix tree computation
259 radix_trees[id_patch] = std::make_unique<RadixTree<u_morton, vec>>(
261 box,
262 buf_xyz,
263 mpdat.get_obj_cnt(),
264 reduc_level);
265 });
266
267 sched.for_each_patch([&](u64 id_patch, Patch /*cur_p*/) {
268 shamlog_debug_ln(
269 "SPHLeapfrog", "patch : n", id_patch, "->", "compute radix tree cell volumes");
270 if (merge_pdat.at(id_patch).or_element_cnt == 0)
271 shamlog_debug_ln(
272 "SPHLeapfrog",
273 "patch : n",
274 id_patch,
275 "->",
276 "is empty skipping tree volumes step");
277
278 radix_trees[id_patch]->compute_cell_ibounding_box(
280 radix_trees[id_patch]->convert_bounding_box(shamsys::instance::get_compute_queue());
281 });
282
283 sched.for_each_patch([&](u64 id_patch, Patch /*cur_p*/) {
284 shamlog_debug_ln(
285 "SPHLeapfrog",
286 "patch : n",
287 id_patch,
288 "->",
289 "compute Radix Tree interaction boxes");
290 if (merge_pdat.at(id_patch).or_element_cnt == 0)
291 shamlog_debug_ln(
292 "SPHLeapfrog",
293 "patch : n",
294 id_patch,
295 "->",
296 "is empty skipping interaction box compute");
297
298 PatchData &mpdat = merge_pdat.at(id_patch).data;
299
300 auto &buf_h = mpdat.get_field<flt>(ihpart).get_buf();
301
302 cell_int_rads[id_patch] = std::make_unique<RadixTreeField<flt>>(
303 radix_trees[id_patch]->compute_int_boxes(
304 shamsys::instance::get_compute_queue(), buf_h, htol_up_tol));
305 });
306
307 // create compute field for new h and omega
308 std::cout << "making omega field" << std::endl;
309 PatchComputeField<flt> hnew_field;
310 PatchComputeField<flt> omega_field;
311
312 hnew_field.generate(sched);
313 omega_field.generate(sched);
314
315 // iterate smoothing length
316 sched.for_each_patch([&](u64 id_patch, Patch cur_p) {
317 shamlog_debug_ln("SPHLeapfrog", "patch : n", id_patch, "->", "Init h iteration");
318 if (merge_pdat.at(id_patch).or_element_cnt == 0)
319 shamlog_debug_ln(
320 "SPHLeapfrog",
321 "patch : n",
322 id_patch,
323 "->",
324 "is empty skipping h iteration");
325
326 PatchData &pdat_merge = merge_pdat.at(id_patch).data;
327
328 auto &hnew = hnew_field.get_buf(id_patch);
329 auto &omega = omega_field.get_buf(id_patch);
330 sycl::buffer<flt> eps_h = sycl::buffer<flt>(merge_pdat.at(id_patch).or_element_cnt);
331
332 sycl::range range_npart{merge_pdat.at(id_patch).or_element_cnt};
333
334 shamlog_debug_ln(
335 "SPHLeapfrog",
336 "merging -> original size :",
337 merge_pdat.at(id_patch).or_element_cnt,
338 "| merged :",
339 pdat_merge.get_obj_cnt());
340
342 sched.pdl, htol_up_tol, htol_up_iter);
343
344 h_iterator.iterate_smoothing_length(
345 shamsys::instance::get_compute_queue(),
346 merge_pdat.at(id_patch).or_element_cnt,
347 sph_gpart_mass,
348 *radix_trees[id_patch],
349 *cell_int_rads[id_patch],
350 pdat_merge,
351 *hnew,
352 *omega,
353 eps_h);
354 // write back h test
355 //*
356 shamsys::instance::get_compute_queue().submit([&](sycl::handler &cgh) {
357 auto h_new = hnew->template get_access<sycl::access::mode::read>(cgh);
358
359 auto acc_hpart = pdat_merge.get_field<flt>(ihpart)
360 .get_buf()
361 ->template get_access<sycl::access::mode::write>(cgh);
362
363 cgh.parallel_for(range_npart, [=](sycl::item<1> item) {
364 acc_hpart[item] = h_new[item];
365 });
366 });
367 //*/
368 });
369
370 write_back_merge_patches(sched, merge_pdat);
371
372 // hnew_field.to_map();
373 // omega_field.to_map();
374 }
375
376 } // namespace algs
377} // namespace models::sph
constexpr const char * eps_h
Epsilon h references (for h-iteration convergence).
constexpr const char * h_new
New smoothing length references (for h-iteration).
constexpr const char * omega
Grad-h correction factor \Omega.
sycl::queue & get_compute_queue(u32 id=0)
MPI scheduler.
float f32
Alias for float.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
The MPI scheduler.
PatchTree patch_tree
handle the tree structure of the patches
The radix tree.
Definition RadixTree.hpp:50
Define a field attached to a patch (example: FMM multipoles, hmax in SPH).
u32 get_field_idx(const std::string &field_name) const
Get the field id if matching name & type.
PatchCoordTransform< T > get_patch_transform() const
Get a PatchCoordTransform object that describes the conversion between patch coordinates and domain c...
Definition SimBox.hpp:285
header for PatchData related function and declaration
shambase::details::BasicStackEntry StackEntry
Alias for shambase::details::BasicStackEntry.
Patch object that contain generic patch information.
Definition Patch.hpp:33