Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
SolverConfig.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#pragma once
11
23
25#include "shambase/string.hpp"
26#include "shambackends/vec.hpp"
27#include "shamcomm/logs.hpp"
38#include <nlohmann/json.hpp>
42#include <stdexcept>
43#include <variant>
44
46
50 struct DragConfig {
51 DragSolverMode drag_solver_config = NoDrag;
52 std::vector<f64> alphas;
53 bool enable_frictional_heating
54 = false; // 0 to turn off and 1 when all dissipation is deposited to the gas
55 };
56
57 struct DustConfig {
58 DustRiemannSolverMode dust_riemann_config = NoDust;
59 u32 ndust = 0;
60
61 inline bool is_dust_on() {
62 if (dust_riemann_config != NoDust) {
63
64 if (ndust == 0) {
66 "Dust is on with ndust == 0");
67 }
68 return true;
69 }
70 return false;
71 }
72 };
73
77 u32 npscal_gas = 0;
78
79 inline bool is_gas_passive_scalar_on() { return npscal_gas > 0; }
80 };
81
82 template<class Tvec>
84 using Tscal = shambase::VecComponent<Tvec>;
85 GravityMode gravity_mode = NoGravity;
86 bool analytical_gravity = false; // whether to use an external analytical gravity
87 Tscal tol = 1e-6;
88 inline Tscal get_tolerance() { return tol; }
89 inline bool is_gravity_on() { return gravity_mode != NoGravity; }
90 };
91
92 template<class Tvec, class TgridVec>
93 struct AMRMode {
94
95 using Tscal = shambase::VecComponent<Tvec>;
96
97 struct None {};
98
99 struct DensityBased {
100 Tscal crit_mass;
101 };
102
104 Tscal error_min;
105 Tscal error_max;
106 };
107
109 u32 N_J = 4;
110 Tscal T_0 = 10.;
111 };
112
113 struct ShearBased {
114 Tscal threshold;
115 };
116
117 using mode
118 = std::variant<None, DensityBased, PseudoGradientBased, JeansLengthBased, ShearBased>;
119
120 mode config = None{};
121
122 bool old_amr = true;
123
124 void set_refine_none() { config = None{}; }
125 void set_refine_density_based(Tscal crit_mass) { config = DensityBased{crit_mass}; }
126 void set_refine_pseudo_gradient_based(Tscal error_min, Tscal error_max) {
127 config = PseudoGradientBased{error_min, error_max};
128 }
129
130 void set_refine_jeans_length_based(u32 N_J, Tscal T_0) {
131 config = JeansLengthBased{N_J, T_0};
132 }
133
134 void set_refine_shear_based(Tscal thresh) { config = ShearBased{thresh}; }
135
136 bool need_level_zero_compute() { return !old_amr; }
137 bool need_amr_level_compute() { return !old_amr; }
138 };
139
140 struct BCConfig {
141 enum class GhostType { Periodic = 0, Reflective = 1, Outflow = 2 };
142
143 GhostType ghost_type_x = GhostType::Periodic;
144 GhostType ghost_type_y = GhostType::Periodic;
145 GhostType ghost_type_z = GhostType::Periodic;
146
147 GhostType get_x() const { return ghost_type_x; }
148 GhostType get_y() const { return ghost_type_y; }
149 GhostType get_z() const { return ghost_type_z; }
150
151 void set_x(GhostType ghost_type) { ghost_type_x = ghost_type; }
152 void set_y(GhostType ghost_type) { ghost_type_y = ghost_type; }
153 void set_z(GhostType ghost_type) { ghost_type_z = ghost_type; }
154 };
155
156 template<class Tvec, class TgridVec>
157 struct SolverConfig;
158
159}; // namespace shammodels::basegodunov
160
161template<class Tvec, class TgridVec>
163
164 using Tscal = shambase::VecComponent<Tvec>;
165
166 Tscal eos_gamma = 5. / 3.;
167
168 Tscal grid_coord_to_pos_fact = 1;
169
170 static constexpr u32 NsideBlockPow = 1;
172
173 inline void set_eos_gamma(Tscal gamma) { eos_gamma = gamma; }
174
175 RiemannSolverMode riemann_config = HLL;
176 SlopeMode slope_config = VanLeer_sym;
177 bool face_half_time_interpolation = true;
178
179 AMRInterpMode amr_interp_mode = FIRST_ORDER;
180
181 inline bool should_compute_rho_mean() { return is_gravity_on() && is_boundary_periodic(); }
182
184 // Dust config
186
187 DustConfig dust_config{};
188 DragConfig drag_config{};
189
190 inline bool is_dust_on() { return dust_config.is_dust_on(); }
191 // get alpha values from user
192 // alphas is the dust collision rate (the inverse of the stopping time)
193 inline void set_alphas_static(f32 alpha_values) {
194 StackEntry stack_lock{};
195 drag_config.alphas.push_back(alpha_values);
196 }
197
199 // Dust config (END)
201
202 BCConfig bc_config{};
203
205 // Gas passive scalars config
207
208 PassiveScalarGasConfig npscal_gas_config{};
209
210 inline bool is_gas_passive_scalar_on() { return npscal_gas_config.is_gas_passive_scalar_on(); }
212 // Gas passive scalars config (END)
214
216 // Gravity config
218 inline Tscal get_constant_G() {
219 if (!unit_sys) {
220 ON_RANK_0(logger::warn_ln("amr::Config", "the unit system is not set"));
222 return ctes.G();
223 } else {
225 }
226 }
227 inline bool is_boundary_periodic() { return true; }
228 GravityConfig<Tvec> gravity_config{};
229 inline Tscal get_constant_4piG() {
230 auto scal_G = get_constant_G();
231 return 4 * M_PI * scal_G;
232 }
233 inline Tscal get_grav_tol() { return gravity_config.get_tolerance(); }
234 inline bool is_gravity_on() { return gravity_config.is_gravity_on(); }
235 inline bool is_coordinate_field_required() { return gravity_config.analytical_gravity; }
236
238 // Gravity config (END)
240
243
245 // Units Config
247
249 std::optional<shamunits::UnitSystem<Tscal>> unit_sys = {};
250
252 inline void set_units(shamunits::UnitSystem<Tscal> new_sys) { unit_sys = new_sys; }
254 // Units Config (END)
256
257 PatchSchedulerConfig scheduler_conf = {};
258
260 // CFL Configuration (config)
262
263 Tscal Csafe = 0.9;
264
266 // CFL Configuration (END)
268
269 inline void check_config() {
270 if (grid_coord_to_pos_fact <= 0) {
272 sham::format("grid_coord_to_pos_fact must be > 0, got {}", grid_coord_to_pos_fact));
273 }
274
275 if (is_dust_on()) {
276 ON_RANK_0(logger::warn_ln("Ramses::SolverConfig", "Dust is experimental"));
277 }
278
279 if (is_gravity_on()) {
280 ON_RANK_0(logger::warn_ln("Ramses::SolverConfig", "Self gravity is experimental"));
281 u32 mode = gravity_config.gravity_mode;
282
284 sham::format(
285 "self gravity mode is not enabled but gravity mode is set to {} (> 0 whith 0 "
286 "== "
287 "NoGravity mode)",
288 mode));
289 }
290
291 if (!(eos_gamma > 1.0)) {
293 sham::format("Gamma must be > 1, currently Gamma = {}", eos_gamma));
294 }
295
296 if (is_gas_passive_scalar_on()) {
297 ON_RANK_0(logger::warn_ln("Ramses::SolverConfig", "Passive scalars are experimental"));
299 sham::format(
300 "gas passive scalars mode is not enabled but gas passive scalars mode is set "
301 "to {}"
302 "> 0",
303 npscal_gas_config.npscal_gas));
304 }
305
306 if (!amr_mode.old_amr) {
307 shamrock::experimental_feature_check("new AMR is experimental");
308 }
309 }
310
311 void set_layout(shamrock::patch::PatchDataLayerLayout &pdl);
312};
313
314namespace shammodels::basegodunov {
315
316 inline void to_json(nlohmann::json &j, const BCConfig::GhostType &e) {
317 switch (e) {
318 case BCConfig::GhostType::Periodic : j = "periodic"; break;
319 case BCConfig::GhostType::Reflective: j = "reflective"; break;
320 case BCConfig::GhostType::Outflow : j = "outflow"; break;
321 default:
323 "Invalid BCConfig::GhostType value: " + std::to_string(static_cast<int>(e)));
324 }
325 }
326
327 inline void from_json(const nlohmann::json &j, BCConfig::GhostType &e) {
328 const std::string type = j.get<std::string>();
329 if (type == "periodic") {
330 e = BCConfig::GhostType::Periodic;
331 } else if (type == "reflective") {
332 e = BCConfig::GhostType::Reflective;
333 } else if (type == "outflow") {
334 e = BCConfig::GhostType::Outflow;
335 } else {
337 "Invalid BCConfig::GhostType value: " + type);
338 }
339 }
340
341 inline void to_json(nlohmann::json &j, const BCConfig &p) {
342 j = nlohmann::json{
343 {"ghost_type_x", p.ghost_type_x},
344 {"ghost_type_y", p.ghost_type_y},
345 {"ghost_type_z", p.ghost_type_z}};
346 }
347
348 inline void from_json(const nlohmann::json &j, BCConfig &p) {
349 j.at("ghost_type_x").get_to(p.ghost_type_x);
350 j.at("ghost_type_y").get_to(p.ghost_type_y);
351 j.at("ghost_type_z").get_to(p.ghost_type_z);
352 }
353
354 inline void to_json(nlohmann::json &j, const DragConfig &p) {
355 j = nlohmann::json{
356 {"drag_solver", p.drag_solver_config},
357 {"alphas", p.alphas},
358 {"enable_frictional_heating", p.enable_frictional_heating}};
359 }
360
361 inline void from_json(const nlohmann::json &j, DragConfig &p) {
362 j.at("drag_solver").get_to(p.drag_solver_config);
363 j.at("alphas").get_to(p.alphas);
364 j.at("enable_frictional_heating").get_to(p.enable_frictional_heating);
365 }
366
367 template<class Tvec, class TgridVec>
368 inline void amr_config_to_json(nlohmann::json &j, const AMRMode<Tvec, TgridVec> &p) {
369 using AMR = AMRMode<Tvec, TgridVec>;
370
371 if (std::holds_alternative<typename AMR::None>(p.config)) {
372 j = {{"type", "none"}};
373 } else if (const auto *cfg = std::get_if<typename AMR::DensityBased>(&p.config)) {
374 j = {{"type", "density_based"}, {"crit_mass", cfg->crit_mass}};
375 } else if (const auto *cfg = std::get_if<typename AMR::PseudoGradientBased>(&p.config)) {
376 j
377 = {{"type", "pseudo_gradient_based"},
378 {"error_min", cfg->error_min},
379 {"error_max", cfg->error_max}};
380 } else if (const auto *cfg = std::get_if<typename AMR::JeansLengthBased>(&p.config)) {
381 j = {{"type", "jeans_length_based"}, {"N_J", cfg->N_J}, {"T_0", cfg->T_0}};
382 } else if (const auto *cfg = std::get_if<typename AMR::ShearBased>(&p.config)) {
383 j = {{"type", "shear_based"}, {"threshold", cfg->threshold}};
384 } else {
386 }
387 }
388
389 template<class Tvec, class TgridVec>
390 inline void amr_config_from_json(const nlohmann::json &j, AMRMode<Tvec, TgridVec> &p) {
391 using Tscal = shambase::VecComponent<Tvec>;
392
393 const std::string type = j.at("type").get<std::string>();
394 if (type == "none") {
395 p.set_refine_none();
396 } else if (type == "density_based") {
397 p.set_refine_density_based(j.at("crit_mass").get<Tscal>());
398 } else if (type == "pseudo_gradient_based") {
399 p.set_refine_pseudo_gradient_based(
400 j.at("error_min").get<Tscal>(), j.at("error_max").get<Tscal>());
401 } else if (type == "jeans_length_based") {
402 p.set_refine_jeans_length_based(j.at("N_J").get<u32>(), j.at("T_0").get<Tscal>());
403 } else if (type == "shear_based") {
404 p.set_refine_shear_based(j.at("threshold").get<Tscal>());
405 } else {
406 shambase::throw_with_loc<std::runtime_error>("Invalid AMR mode type: " + type);
407 }
408 }
409
410 template<class Tvec, class TgridVec>
411 inline void to_json(nlohmann::json &j, const AMRMode<Tvec, TgridVec> &p) {
412 nlohmann::json config_j;
413 amr_config_to_json(config_j, p);
414 j = nlohmann::json{{"old_amr", p.old_amr}, {"config", config_j}};
415 }
416
417 template<class Tvec, class TgridVec>
418 inline void from_json(const nlohmann::json &j, AMRMode<Tvec, TgridVec> &p) {
419 j.at("old_amr").get_to(p.old_amr);
420 amr_config_from_json(j.at("config"), p);
421 }
422
429 template<class Tvec, class TgridVec>
430 void to_json(nlohmann::json &j, const SolverConfig<Tvec, TgridVec> &p);
437 template<class Tvec, class TgridVec>
438 void from_json(const nlohmann::json &j, SolverConfig<Tvec, TgridVec> &p);
439
440} // namespace shammodels::basegodunov
utility to manipulate AMR blocks
MPI scheduler.
float f32
Alias for float.
std::uint32_t u32
32 bit unsigned integer
Defines a unit system.
AMR (refinement) prolongation mode enum + json serialization/deserialization.
Drag solver mode enum + json serialization/deserialization.
Dust Riemann solver mode enum + json serialization/deserialization.
Gravity mode enum + json serialization/deserialization.
Riemann solver mode enum + json serialization/deserialization.
Slope mode enum + json serialization/deserialization.
This header file contains utility functions related to exception handling in the code.
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
ExcptTypes make_except_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Create an exception with a message and a location.
void throw_unimplemented(SourceLocation loc=SourceLocation{})
Throw a std::runtime_error saying that the function is unimplemented.
namespace for the basegodunov model
DustRiemannSolverMode
Dust Riemann solver mode enum.
@ NoDust
No dust, so no Riemann solver is used.
SlopeMode
Slope limiter modes.
void experimental_feature_check(const std::string &message, SourceLocation loc=SourceLocation{})
Check if experimental features are enabled, if not throw with the given message.
void warn_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.
utility class to handle AMR blocks
Definition AMRBlock.hpp:35
alphas is the dust collision rate (the inverse of the stopping time)
Npscal_gas is the number of gas passive scalars.
AMRMode< Tvec, TgridVec > amr_mode
AMR refinement mode.
std::optional< shamunits::UnitSystem< Tscal > > unit_sys
The unit system of the simulation.
void set_units(shamunits::UnitSystem< Tscal > new_sys)
Set the unit system of the simulation.
Physical constants.
constexpr T G()
get the value of G in the current unit system units
#define ON_RANK_0(x)
Macro to execute code only on rank 0.
Definition worldInfo.hpp:73