Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
Model.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
16
17#include "shambase/memory.hpp"
24#include <string>
25
26template<class Tvec, class TgridVec>
28
29 if (solver.solver_config.scheduler_conf.split_load_value == 0) {
31 "Scheduler load value should be greater than 0");
32 }
33
34 solver.init_required_fields();
35 // solver.init_ghost_layout();
36 ctx.init_sched(
37 solver.solver_config.scheduler_conf.split_load_value,
38 solver.solver_config.scheduler_conf.merge_load_value);
39
40 using namespace shamrock::patch;
41
42 PatchScheduler &sched = shambase::get_check_ref(ctx.sched);
43
44 // sched.add_root_patch();
45
46 // std::cout << "build local" << std::endl;
47 // sched.owned_patch_id = sched.patch_list.build_local();
48 // sched.patch_list.build_local_idx_map();
49 // sched.update_local_dtcnt_value();
50 // sched.update_local_load_value();
51
52 // must be done after init_sched to ensure time/dt edges are registered
53 solver.ensure_time_state_edges();
54
55 solver.init_solver_graph();
56}
57
58template<class Tvec, class TgridVec>
59void shammodels::basegodunov::Model<Tvec, TgridVec>::make_base_grid(
60 TgridVec bmin, TgridVec cell_size, u32_3 cell_count) {
61
62 if (cell_size.x() < Solver::Config::AMRBlock::Nside) {
64 "the x block size must be larger than {}, currently : cell_size = {}",
65 Solver::Config::AMRBlock::Nside,
66 cell_size));
67 }
68 if (cell_size.y() < Solver::Config::AMRBlock::Nside) {
70 "the y block size must be larger than {}, currently : cell_size = {}",
71 Solver::Config::AMRBlock::Nside,
72 cell_size));
73 }
74 if (cell_size.z() < Solver::Config::AMRBlock::Nside) {
76 "the z block size must be larger than {}, currently : cell_size = {}",
77 Solver::Config::AMRBlock::Nside,
78 cell_size));
79 }
80
81 modules::AMRSetup<Tvec, TgridVec> setup(ctx, solver.solver_config, solver.storage);
82 setup.make_base_grid(bmin, cell_size, {cell_count[0], cell_count[1], cell_count[2]});
83 return;
84
85 /* Old cell injection
86 shamrock::amr::AMRGrid<TgridVec, 3> grid(shambase::get_check_ref(ctx.sched));
87 grid.make_base_grid(bmin, cell_size, {cell_count.x(), cell_count.y(), cell_count.z()});
88
89 PatchScheduler &sched = shambase::get_check_ref(ctx.sched);
90
91 sched.owned_patch_id = sched.patch_list.build_local();
92 sched.patch_list.build_local_idx_map();
93 sched.update_local_load_value([&](shamrock::patch::Patch p) {
94 return sched.patch_data.owned_data.get(p.id_patch).get_obj_cnt();
95 });
96 sched.scheduler_step(true, true);
97 */
98}
99
100template<class Tvec, class TgridVec>
101void shammodels::basegodunov::Model<Tvec, TgridVec>::dump_vtk(std::string filename) {
102
103 StackEntry stack_loc{};
104 shamrock::LegacyVtkWriter writer(filename, true, shamrock::UnstructuredGrid);
105
106 try {
107
108 PatchScheduler &sched = shambase::get_check_ref(ctx.sched);
109
110 u32 block_size = Solver::AMRBlock::block_size;
111
112 u64 num_obj = sched.get_rank_count();
113
114 std::unique_ptr<sycl::buffer<TgridVec>> pos1 = sched.rankgather_field<TgridVec>(0);
115 std::unique_ptr<sycl::buffer<TgridVec>> pos2 = sched.rankgather_field<TgridVec>(1);
116
117 sycl::buffer<Tvec> pos_min_cell(num_obj * block_size);
118 sycl::buffer<Tvec> pos_max_cell(num_obj * block_size);
119
120 if (num_obj > 0) {
121
122 shamsys::instance::get_compute_queue().submit([&, block_size](sycl::handler &cgh) {
123 sycl::accessor acc_p1{shambase::get_check_ref(pos1), cgh, sycl::read_only};
124 sycl::accessor acc_p2{shambase::get_check_ref(pos2), cgh, sycl::read_only};
125 sycl::accessor cell_min{pos_min_cell, cgh, sycl::write_only, sycl::no_init};
126 sycl::accessor cell_max{pos_max_cell, cgh, sycl::write_only, sycl::no_init};
127
128 using Block = typename Solver::AMRBlock;
129
130 shambase::parallel_for(cgh, num_obj, "rescale cells", [=](u64 id_a) {
131 Tvec block_min = acc_p1[id_a].template convert<Tscal>();
132 Tvec block_max = acc_p2[id_a].template convert<Tscal>();
133
134 Tvec delta_cell = (block_max - block_min) / Block::side_size;
135#pragma unroll
136 for (u32 ix = 0; ix < Block::side_size; ix++) {
137#pragma unroll
138 for (u32 iy = 0; iy < Block::side_size; iy++) {
139#pragma unroll
140 for (u32 iz = 0; iz < Block::side_size; iz++) {
141 u32 i = Block::get_index({ix, iy, iz});
142 Tvec delta_val = delta_cell * Tvec{ix, iy, iz};
143 cell_min[id_a * block_size + i] = block_min + delta_val;
144 cell_max[id_a * block_size + i]
145 = block_min + (delta_cell) + delta_val;
146 }
147 }
148 }
149 });
150 });
151 }
152
153 writer.write_voxel_cells(pos_min_cell, pos_max_cell, num_obj * block_size);
154
155 writer.add_cell_data_section();
156
157 u32 fieldnum = 3;
158 if (solver.solver_config.is_dust_on()) {
159 u32 ndust = solver.solver_config.dust_config.ndust;
160 fieldnum += 2 * ndust;
161 }
162 writer.add_field_data_section(fieldnum);
163
164 std::unique_ptr<sycl::buffer<Tscal>> fields_rho = sched.rankgather_field<Tscal>(2);
165 writer.write_field("rho", fields_rho, num_obj * block_size);
166
167 std::unique_ptr<sycl::buffer<Tvec>> fields_vel = sched.rankgather_field<Tvec>(3);
168 writer.write_field("rhovel", fields_vel, num_obj * block_size);
169
170 std::unique_ptr<sycl::buffer<Tscal>> fields_eint = sched.rankgather_field<Tscal>(4);
171 writer.write_field("rhoetot", fields_eint, num_obj * block_size);
172
173 if (solver.solver_config.is_dust_on()) {
174 u32 ndust = solver.solver_config.dust_config.ndust;
175
176 shamrock::patch::PatchDataLayerLayout &pdl = solver.scheduler().pdl_old();
177 const u32 irho_dust = pdl.get_field_idx<Tscal>("rho_dust");
178 const u32 irhovel_dust = pdl.get_field_idx<Tvec>("rhovel_dust");
179
180 std::unique_ptr<sycl::buffer<Tscal>> fields_rho_dust
181 = sched.rankgather_field<Tscal>(irho_dust);
182 // writer.write_field("rho_dust", fields_rho_dust, ndust*num_obj*block_size);
183
184 if (fields_rho_dust) {
185 u32 nobj = fields_rho_dust->size();
186 u32 nsplit = ndust;
187
188 for (u32 off = 0; off < nsplit; off++) {
189
190 sycl::buffer<Tscal> partition(nobj / nsplit);
191
193 .submit([&, off, nsplit](sycl::handler &cgh) {
194 sycl::accessor out{partition, cgh, sycl::write_only, sycl::no_init};
195 sycl::accessor in{*fields_rho_dust, cgh, sycl::read_only};
196
197 shambase::parallel_for(
198 cgh, nobj / nsplit, "split field for dump", [=](u64 i) {
199 out[i] = in[i * nsplit + off];
200 });
201 })
202 .wait();
203
204 writer.write_field(
205 std::string("rho_dust") + std::to_string(off),
206 partition,
207 num_obj * block_size);
208 }
209 }
210
211 std::unique_ptr<sycl::buffer<Tvec>> fields_vel_dust
212 = sched.rankgather_field<Tvec>(irhovel_dust);
213 if (fields_vel_dust) {
214 u32 nobj = fields_vel_dust->size();
215 u32 nsplit = ndust;
216
217 for (u32 off = 0; off < nsplit; off++) {
218
219 sycl::buffer<Tvec> partition(nobj / nsplit);
220
222 .submit([&, off, nsplit](sycl::handler &cgh) {
223 sycl::accessor out{partition, cgh, sycl::write_only, sycl::no_init};
224 sycl::accessor in{*fields_vel_dust, cgh, sycl::read_only};
225
226 shambase::parallel_for(
227 cgh, nobj / nsplit, "split field for dump", [=](u64 i) {
228 out[i] = in[i * nsplit + off];
229 });
230 })
231 .wait();
232
233 writer.write_field(
234 std::string("rhovel_dust") + std::to_string(off),
235 partition,
236 num_obj * block_size);
237 }
238 }
239 }
240
241 } catch (std::runtime_error e) {
243 "Godunov",
244 "std::runtime_error catched while MPI file open -> unrecoverable\n what():\n",
245 e.what());
246 } catch (std::exception e) {
248 "Godunov",
249 "exception catched while MPI file open -> unrecoverable\n what():\n",
250 e.what());
251 } catch (...) {
252 logger::err_ln("Godunov", "something unknwon catched while MPI file open -> unrecoverable");
253 }
254}
255
Header file describing a Node Instance.
sycl::queue & get_compute_queue(u32 id=0)
MPI scheduler.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
The MPI scheduler.
void init()
Initialise the model and all the related data structures (patch scheduler in particular).
Definition Model.cpp:27
u32 get_field_idx(const std::string &field_name) const
Get the field id if matching name & type.
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
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:112
ExcptTypes make_except_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Create an exception with a message and a location.
void err_ln(std::string module_name, Types... var2)
Prints a log message with multiple arguments followed by a newline.
Definition logs.hpp:132
shambase::details::BasicStackEntry StackEntry
Alias for shambase::details::BasicStackEntry.