Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
GeneratorMCDisc.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
17
20#include "shamalgs/random.hpp"
23
24template<class Tvec, template<class> class SPHKernel>
25auto shammodels::sph::modules::GeneratorMCDisc<Tvec, SPHKernel>::DiscIterator::next(u64 seed)
26 -> DiscOutput {
27
28 std::mt19937_64 eng_local(seed); // ensure that 1 part = 1 random draw
29
30 Tscal fmax = f_func(r_out);
31
32 auto find_r = [&]() {
33 while (true) {
34 Tscal u2 = shamalgs::primitives::mock_value<Tscal>(eng_local, 0, fmax);
35 Tscal r = shamalgs::primitives::mock_value<Tscal>(eng_local, r_in, r_out);
36 if (u2 < f_func(r)) {
37 return r;
38 }
39 }
40 };
41
42 auto theta = shamalgs::primitives::mock_value<Tscal>(eng_local, 0, _2pi);
43 auto Gauss = shamalgs::random::mock_gaussian<Tscal>(eng_local);
44
45 // depends on sigma profile
46 Tscal r = find_r();
47 Tscal sigma = sigma_profile(r);
48
49 // depends on H profile & sigma profile (through r)
50 Tscal H = H_profile(r);
51 Tscal z = H * Gauss;
52
53 auto pos = sycl::vec<Tscal, 3>{r * sycl::cos(theta), r * sycl::sin(theta), z};
54
55 // extrapolate the density from sigma profile
56 Tscal fs = 1;
57 Tscal rho = (sigma * fs) * sycl::exp(-z * z / (2 * H * H));
58
59 DiscOutput out{.pos = pos, .rho = rho};
60
61 // increase counter + check if finished
62 current_index++;
63 if (current_index == Npart) {
64 done = true;
65 }
66
67 return out;
68}
69
70template<class Tvec, template<class> class SPHKernel>
74
75template<class Tvec, template<class> class SPHKernel>
77 u32 nmax) {
78
79 using namespace shamrock::patch;
80 PatchScheduler &sched = shambase::get_check_ref(context.sched);
81
82 std::vector<DiscOutput> pos_data;
83
84 // Fill pos_data if the scheduler has some patchdata in this rank
85 if (!generator.is_done()) {
86 u64 loc_gen_count = nmax;
87 pos_data = generator.next_n(loc_gen_count);
88 }
89
90 // extract data from disc output
91 std::vector<Tvec> vec_pos;
92 std::vector<Tscal> vec_rho;
93
94 vec_pos.reserve(pos_data.size());
95 vec_rho.reserve(pos_data.size());
96
97 for (DiscOutput o : pos_data) {
98 vec_pos.push_back(o.pos);
99 vec_rho.push_back(o.rho);
100 }
101
102 // compute the hpart from the rho
103 std::vector<Tscal> vec_h;
104 vec_h.reserve(pos_data.size());
105 for (Tscal rho : vec_rho) {
106 vec_h.push_back(shamrock::sph::h_rho(pmass, rho, Kernel::hfactd) * init_h_factor);
107 }
108
109 // compute velocities
110 std::vector<Tvec> vec_vel;
111 vec_vel.reserve(pos_data.size());
112 for (size_t i = 0; i < vec_pos.size(); i++) {
113 Tvec vel = vel_profile(vec_pos[i]);
114 vec_vel.push_back(vel);
115 }
116
117 // compute the cs
118 bool need_cs = solver_config.is_eos_locally_isothermal();
119
120 std::vector<Tscal> vec_cs;
121 if (need_cs) {
122 if (!cs_profile) {
124 "With this EOS you need to provide a cs_profile");
125 }
126 vec_cs.reserve(pos_data.size());
127 for (size_t i = 0; i < vec_pos.size(); i++) {
128 Tscal cs = cs_profile(vec_pos[i]);
129 vec_cs.push_back(cs);
130 }
131 }
132
133 // Make a patchdata from pos_data
134 PatchDataLayer tmp(sched.get_layout_ptr_old());
135 if (!pos_data.empty()) {
136 tmp.resize(pos_data.size());
137 tmp.fields_raz();
138
139 {
140 u32 len = pos_data.size();
142 = tmp.get_field<Tvec>(sched.pdl_old().get_field_idx<Tvec>("xyz"));
143 sycl::buffer<Tvec> buf(vec_pos.data(), len);
144 f.override(buf, len);
145 }
146
147 {
148 u32 len = pos_data.size();
150 = tmp.get_field<Tvec>(sched.pdl_old().get_field_idx<Tvec>("vxyz"));
151 sycl::buffer<Tvec> buf(vec_vel.data(), len);
152 f.override(buf, len);
153 }
154 {
155 u32 len = vec_pos.size();
157 = tmp.get_field<Tscal>(sched.pdl_old().get_field_idx<Tscal>("hpart"));
158 sycl::buffer<Tscal> buf(vec_h.data(), len);
159 f.override(buf, len);
160 }
161
162 if (need_cs) {
163 u32 len = vec_pos.size();
165 = tmp.get_field<Tscal>(sched.pdl_old().get_field_idx<Tscal>("soundspeed"));
166 sycl::buffer<Tscal> buf(vec_cs.data(), len);
167 f.override(buf, len);
168 }
169 }
170
171 return tmp;
172}
173
174using namespace shammath;
178
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
The MPI scheduler.
shamrock::patch::PatchDataLayer next_n(u32 nmax)
This function generate patchdata with at most nmax per MPI ranks This function is always assumed as c...
bool is_done()
This function return true if the setup is done.
PatchDataLayer container class, the layout is described in patchdata_layout.
Class holding the value of numerous constants generated from the following source.
T mock_value(Engine &eng, T min_bound, T max_bound)
Generates a random mock value within specified bounds.
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
ExcptTypes make_except_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Create an exception with a message and a location.
namespace for math utility
Definition AABB.hpp:26