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
28
30#include "shambackends/math.hpp"
33#include "shambackends/vec.hpp"
40#include "shammodels/sph/config/BCConfig.hpp" // Reuse boundary conditions from SPH
49#include <nlohmann/json.hpp>
52#include <variant>
53#include <vector>
54
55namespace shammodels::gsph {
56
63 template<class Tvec, template<class> class SPHKernel>
64 struct SolverConfig;
65
71 template<class Tvec>
72 struct SolverStatusVar;
73
79 template<class Tscal>
80 struct CFLConfig {
81 Tscal cfl_cour = 0.3;
82 Tscal cfl_force = 0.25;
83 };
84
85} // namespace shammodels::gsph
86
87template<class Tvec>
89 using Tscal = shambase::VecComponent<Tvec>;
90
91 Tscal time = 0;
92 Tscal dt = 0;
93};
94
95template<class Tvec, template<class> class SPHKernel>
97
98 using Tscal = shambase::VecComponent<Tvec>;
99 static constexpr u32 dim = shambase::VectorProperties<Tvec>::dimension;
100 using Kernel = SPHKernel<Tscal>;
101 using u_morton = u32;
102
104
105 static constexpr Tscal Rkern = Kernel::Rkern;
106
107 Tscal gpart_mass{0};
108
110
111 PatchSchedulerConfig scheduler_conf = {};
112
114 // Units Config
116
117 std::optional<shamunits::UnitSystem<Tscal>> unit_sys = {};
118
119 inline void set_units(shamunits::UnitSystem<Tscal> new_sys) { unit_sys = new_sys; }
120
121 inline Tscal get_constant_G() const {
122 if (!unit_sys) {
123 ON_RANK_0(logger::warn_ln("gsph::Config", "the unit system is not set"));
125 return ctes.G();
126 } else {
127 return shamunits::Constants<Tscal>{*unit_sys}.G();
128 }
129 }
130
132 // Units Config (END)
134
136 // Solver status variables
138
139 using SolverStatusVar = SolverStatusVar<Tvec>;
140 SolverStatusVar time_state;
141
142 inline void set_time(Tscal t) { time_state.time = t; }
143 inline void set_next_dt(Tscal dt) { time_state.dt = dt; }
144 inline Tscal get_time() const { return time_state.time; }
145 inline Tscal get_dt() const { return time_state.dt; }
146
148 // Solver status variables (END)
150
152 // Riemann Solver Config
154
155 using RiemannConfig = RiemannConfig<Tvec>;
156 RiemannConfig riemann_config;
157
158 inline void set_riemann_iterative(Tscal tol = Tscal{1e-6}, u32 max_iter = 20) {
159 riemann_config.set_iterative(tol, max_iter);
160 }
161
162 inline void set_riemann_hllc() { riemann_config.set_hllc(); }
163
165 // Riemann Solver Config (END)
167
169 // Reconstruction Config
171
172 using ReconstructConfig = ReconstructConfig<Tvec>;
173 ReconstructConfig reconstruct_config;
174
175 inline void set_reconstruct_piecewise_constant() {
176 reconstruct_config.set_piecewise_constant();
177 }
178
179 inline void set_reconstruct_muscl(
181 reconstruct_config.set_muscl(limiter);
182 }
183
184 inline bool requires_gradients() const { return reconstruct_config.requires_gradients(); }
185
187 // Reconstruction Config (END)
189
191 // EOS Config
193
194 using EOSConfig = shammodels::EOSConfig<Tvec>;
195 EOSConfig eos_config;
196
197 inline bool is_eos_adiabatic() const {
198 using T = typename EOSConfig::Adiabatic;
199 return bool(std::get_if<T>(&eos_config.config));
200 }
201
202 inline bool is_eos_isothermal() const {
203 using T = typename EOSConfig::Isothermal;
204 return bool(std::get_if<T>(&eos_config.config));
205 }
206
212 inline Tscal get_eos_gamma() const {
213 using Adiabatic = typename EOSConfig::Adiabatic;
214 using Polytropic = typename EOSConfig::Polytropic;
215 if (const auto *eos = std::get_if<Adiabatic>(&eos_config.config)) {
216 return eos->gamma;
217 } else if (const auto *eos = std::get_if<Polytropic>(&eos_config.config)) {
218 return eos->gamma;
219 }
220 return Tscal{1.4}; // Default for non-gamma EOS types
221 }
222
223 inline void set_eos_adiabatic(Tscal gamma) { eos_config.set_adiabatic(gamma); }
224
225 inline void set_eos_isothermal(Tscal cs) { eos_config.set_isothermal(cs); }
226
228 // EOS Config (END)
230
232 // Boundary Config
234
235 using BCConfig = shammodels::sph::BCConfig<Tvec>; // Reuse from SPH
236 BCConfig boundary_config;
237
238 inline void set_boundary_free() { boundary_config.set_free(); }
239 inline void set_boundary_periodic() { boundary_config.set_periodic(); }
240
251 inline void set_boundary_shearing_periodic(i32_3 shear_base, i32_3 shear_dir, Tscal speed) {
252 boundary_config.set_shearing_periodic(shear_base, shear_dir, speed);
253 }
254
256 // Boundary Config (END)
258
260 // External Force Config
262
264 ExtForceConfig ext_force_config{};
265
266 inline void add_ext_force_point_mass(Tscal central_mass, Tscal Racc) {
267 ext_force_config.add_point_mass(central_mass, Racc);
268 }
269
271 // External Force Config (END)
273
275 // Tree config
277
278 u32 tree_reduction_level = 3;
279 bool use_two_stage_search = true;
280
281 inline void set_tree_reduction_level(u32 level) { tree_reduction_level = level; }
282 inline void set_two_stage_search(bool enable) { use_two_stage_search = enable; }
283
285 // Tree config (END)
287
289 // Solver behavior config
291
293 Tscal htol_up_fine_cycle = 1.1;
294 Tscal epsilon_h = 1e-6;
297
299 // Solver behavior config (END)
301
302 inline bool has_field_uint() const { return is_eos_adiabatic(); }
303
304 inline void print_status() {
305 if (shamcomm::world_rank() != 0) {
306 return;
307 }
308 logger::raw_ln("----- GSPH Solver configuration -----");
309 logger::raw_ln("gpart_mass =", gpart_mass);
310 riemann_config.print_status();
311 reconstruct_config.print_status();
312 eos_config.print_status();
313 logger::raw_ln("--------------------------------------");
314 }
315
316 inline void check_config() const {
317 // Validate configuration (gpart_mass checked later at runtime)
318 // Only check gamma for adiabatic EOS types
319 if (is_eos_adiabatic() && get_eos_gamma() <= 1) {
320 shambase::throw_with_loc<std::runtime_error>("gamma must be > 1 for adiabatic gas");
321 }
322 }
323
324 inline void check_config_runtime() const {
325 // Validate configuration for runtime (called before simulation starts)
326 if (gpart_mass <= 0) {
328 "gpart_mass must be positive. Call set_particle_mass() before evolving.");
329 }
330 check_config();
331 }
332
333 void set_layout(shamrock::patch::PatchDataLayerLayout &pdl);
334 void set_ghost_layout(shamrock::patch::PatchDataLayerLayout &ghost_layout);
335};
336
337namespace shammodels::gsph {
338
339 template<class Tscal>
340 inline void to_json(nlohmann::json &j, const CFLConfig<Tscal> &p) {
341 j = nlohmann::json{
342 {"cfl_cour", p.cfl_cour},
343 {"cfl_force", p.cfl_force},
344 };
345 }
346
347 template<class Tscal>
348 inline void from_json(const nlohmann::json &j, CFLConfig<Tscal> &p) {
349 j.at("cfl_cour").get_to(p.cfl_cour);
350 j.at("cfl_force").get_to(p.cfl_force);
351 }
352
353 template<class Tvec>
354 inline void to_json(nlohmann::json &j, const SolverStatusVar<Tvec> &p) {
355 j = nlohmann::json{
356 {"time", p.time},
357 {"dt", p.dt},
358 };
359 }
360
361 template<class Tvec>
362 inline void from_json(const nlohmann::json &j, SolverStatusVar<Tvec> &p) {
363 using Tscal = typename SolverStatusVar<Tvec>::Tscal;
364 j.at("time").get_to<Tscal>(p.time);
365 j.at("dt").get_to<Tscal>(p.dt);
366 }
367
368 template<class Tvec, template<class> class SPHKernel>
369 inline void to_json(nlohmann::json &j, const SolverConfig<Tvec, SPHKernel> &p) {
371 using Tkernel = typename T::Kernel;
372
373 std::string kernel_id = shambase::get_type_name<Tkernel>();
374 std::string type_id = shambase::get_type_name<Tvec>();
375
376 j = nlohmann::json{
377 {"solver_type", "gsph"},
378 {"kernel_id", kernel_id},
379 {"type_id", type_id},
380 {"scheduler_config", p.scheduler_conf},
381 {"gpart_mass", p.gpart_mass},
382 {"cfl_config", p.cfl_config},
383 {"unit_sys", p.unit_sys},
384 {"time_state", p.time_state},
385 {"riemann_config", p.riemann_config},
386 {"reconstruct_config", p.reconstruct_config},
387 {"eos_config", p.eos_config},
388 {"boundary_config", p.boundary_config},
389 {"tree_reduction_level", p.tree_reduction_level},
390 {"use_two_stage_search", p.use_two_stage_search},
391 {"htol_up_coarse_cycle", p.htol_up_coarse_cycle},
392 {"htol_up_fine_cycle", p.htol_up_fine_cycle},
393 {"epsilon_h", p.epsilon_h},
394 {"h_iter_per_subcycles", p.h_iter_per_subcycles},
395 {"h_max_subcycles_count", p.h_max_subcycles_count},
396 };
397 }
398
399 template<class Tvec, template<class> class SPHKernel>
400 inline void from_json(const nlohmann::json &j, SolverConfig<Tvec, SPHKernel> &p) {
402 using Tkernel = typename T::Kernel;
403
404 std::string kernel_id = j.at("kernel_id").get<std::string>();
405 if (kernel_id != shambase::get_type_name<Tkernel>()) {
407 "Invalid kernel type: expected " + shambase::get_type_name<Tkernel>() + " but got "
408 + kernel_id);
409 }
410
411 std::string type_id = j.at("type_id").get<std::string>();
412 if (type_id != shambase::get_type_name<Tvec>()) {
414 "Invalid vector type: expected " + shambase::get_type_name<Tvec>() + " but got "
415 + type_id);
416 }
417
418 bool has_used_defaults = false;
419 bool has_updated_config = false;
420
421 auto _get_to_if_contains = [&](const std::string &key, auto &value) {
422 shamrock::get_to_if_contains(j, key, value, has_used_defaults);
423 };
424
425 _get_to_if_contains("scheduler_config", p.scheduler_conf);
426 _get_to_if_contains("gpart_mass", p.gpart_mass);
427 _get_to_if_contains("cfl_config", p.cfl_config);
428 _get_to_if_contains("unit_sys", p.unit_sys);
429 _get_to_if_contains("time_state", p.time_state);
430 _get_to_if_contains("riemann_config", p.riemann_config);
431 _get_to_if_contains("reconstruct_config", p.reconstruct_config);
432 _get_to_if_contains("eos_config", p.eos_config);
433 _get_to_if_contains("boundary_config", p.boundary_config);
434 _get_to_if_contains("tree_reduction_level", p.tree_reduction_level);
435 _get_to_if_contains("use_two_stage_search", p.use_two_stage_search);
436 _get_to_if_contains("htol_up_coarse_cycle", p.htol_up_coarse_cycle);
437 _get_to_if_contains("htol_up_fine_cycle", p.htol_up_fine_cycle);
438 _get_to_if_contains("epsilon_h", p.epsilon_h);
439 _get_to_if_contains("h_iter_per_subcycles", p.h_iter_per_subcycles);
440 _get_to_if_contains("h_max_subcycles_count", p.h_max_subcycles_count);
441
442 if (has_used_defaults || has_updated_config) {
443 if (shamcomm::world_rank() == 0) {
444 logger::info_ln(
445 "GSPH::SolverConfig",
446 shamrock::log_json_changes(p, j, has_used_defaults, has_updated_config));
447 }
448 }
449 }
450
451} // namespace shammodels::gsph
Header file describing a Node Instance.
MPI scheduler.
Configuration for reconstruction methods in GSPH.
Configuration for Riemann solvers in GSPH.
std::uint32_t u32
32 bit unsigned integer
A Compressed Leaf Bounding Volume Hierarchy (CLBVH) for neighborhood queries.
Defines a unit system.
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.
i32 world_rank()
Gives the rank of the current process in the MPI communicator.
Definition worldInfo.cpp:40
void get_to_if_contains(const nlohmann::json &j, const std::string &key, T &value, bool &has_used_defaults)
std::string log_json_changes(const nlohmann::json &j_current, const nlohmann::json &j, bool has_used_defaults, bool has_updated_config)
Shown the changes between two JSON objects to log config changes.
Contains traits and utilities for backend related types.
void raw_ln(Types... var2)
Prints a log message with multiple arguments followed by a newline.
Definition logs.hpp:90
void warn_ln(std::string module_name, Types... var2)
Prints a log message with multiple arguments followed by a newline.
Definition logs.hpp:133
sph kernels
shamphys::EOS_Config_Polytropic< Tscal > Polytropic
Polytropic equation of state configuration.
Definition EOSConfig.hpp:55
shamphys::EOS_Config_Isothermal< Tscal > Isothermal
Isothermal equation of state configuration.
Definition EOSConfig.hpp:58
shamphys::EOS_Config_Adiabatic< Tscal > Adiabatic
Adiabatic equation of state configuration.
Definition EOSConfig.hpp:52
The configuration for the CFL condition in GSPH.
Tscal cfl_force
CFL condition for the force.
Tscal cfl_cour
CFL condition for the courant factor.
Limiter
Slope limiter types for MUSCL reconstruction.
The configuration for a GSPH solver.
u32 h_iter_per_subcycles
Max iterations per subcycle.
void set_boundary_shearing_periodic(i32_3 shear_base, i32_3 shear_dir, Tscal speed)
Set shearing periodic boundary conditions.
Tscal get_eos_gamma() const
Get the adiabatic index (gamma) from the EOS config.
Tscal htol_up_coarse_cycle
Factor for neighbors search.
Tscal gpart_mass
The mass of each gas particle (must be set before use).
u32 h_max_subcycles_count
Max subcycles before crash.
Tscal htol_up_fine_cycle
Max smoothing length evolution per subcycle.
CFLConfig< Tscal > cfl_config
CFL configuration.
Tscal epsilon_h
Convergence criteria for smoothing length.
Solver status variables for GSPH.
Boundary conditions configuration.
Definition BCConfig.hpp:40
void set_free()
Set the boundary condition to free boundaries.
Definition BCConfig.hpp:98
Physical constants.
constexpr T G()
get the value of G in the current unit system units
Functions related to the MPI communicator.
#define ON_RANK_0(x)
Macro to execute code only on rank 0.
Definition worldInfo.hpp:73