Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
ModifierSplitPart.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
22template<class Tvec>
24 u32 nmax) {
25
26 if (n_split == 1) {
27 return parent->next_n(nmax);
28 }
29
30 if (nmax >= n_split && nmax != 0) {
31 nmax = nmax / n_split;
32 }
33
34 using namespace shamrock::patch;
35 PatchScheduler &sched = shambase::get_check_ref(context.sched);
36 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
37
38 shamrock::patch::PatchDataLayer original_pdat = parent->next_n(nmax);
39 u32 npart = original_pdat.get_obj_cnt();
40
41 u32 ixyz = sched.pdl_old().get_field_idx<Tvec>("xyz");
42 u32 ihpart = sched.pdl_old().get_field_idx<Tscal>("hpart");
43
44 std::vector<Tvec> xyz = original_pdat.get_field_buf_ref<Tvec>(ixyz).copy_to_stdvec();
45 std::vector<Tscal> hpart = original_pdat.get_field_buf_ref<Tscal>(ihpart).copy_to_stdvec();
46
47 PatchDataLayer tmp(sched.get_layout_ptr_old());
48
49 // perform the split and insert
50 for (u64 i = 0; i < n_split; i++) {
51 shamrock::patch::PatchDataLayer tmp_pdat = original_pdat.duplicate();
52
53 std::vector<u64> seeds = generator.next_n(npart);
54
55 std::vector<Tvec> new_xyz(npart);
56
57 for (u64 j = 0; j < npart; j++) {
58 std::mt19937_64 eng(seeds[j]);
59 new_xyz[j] = xyz[j] + hpart[j] * shamalgs::random::mock_gaussian_multidim<Tvec>(eng);
60 }
61
62 tmp_pdat.get_field<Tvec>(ixyz).override(new_xyz, npart);
63 tmp.insert_elements(tmp_pdat);
64 }
65
66 // filter particles outside the box
67 std::tuple<Tvec, Tvec> box = sched.get_box_volume<Tvec>();
68
69 PatchDataField<Tvec> &xyz_field = tmp.get_field<Tvec>(ixyz);
70 auto idx_to_remove = xyz_field.get_ids_where(
71 [bmin = std::get<0>(box), bmax = std::get<1>(box)](const Tvec *__restrict pos, u32 i) {
72 return !Patch::is_in_patch_converted(pos[i], bmin, bmax);
73 });
74 tmp.remove_ids(idx_to_remove, idx_to_remove.get_size());
75
76 // ammend smoothing length
77 // See
78 // https://github.com/danieljprice/phantom/blob/f6d5beea4db73f432bc2ca3eaa450320f2abee7a/src/utils/utils_splitmerge.f90#L64
79
80 Tscal h_scaling_fact = sycl::pow(Tscal(n_split), -1. / 3.) * h_scaling;
81
82 sham::DeviceBuffer<Tscal> &hpart_final = tmp.get_field_buf_ref<Tscal>(ihpart);
84 dev_sched->get_queue(),
86 sham::MultiRef{hpart_final},
87 hpart_final.get_size(),
88 [h_scaling_fact](u32 i, Tscal *__restrict hpart) {
89 hpart[i] *= h_scaling_fact;
90 });
91
92 return tmp;
93}
94
95using namespace shammath;
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
The MPI scheduler.
A buffer allocated in USM (Unified Shared Memory)
size_t get_size() const
Gets the number of elements in the buffer.
shamrock::patch::PatchDataLayer next_n(u32 nmax) override
This function generate patchdata with at most nmax per MPI ranks This function is always assumed as c...
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.
void remove_ids(const sham::DeviceBuffer< u32 > &indexes, u32 len)
remove some particles ids
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 & 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.