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"
37#include <nlohmann/json.hpp>
41#include <stdexcept>
42#include <variant>
43
45
49 struct DragConfig {
50 DragSolverMode drag_solver_config = NoDrag;
51 std::vector<f64> alphas;
52 bool enable_frictional_heating
53 = false; // 0 to turn off and 1 when all dissipation is deposited to the gas
54 };
55
56 struct DustConfig {
57 DustRiemannSolverMode dust_riemann_config = NoDust;
58 u32 ndust = 0;
59
60 inline bool is_dust_on() {
61 if (dust_riemann_config != NoDust) {
62
63 if (ndust == 0) {
65 "Dust is on with ndust == 0");
66 }
67 return true;
68 }
69 return false;
70 }
71 };
72
76 u32 npscal_gas = 0;
77
78 inline bool is_gas_passive_scalar_on() { return npscal_gas > 0; }
79 };
80
81 template<class Tvec>
83 using Tscal = shambase::VecComponent<Tvec>;
84 GravityMode gravity_mode = NoGravity;
85 bool analytical_gravity = false; // whether to use an external analytical gravity
86 Tscal tol = 1e-6;
87 inline Tscal get_tolerance() { return tol; }
88 inline bool is_gravity_on() { return gravity_mode != NoGravity; }
89 };
90
91 template<class Tvec, class TgridVec>
92 struct AMRMode {
93
94 using Tscal = shambase::VecComponent<Tvec>;
95
96 struct None {};
97
98 struct DensityBased {
99 Tscal crit_mass;
100 };
101
103 Tscal error_min;
104 Tscal error_max;
105 };
106
108 u32 N_J = 4;
109 Tscal T_0 = 10.;
110 };
111
112 struct ShearBased {
113 Tscal threshold;
114 };
115
116 using mode
117 = std::variant<None, DensityBased, PseudoGradientBased, JeansLengthBased, ShearBased>;
118
119 mode config = None{};
120
121 bool old_amr = true;
122
123 void set_refine_none() { config = None{}; }
124 void set_refine_density_based(Tscal crit_mass) { config = DensityBased{crit_mass}; }
125 void set_refine_pseudo_gradient_based(Tscal error_min, Tscal error_max) {
126 config = PseudoGradientBased{error_min, error_max};
127 }
128
129 void set_refine_jeans_length_based(u32 N_J, Tscal T_0) {
130 config = JeansLengthBased{N_J, T_0};
131 }
132
133 void set_refine_shear_based(Tscal thresh) { config = ShearBased{thresh}; }
134
135 bool need_level_zero_compute() { return !old_amr; }
136 bool need_amr_level_compute() { return !old_amr; }
137 };
138
139 struct BCConfig {
140 enum class GhostType { Periodic = 0, Reflective = 1, Outflow = 2 };
141
142 GhostType ghost_type_x = GhostType::Periodic;
143 GhostType ghost_type_y = GhostType::Periodic;
144 GhostType ghost_type_z = GhostType::Periodic;
145
146 GhostType get_x() const { return ghost_type_x; }
147 GhostType get_y() const { return ghost_type_y; }
148 GhostType get_z() const { return ghost_type_z; }
149
150 void set_x(GhostType ghost_type) { ghost_type_x = ghost_type; }
151 void set_y(GhostType ghost_type) { ghost_type_y = ghost_type; }
152 void set_z(GhostType ghost_type) { ghost_type_z = ghost_type; }
153 };
154
155 template<class Tvec, class TgridVec>
156 struct SolverConfig;
157
158}; // namespace shammodels::basegodunov
159
160template<class Tvec, class TgridVec>
162
163 using Tscal = shambase::VecComponent<Tvec>;
164
165 Tscal eos_gamma = 5. / 3.;
166
167 Tscal grid_coord_to_pos_fact = 1;
168
169 static constexpr u32 NsideBlockPow = 1;
171
172 inline void set_eos_gamma(Tscal gamma) { eos_gamma = gamma; }
173
174 RiemannSolverMode riemann_config = HLL;
175 SlopeMode slope_config = VanLeer_sym;
176 bool face_half_time_interpolation = true;
177
178 inline bool should_compute_rho_mean() { return is_gravity_on() && is_boundary_periodic(); }
179
181 // Dust config
183
184 DustConfig dust_config{};
185 DragConfig drag_config{};
186
187 inline bool is_dust_on() { return dust_config.is_dust_on(); }
188 // get alpha values from user
189 // alphas is the dust collision rate (the inverse of the stopping time)
190 inline void set_alphas_static(f32 alpha_values) {
191 StackEntry stack_lock{};
192 drag_config.alphas.push_back(alpha_values);
193 }
194
196 // Dust config (END)
198
199 BCConfig bc_config{};
200
202 // Gas passive scalars config
204
205 PassiveScalarGasConfig npscal_gas_config{};
206
207 inline bool is_gas_passive_scalar_on() { return npscal_gas_config.is_gas_passive_scalar_on(); }
209 // Gas passive scalars config (END)
211
213 // Gravity config
215 inline Tscal get_constant_G() {
216 if (!unit_sys) {
217 ON_RANK_0(logger::warn_ln("amr::Config", "the unit system is not set"));
219 return ctes.G();
220 } else {
222 }
223 }
224 inline bool is_boundary_periodic() { return true; }
225 GravityConfig<Tvec> gravity_config{};
226 inline Tscal get_constant_4piG() {
227 auto scal_G = get_constant_G();
228 return 4 * M_PI * scal_G;
229 }
230 inline Tscal get_grav_tol() { return gravity_config.get_tolerance(); }
231 inline bool is_gravity_on() { return gravity_config.is_gravity_on(); }
232 inline bool is_coordinate_field_required() { return gravity_config.analytical_gravity; }
233
235 // Gravity config (END)
237
240
242 // Units Config
244
246 std::optional<shamunits::UnitSystem<Tscal>> unit_sys = {};
247
249 inline void set_units(shamunits::UnitSystem<Tscal> new_sys) { unit_sys = new_sys; }
251 // Units Config (END)
253
254 PatchSchedulerConfig scheduler_conf = {};
255
257 // CFL Configuration (config)
259
260 Tscal Csafe = 0.9;
261
263 // CFL Configuration (END)
265
266 inline void check_config() {
267 if (grid_coord_to_pos_fact <= 0) {
269 "grid_coord_to_pos_fact must be > 0, got {}", grid_coord_to_pos_fact));
270 }
271
272 if (is_dust_on()) {
273 ON_RANK_0(logger::warn_ln("Ramses::SolverConfig", "Dust is experimental"));
274 }
275
276 if (is_gravity_on()) {
277 ON_RANK_0(logger::warn_ln("Ramses::SolverConfig", "Self gravity is experimental"));
278 u32 mode = gravity_config.gravity_mode;
279
281 shambase::format(
282 "self gravity mode is not enabled but gravity mode is set to {} (> 0 whith 0 "
283 "== "
284 "NoGravity mode)",
285 mode));
286 }
287
288 if (!(eos_gamma > 1.0)) {
290 shambase::format("Gamma must be > 1, currently Gamma = {}", eos_gamma));
291 }
292
293 if (is_gas_passive_scalar_on()) {
294 ON_RANK_0(logger::warn_ln("Ramses::SolverConfig", "Passive scalars are experimental"));
296 shambase::format(
297 "gas passive scalars mode is not enabled but gas passive scalars mode is set "
298 "to {}"
299 "> 0",
300 npscal_gas_config.npscal_gas));
301 }
302
303 if (!amr_mode.old_amr) {
304 shamrock::experimental_feature_check("new AMR is experimental");
305 }
306 }
307
308 void set_layout(shamrock::patch::PatchDataLayerLayout &pdl);
309};
310
311namespace shammodels::basegodunov {
312
313 inline void to_json(nlohmann::json &j, const BCConfig::GhostType &e) {
314 switch (e) {
315 case BCConfig::GhostType::Periodic : j = "periodic"; break;
316 case BCConfig::GhostType::Reflective: j = "reflective"; break;
317 case BCConfig::GhostType::Outflow : j = "outflow"; break;
318 default:
320 "Invalid BCConfig::GhostType value: " + std::to_string(static_cast<int>(e)));
321 }
322 }
323
324 inline void from_json(const nlohmann::json &j, BCConfig::GhostType &e) {
325 const std::string type = j.get<std::string>();
326 if (type == "periodic") {
327 e = BCConfig::GhostType::Periodic;
328 } else if (type == "reflective") {
329 e = BCConfig::GhostType::Reflective;
330 } else if (type == "outflow") {
331 e = BCConfig::GhostType::Outflow;
332 } else {
334 "Invalid BCConfig::GhostType value: " + type);
335 }
336 }
337
338 inline void to_json(nlohmann::json &j, const BCConfig &p) {
339 j = nlohmann::json{
340 {"ghost_type_x", p.ghost_type_x},
341 {"ghost_type_y", p.ghost_type_y},
342 {"ghost_type_z", p.ghost_type_z}};
343 }
344
345 inline void from_json(const nlohmann::json &j, BCConfig &p) {
346 j.at("ghost_type_x").get_to(p.ghost_type_x);
347 j.at("ghost_type_y").get_to(p.ghost_type_y);
348 j.at("ghost_type_z").get_to(p.ghost_type_z);
349 }
350
351 inline void to_json(nlohmann::json &j, const DragConfig &p) {
352 j = nlohmann::json{
353 {"drag_solver", p.drag_solver_config},
354 {"alphas", p.alphas},
355 {"enable_frictional_heating", p.enable_frictional_heating}};
356 }
357
358 inline void from_json(const nlohmann::json &j, DragConfig &p) {
359 j.at("drag_solver").get_to(p.drag_solver_config);
360 j.at("alphas").get_to(p.alphas);
361 j.at("enable_frictional_heating").get_to(p.enable_frictional_heating);
362 }
363
364 template<class Tvec, class TgridVec>
365 inline void amr_config_to_json(nlohmann::json &j, const AMRMode<Tvec, TgridVec> &p) {
366 using AMR = AMRMode<Tvec, TgridVec>;
367
368 if (std::holds_alternative<typename AMR::None>(p.config)) {
369 j = {{"type", "none"}};
370 } else if (const auto *cfg = std::get_if<typename AMR::DensityBased>(&p.config)) {
371 j = {{"type", "density_based"}, {"crit_mass", cfg->crit_mass}};
372 } else if (const auto *cfg = std::get_if<typename AMR::PseudoGradientBased>(&p.config)) {
373 j
374 = {{"type", "pseudo_gradient_based"},
375 {"error_min", cfg->error_min},
376 {"error_max", cfg->error_max}};
377 } else if (const auto *cfg = std::get_if<typename AMR::JeansLengthBased>(&p.config)) {
378 j = {{"type", "jeans_length_based"}, {"N_J", cfg->N_J}, {"T_0", cfg->T_0}};
379 } else if (const auto *cfg = std::get_if<typename AMR::ShearBased>(&p.config)) {
380 j = {{"type", "shear_based"}, {"threshold", cfg->threshold}};
381 } else {
383 }
384 }
385
386 template<class Tvec, class TgridVec>
387 inline void amr_config_from_json(const nlohmann::json &j, AMRMode<Tvec, TgridVec> &p) {
388 using Tscal = shambase::VecComponent<Tvec>;
389
390 const std::string type = j.at("type").get<std::string>();
391 if (type == "none") {
392 p.set_refine_none();
393 } else if (type == "density_based") {
394 p.set_refine_density_based(j.at("crit_mass").get<Tscal>());
395 } else if (type == "pseudo_gradient_based") {
396 p.set_refine_pseudo_gradient_based(
397 j.at("error_min").get<Tscal>(), j.at("error_max").get<Tscal>());
398 } else if (type == "jeans_length_based") {
399 p.set_refine_jeans_length_based(j.at("N_J").get<u32>(), j.at("T_0").get<Tscal>());
400 } else if (type == "shear_based") {
401 p.set_refine_shear_based(j.at("threshold").get<Tscal>());
402 } else {
403 shambase::throw_with_loc<std::runtime_error>("Invalid AMR mode type: " + type);
404 }
405 }
406
407 template<class Tvec, class TgridVec>
408 inline void to_json(nlohmann::json &j, const AMRMode<Tvec, TgridVec> &p) {
409 nlohmann::json config_j;
410 amr_config_to_json(config_j, p);
411 j = nlohmann::json{{"old_amr", p.old_amr}, {"config", config_j}};
412 }
413
414 template<class Tvec, class TgridVec>
415 inline void from_json(const nlohmann::json &j, AMRMode<Tvec, TgridVec> &p) {
416 j.at("old_amr").get_to(p.old_amr);
417 amr_config_from_json(j.at("config"), p);
418 }
419
426 template<class Tvec, class TgridVec>
427 void to_json(nlohmann::json &j, const SolverConfig<Tvec, TgridVec> &p);
434 template<class Tvec, class TgridVec>
435 void from_json(const nlohmann::json &j, SolverConfig<Tvec, TgridVec> &p);
436
437} // 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.
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:133
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