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
20
23#include "config/AVConfig.hpp"
24#include "config/BCConfig.hpp"
25#include "shambackends/math.hpp"
28#include "shambackends/vec.hpp"
48#include <stdexcept>
49#include <variant>
50#include <vector>
51
52namespace shammodels::sph {
53
60 template<class Tvec, template<class> class SPHKernel>
61 struct SolverConfig;
62
68 template<class Tscal>
69 struct CFLConfig {
70
74 Tscal cfl_cour;
75
79 Tscal cfl_force;
80
85
87 Tscal eta_sink = 0.05;
88 };
89
90 template<class Tvec>
92 using Tscal = shambase::VecComponent<Tvec>;
93 struct Sphere {
94 Tvec center;
95 Tscal radius;
96 };
97
98 using kill_t = std::variant<Sphere>;
99
100 std::vector<kill_t> kill_list;
101
102 inline void add_kill_sphere(const Tvec &center, Tscal radius) {
103 kill_list.push_back(Sphere{center, radius});
104 }
105 };
106
107 template<class Tscal>
109 Tscal rhodust_eps;
110 Tscal dv_max;
111 std::vector<Tscal> massgrid;
112 std::vector<Tscal> tabflux_coag;
113 };
114
115 template<class Tscal>
116 struct DustConfig {
117
118 struct None {};
119
121 u32 ndust;
122 bool pure_diffusion_mode = false;
123
124 Tscal C_1_fluid = 0.1;
125 Tscal C_drift = 1.0;
126 Tscal cfl_density_threshold = shambase::get_epsilon<Tscal>();
127
128 bool ensure_s_j_positivity = true;
129
130 bool smooth_s_positivity_limiter = false;
131
132 // use the corrected q_AV from Hutchison 2018 & Price Laibe 15
133 bool dust_corrected_av = false;
134
135 // Fraction of rho(h) that the dust density (per-species and summed) is clamped to.
136 // The clamp runs only when this is set.
137 std::optional<Tscal> clamp_dust_frac = std::nullopt;
138
139 static constexpr Tscal default_clamp_dust_frac = 0.99;
140
141 inline bool should_clamp_dust_density() const { return clamp_dust_frac.has_value(); }
142
143 inline Tscal get_clamp_dust_frac() const {
144 return clamp_dust_frac.value_or(default_clamp_dust_frac);
145 }
146 };
147
149 u32 ndust;
150 };
151
153 using Variant = std::variant<None, MonofluidTVA, MonofluidComplete>;
154
155 Variant current_mode = None{};
156
157 inline void set_none() { current_mode = None{}; }
158 inline void set_monofluid_tva(
159 u32 nvar,
160 bool pure_diffusion_mode = false,
161 Tscal C_1_fluid = 0.1,
162 Tscal C_drift = 1.0,
163 Tscal cfl_density_threshold = shambase::get_epsilon<Tscal>(),
164 bool ensure_s_j_positivity = true,
165 bool smooth_s_positivity_limiter = false,
166 bool dust_corrected_av = false,
167 std::optional<Tscal> clamp_dust_frac = std::nullopt) {
168 current_mode = MonofluidTVA{
169 nvar,
170 pure_diffusion_mode,
171 C_1_fluid,
172 C_drift,
173 cfl_density_threshold,
174 ensure_s_j_positivity,
175 smooth_s_positivity_limiter,
176 dust_corrected_av,
177 clamp_dust_frac};
178 }
179 inline void set_monofluid_complete(u32 nvar) { current_mode = MonofluidComplete{nvar}; }
180
181 inline bool is_none() { return std::holds_alternative<None>(current_mode); }
182 inline bool is_monofluid_tva() { return bool(std::get_if<MonofluidTVA>(&current_mode)); }
183 inline bool is_monofluid_complete() {
184 return bool(std::get_if<MonofluidComplete>(&current_mode));
185 }
186
187 inline MonofluidTVA &get_monofluid_tva() {
188 return shambase::get_check_ref(std::get_if<MonofluidTVA>(&current_mode));
189 }
190
191 inline void mode_to_json(nlohmann::json &j) const {
192 if (const None *cfg = std::get_if<None>(&current_mode)) {
193 j = {{"type", "none"}};
194 } else if (const MonofluidTVA *cfg = std::get_if<MonofluidTVA>(&current_mode)) {
195 j
196 = {{"type", "monofluid_tva"},
197 {"ndust", cfg->ndust},
198 {"pure_diffusion_mode", cfg->pure_diffusion_mode},
199 {"C_1_fluid", cfg->C_1_fluid},
200 {"C_drift", cfg->C_drift},
201 {"cfl_density_threshold", cfg->cfl_density_threshold},
202 {"ensure_s_j_positivity", cfg->ensure_s_j_positivity},
203 {"smooth_s_positivity_limiter", cfg->smooth_s_positivity_limiter},
204 {"dust_corrected_av", cfg->dust_corrected_av},
205 {"clamp_dust_frac", cfg->clamp_dust_frac}};
206 } else if (
207 const MonofluidComplete *cfg = std::get_if<MonofluidComplete>(&current_mode)) {
208 j = {{"type", "monofluid_complete"}, {"ndust", cfg->ndust}};
209 } else {
211 }
212 }
213
214 inline void mode_from_json(const nlohmann::json &j) {
215 const std::string type = j.at("type").get<std::string>();
216 if (type == "none") {
217 set_none();
218 } else if (type == "monofluid_tva") {
219 set_monofluid_tva(
220 j.at("ndust").get<u32>(),
221 j.at("pure_diffusion_mode").get<bool>(),
222 j.at("C_1_fluid").get<Tscal>(),
223 j.at("C_drift").get<Tscal>(),
224 j.at("cfl_density_threshold").get<Tscal>(),
225 j.at("ensure_s_j_positivity").get<bool>(),
226 j.value("smooth_s_positivity_limiter", false),
227 j.value("dust_corrected_av", false),
228 j.value("clamp_dust_frac", std::optional<Tscal>{}));
229 } else if (type == "monofluid_complete") {
230 set_monofluid_complete(j.at("ndust").get<u32>());
231 } else {
233 }
234 }
235
236 inline bool has_s_j_field() {
237 return is_monofluid_tva(); // S_j = sqrt(\rho \epsilon_j)
238 }
239
240 inline bool should_use_dust_av() {
241 if (!is_monofluid_tva()) {
242 return false;
243 }
244 return get_monofluid_tva().dust_corrected_av;
245 }
246
247 inline bool has_epsilon_field() {
248 return bool(std::get_if<MonofluidComplete>(&current_mode));
249 }
250
251 inline bool has_deltav_field() {
252 return bool(std::get_if<MonofluidComplete>(&current_mode));
253 }
254
255 inline u32 get_dust_nvar() {
256 if (None *cfg = std::get_if<None>(&current_mode)) {
258 "Querying a dust nvar with no dust as config is ... discutable ...");
259 return 0;
260 } else if (MonofluidTVA *cfg = std::get_if<MonofluidTVA>(&current_mode)) {
261 return cfg->ndust;
262 } else if (MonofluidComplete *cfg = std::get_if<MonofluidComplete>(&current_mode)) {
263 return cfg->ndust;
264 } else {
265 shambase::throw_unimplemented("How did you get here ???");
266 }
267 return 0;
268 }
269
271 std::vector<Tscal> stopping_times;
272 };
273
274 struct EpsteinDrag {
275 static constexpr bool supersonic_correction = false;
276 Tscal gamma;
277 std::vector<Tscal> grains_sizes;
278 std::vector<Tscal> grains_densities;
279 };
280
281 std::variant<None, ConstantStoppingTimes, EpsteinDrag> dust_drag_mode = None{};
282
283 bool ballabio_ts_limiter = false;
284
285 inline void drag_mode_to_json(nlohmann::json &j) const {
286 if (std::holds_alternative<None>(dust_drag_mode)) {
287 j = {{"type", "none"}};
288 } else if (
289 const ConstantStoppingTimes *cfg
290 = std::get_if<ConstantStoppingTimes>(&dust_drag_mode)) {
291 j = {{"type", "constant_stopping_times"}, {"stopping_times", cfg->stopping_times}};
292 } else if (const EpsteinDrag *cfg = std::get_if<EpsteinDrag>(&dust_drag_mode)) {
293 j
294 = {{"type", "epstein_drag"},
295 {"gamma", cfg->gamma},
296 {"grains_sizes", cfg->grains_sizes},
297 {"grains_densities", cfg->grains_densities}};
298 } else {
300 }
301 }
302
303 inline void drag_mode_from_json(const nlohmann::json &j) {
304 if (j.at("type").get<std::string>() == "none") {
305 dust_drag_mode = None{};
306 } else if (j.at("type").get<std::string>() == "constant_stopping_times") {
307 dust_drag_mode
308 = ConstantStoppingTimes{j.at("stopping_times").get<std::vector<Tscal>>()};
309 } else if (j.at("type").get<std::string>() == "epstein_drag") {
310 dust_drag_mode = EpsteinDrag{
311 j.at("gamma").get<Tscal>(),
312 j.at("grains_sizes").get<std::vector<Tscal>>(),
313 j.at("grains_densities").get<std::vector<Tscal>>()};
314 } else {
316 }
317 }
318
319 inline void set_drag_constant(ConstantStoppingTimes in) { dust_drag_mode = std::move(in); }
320
321 inline void set_drag_epstein(EpsteinDrag in) { dust_drag_mode = std::move(in); }
322
323 std::variant<None, DustEvolCoalaCoag<Tscal>> dust_evol_config = None{};
324
325 inline void evol_mode_to_json(nlohmann::json &j) const {
326 std::visit(
328 [&](const None &) {
329 j = {{"type", "none"}};
330 },
331 [&](const DustEvolCoalaCoag<Tscal> &cfg) {
332 j
333 = {{"type", "coala_coag"},
334 {"rhodust_eps", cfg.rhodust_eps},
335 {"dv_max", cfg.dv_max},
336 {"massgrid", cfg.massgrid},
337 {"tabflux_coag", cfg.tabflux_coag}};
338 },
339 },
340 dust_evol_config);
341 }
342
343 inline void evol_mode_from_json(const nlohmann::json &j) {
344 if (j.at("type").get<std::string>() == "none") {
345 dust_evol_config = None{};
346 } else if (j.at("type").get<std::string>() == "coala_coag") {
347 dust_evol_config = DustEvolCoalaCoag<Tscal>{
348 .rhodust_eps = j.at("rhodust_eps").get<Tscal>(),
349 .dv_max = j.at("dv_max").get<Tscal>(),
350 .massgrid = j.at("massgrid").get<std::vector<Tscal>>(),
351 .tabflux_coag = j.at("tabflux_coag").get<std::vector<Tscal>>()};
352 } else {
354 }
355 }
356
357 inline void set_dust_evol_coala(DustEvolCoalaCoag<Tscal> cfg) { dust_evol_config = cfg; }
358
359 inline void check_config() {
360 bool is_not_none = !is_none();
361 if (is_not_none) {
362
365 "Dust config != None is experimental");
366 } else {
367 ON_RANK_0(
368 logger::warn_ln(
369 "SPH::config",
370 "Dust config != None is work in progress, use it at your own risk"));
371 }
372
373 if (std::holds_alternative<None>(dust_drag_mode)) {
375 "you must select a drag mode for the dust if the dust is on !");
376 } else if (
378 = std::get_if<ConstantStoppingTimes>(&dust_drag_mode)) {
379 if (get_dust_nvar() != cfg->stopping_times.size()) {
381 "stopping_times size does not match the number of dust bins");
382 }
383 } else if (EpsteinDrag *cfg = std::get_if<EpsteinDrag>(&dust_drag_mode)) {
384 if (get_dust_nvar() != cfg->grains_densities.size()) {
386 "grains_densities size does not match the number of dust bins");
387 }
388
389 if (get_dust_nvar() != cfg->grains_sizes.size()) {
391 "grains_sizes size does not match the number of dust bins");
392 }
393 }
394 }
395
396 if (!std::holds_alternative<None>(dust_evol_config) && is_not_none) {
397
398 if (DustEvolCoalaCoag<Tscal> *cfg
399 = std::get_if<DustEvolCoalaCoag<Tscal>>(&dust_evol_config)) {
400
401 u32 ndust = get_dust_nvar();
402
403 if (cfg->massgrid.size() - 1 != ndust) {
405 "massgrid must have ndust + 1 = " + std::to_string(ndust + 1)
406 + " entries for ndust = " + std::to_string(ndust) + ", got "
407 + std::to_string(cfg->massgrid.size()));
408 }
409
410 if (cfg->tabflux_coag.size() != ndust * ndust * ndust) {
412 "tabflux_coag must have ndust^3 = "
413 + std::to_string(ndust * ndust * ndust)
414 + " entries for ndust = " + std::to_string(ndust) + ", got "
415 + std::to_string(cfg->tabflux_coag.size()));
416 }
417
418 if (cfg->rhodust_eps <= 0) {
420 "rhodust_eps must be positive, got "
421 + std::to_string(cfg->rhodust_eps));
422 }
423
424 if (cfg->dv_max <= 0) {
426 "dv_max must be positive, got " + std::to_string(cfg->dv_max));
427 }
428
429 } else {
431 }
432
433 } else if (!std::holds_alternative<None>(dust_evol_config) && is_none()) {
435 "cannot enable dust evolution because the dust mode is 'none', call "
436 "set_dust_mode_* before set_dust_evol_coala");
437 }
438 }
439 };
440
442 struct DensityBased {};
444 u32 max_neigh_count = 500;
445 };
446
447 using mode = std::variant<DensityBased, DensityBasedNeighLim>;
448
449 mode config = DensityBased{};
450
451 void set_density_based() { config = DensityBased{}; }
452 void set_density_based_neigh_lim(u32 max_neigh_count) {
453 config = DensityBasedNeighLim{max_neigh_count};
454 }
455
456 bool is_density_based_neigh_lim() const {
457 return std::holds_alternative<DensityBasedNeighLim>(config);
458 }
459 };
460
462
463 struct SFMM {
464 u32 order;
465 f64 opening_angle;
466 bool leaf_lowering;
467 u32 reduction_level;
468 };
469
470 struct FMM {
471 u32 order;
472 f64 opening_angle;
473 u32 reduction_level;
474 };
475
476 struct MM {
477 u32 order;
478 f64 opening_angle;
479 u32 reduction_level;
480 };
481
482 struct Direct {
483 bool reference_mode = false;
484 };
485
486 struct None {};
487
488 using mode = std::variant<SFMM, FMM, MM, Direct, None>;
489
490 mode config = None{};
491
492 void set_none() { config = None{}; }
493 void set_direct(bool reference_mode = false) { config = Direct{reference_mode}; }
494 void set_mm(u32 mm_order, f64 opening_angle, u32 reduction_level) {
495 config = MM{
496 .order = mm_order,
497 .opening_angle = opening_angle,
498 .reduction_level = reduction_level};
499 }
500 void set_fmm(u32 order, f64 opening_angle, u32 reduction_level) {
501 config = FMM{
502 .order = order, .opening_angle = opening_angle, .reduction_level = reduction_level};
503 }
504 void set_sfmm(u32 order, f64 opening_angle, bool leaf_lowering, u32 reduction_level) {
505 config = SFMM{
506 .order = order,
507 .opening_angle = opening_angle,
508 .leaf_lowering = leaf_lowering,
509 .reduction_level = reduction_level};
510 }
511
512 bool is_none() const { return std::holds_alternative<None>(config); }
513 bool is_direct() const { return std::holds_alternative<Direct>(config); }
514 bool is_mm() const { return std::holds_alternative<MM>(config); }
515 bool is_fmm() const { return std::holds_alternative<FMM>(config); }
516 bool is_sfmm() const { return std::holds_alternative<SFMM>(config); }
517
518 bool is_sg_on() const { return !is_none(); }
519 bool is_sg_off() const { return is_none(); }
520
522 f64 epsilon;
523 };
524
525 using mode_soft = std::variant<SofteningPlummer>;
526 mode_soft softening_mode = SofteningPlummer{1e-9};
527
528 void set_softening_plummer(f64 epsilon) { softening_mode = SofteningPlummer{epsilon}; }
529 void set_softening_none() { set_softening_plummer(0.); }
530
531 bool is_softening_plummer() const {
532 return std::holds_alternative<SofteningPlummer>(softening_mode);
533 }
534 };
535
536} // namespace shammodels::sph
537
538template<class Tvec, template<class> class SPHKernel>
540
542 using Tscal = shambase::VecComponent<Tvec>;
544 static constexpr u32 dim = shambase::VectorProperties<Tvec>::dimension;
546 using Kernel = SPHKernel<Tscal>;
548 using u_morton = u32;
549
551
553 static constexpr Tscal Rkern = Kernel::Rkern;
554
556
557 bool track_particles_id = false;
558
559 inline void set_particle_tracking(bool state) { track_particles_id = state; }
560
561 PatchSchedulerConfig scheduler_conf = {};
562
564 // Units Config
566
568 std::optional<shamunits::UnitSystem<Tscal>> unit_sys = {};
569
571 inline void set_units(shamunits::UnitSystem<Tscal> new_sys) { unit_sys = new_sys; }
572
575 if (!unit_sys) {
576 ON_RANK_0(logger::warn_ln("sph::Config", "the unit system is not set"));
578 return ctes.G();
579 } else {
581 }
582 }
583
586 if (!unit_sys) {
587 ON_RANK_0(logger::warn_ln("sph::Config", "the unit system is not set"));
589 return ctes.c();
590 } else {
592 }
593 }
594
597 if (!unit_sys) {
598 ON_RANK_0(logger::warn_ln("sph::Config", "the unit system is not set"));
600 return ctes.mu_0();
601 } else {
603 }
604 }
605
607 // Units Config (END)
609
611 // Particle killing config
613
614 ParticleKillingConfig<Tvec> particle_killing;
615
617 // Particle killing config (END)
619
621 // CFL Configuration (config)
623
625
627 inline void set_cfl_mult_stiffness(Tscal cstiff) {
628 cfl_config.cfl_multiplier_stiffness = cstiff;
629 }
630
632 inline Tscal get_cfl_mult_stiffness() { return cfl_config.cfl_multiplier_stiffness; }
633
634 bool show_cfl_detail = false;
635
637 // CFL Configuration (END)
639
641 // MHD Config
643
645 MHDConfig mhd_config = {};
646
648 inline void set_noMHD() {
649 using Tmp = typename MHDConfig::None;
650 mhd_config.set(Tmp{});
651 }
652
655 mhd_config.set(v);
656 }
657
658 inline void set_NonIdealMHD(typename MHDConfig::NonIdealMHD v) { mhd_config.set(v); }
659
661 // MHD Config (END)
663
665 // Dust config
667
668 using DustConfig = DustConfig<Tscal>;
669 DustConfig dust_config = {};
670
672 // Dust config (END)
674
676 // Self gravity config
678
679 SelfGravConfig self_grav_config = SelfGravConfig{};
680
682 // Self gravity config (END)
684
686 // Tree config
688
690
693
695 inline void set_tree_reduction_level(u32 level) { tree_reduction_level = level; }
696
699 neigh_cache_strategy = strategy;
700 }
701
706 inline void set_two_stage_search(bool enable) {
707 ON_RANK_0(shamlog_warn_ln(
708 "SPH::SolverConfig",
709 "set_two_stage_search() is deprecated,\n"
710 " -> use set_neigh_cache_strategy(NeighCacheStrategy.TwoStage) or\n"
711 " set_neigh_cache_strategy(NeighCacheStrategy.SingleStage) instead"););
713 }
714
715 bool show_neigh_stats = false;
716 inline void set_show_neigh_stats(bool enable) { show_neigh_stats = enable; }
718 // Tree config (END)
720
722 // Solver behavior config
724
734
735 SmoothingLengthConfig smoothing_length_config;
736
737 inline void set_smoothing_length_density_based() {
738 smoothing_length_config.set_density_based();
739 }
740 inline void set_smoothing_length_density_based_neigh_lim(u32 max_neigh_count) {
741 smoothing_length_config.set_density_based_neigh_lim(max_neigh_count);
742 }
743
744 bool enable_particle_reordering = false;
745 inline void set_enable_particle_reordering(bool enable) { enable_particle_reordering = enable; }
746 u64 particle_reordering_step_freq = 1000;
747 inline void set_particle_reordering_step_freq(u64 freq) {
748 if (freq == 0) {
750 "particle_reordering_step_freq cannot be zero");
751 }
752 particle_reordering_step_freq = freq;
753 }
754
755 bool save_dt_to_fields = false;
756 inline void set_save_dt_to_fields(bool enable) { save_dt_to_fields = enable; }
757 inline bool should_save_dt_to_fields() const { return save_dt_to_fields; }
758
759 bool show_ghost_zone_graph = false;
760 inline void set_show_ghost_zone_graph(bool enable) { show_ghost_zone_graph = enable; }
761
763 // Solver behavior config (END)
765
767 // EOS Config
769
772
775
778 using T = typename EOSConfig::LocallyIsothermal;
779 return bool(std::get_if<T>(&eos_config.config));
780 }
781
783 inline bool is_eos_adiabatic() {
784 using T = typename EOSConfig::Adiabatic;
785 return bool(std::get_if<T>(&eos_config.config));
786 }
787
789 inline bool is_eos_polytropic() {
790 using T = typename EOSConfig::Polytropic;
791 return bool(std::get_if<T>(&eos_config.config));
792 }
793
795 inline bool is_eos_isothermal() {
796 using T = typename EOSConfig::Isothermal;
797 return bool(std::get_if<T>(&eos_config.config));
798 }
799
801 inline bool is_eos_fermi() {
802 using T = typename EOSConfig::Fermi;
803 return bool(std::get_if<T>(&eos_config.config));
804 }
805
811 inline void set_eos_isothermal(Tscal cs) { eos_config.set_isothermal(cs); }
812
818 inline void set_eos_adiabatic(Tscal gamma) { eos_config.set_adiabatic(gamma); }
819
825 inline void set_eos_polytropic(Tscal K, Tscal gamma) { eos_config.set_polytropic(K, gamma); }
826
830 inline void set_eos_locally_isothermal() { eos_config.set_locally_isothermal(); }
831
841 eos_config.set_locally_isothermalLP07(cs0, q, r0);
842 }
843
852 eos_config.set_locally_isothermalFA2014(h_over_r);
853 }
854
865 Tscal cs0, Tscal q, Tscal r0, u32 n_sinks) {
866 eos_config.set_locally_isothermalFA2014_extended(cs0, q, r0, n_sinks);
867 }
868
874 inline void set_eos_fermi(Tscal mu_e) { eos_config.set_fermi(mu_e); }
875
877 // EOS Config (END)
879
881 // Artificial viscosity Config
883
896
899
904 using Tmp = typename AVConfig::None;
905 artif_viscosity.set(Tmp{});
906 }
907
913 inline void set_artif_viscosity_Constant(typename AVConfig::Constant v) {
914 artif_viscosity.set(v);
915 }
916
923 inline void set_artif_viscosity_VaryingMM97(typename AVConfig::VaryingMM97 v) {
924 artif_viscosity.set(v);
925 }
926
933 inline void set_artif_viscosity_VaryingCD10(typename AVConfig::VaryingCD10 v) {
934 artif_viscosity.set(v);
935 }
936
941 inline void set_artif_viscosity_ConstantDisc(typename AVConfig::ConstantDisc v) {
942 artif_viscosity.set(v);
943 }
944
946 // Artificial viscosity Config (END)
948
950 // Boundary Config
952
957
964
968 inline void set_boundary_free() { boundary_config.set_free(); }
969
973 inline void set_boundary_periodic() { boundary_config.set_periodic(); }
974
986 inline void set_boundary_shearing_periodic(i32_3 shear_base, i32_3 shear_dir, Tscal speed) {
987 boundary_config.set_shearing_periodic(shear_base, shear_dir, speed);
988 }
989
991 // Boundary Config (END)
993
995 // Ext force Config
997
1010
1015
1024 Tscal central_mass, Tscal Racc, Tvec central_pos = Tvec{}) {
1025 ext_force_config.add_point_mass(central_mass, Racc, central_pos);
1026 }
1027
1034 inline void add_ext_force_paczynski_wiita(Tscal central_mass, Tvec central_pos, Tscal Racc) {
1035 ext_force_config.add_paczynski_wiita(central_mass, central_pos, Racc);
1036 }
1037
1048 Tscal central_mass, Tscal Racc, Tscal a_spin, Tvec dir_spin, Tvec central_pos = Tvec{}) {
1049 ext_force_config.add_lense_thirring(central_mass, Racc, a_spin, dir_spin, central_pos);
1050 }
1051
1059 inline void add_ext_force_shearing_box(Tscal Omega_0, Tscal eta, Tscal q) {
1060 ext_force_config.add_shearing_box(Omega_0, eta, q);
1061 }
1062
1064 // Ext force Config (END)
1066
1068 // Debug dump config
1070
1072 bool do_debug_dump = false;
1073
1075 std::string debug_dump_filename = "";
1076
1081 inline void set_debug_dump(bool _do_debug_dump, std::string _debug_dump_filename) {
1082 this->do_debug_dump = _do_debug_dump;
1083 this->debug_dump_filename = _debug_dump_filename;
1084 }
1085
1087 inline constexpr bool do_MHD_debug() { return false; }
1088
1090 // Debug dump config (END)
1092
1095
1099 inline bool has_field_uint() {
1100 // no barotropic for now
1101 return true;
1102 }
1103
1105 inline bool has_field_alphaAV() { return artif_viscosity.has_alphaAV_field(); }
1106
1108 inline bool has_field_divv() { return artif_viscosity.has_alphaAV_field(); }
1109
1111 inline bool has_field_dtdivv() { return artif_viscosity.has_dtdivv_field(); }
1112
1114 inline bool has_field_curlv() { return artif_viscosity.has_curlv_field() && (dim == 3); }
1115
1117 inline bool has_axyz_in_ghost() { return has_field_dtdivv(); }
1118
1120 inline bool has_field_soundspeed() {
1121 return artif_viscosity.has_field_soundspeed() || is_eos_locally_isothermal();
1122 }
1123
1125 inline bool has_field_B_on_rho() { return mhd_config.has_B_field() && (dim == 3); }
1126
1128 inline bool has_field_psi_on_ch() { return mhd_config.has_psi_field(); }
1129
1131 inline bool has_field_divB() { return mhd_config.has_divB_field(); }
1132
1134 inline bool has_field_curlB() { return mhd_config.has_curlB_field() && (dim == 3); }
1135
1137 inline bool has_field_dtdivB() { return mhd_config.has_dtdivB_field(); }
1138
1141 inline void use_luminosity(bool enable) { compute_luminosity = enable; }
1142
1144 bool compute_gw = false;
1145 inline void use_GW(bool enable) {
1146 shamrock::experimental_feature_check("GW computation is experimental.");
1147 compute_gw = enable;
1148 }
1149
1151 inline void print_status() {
1152 if (shamcomm::world_rank() != 0) {
1153 return;
1154 }
1155 logger::raw_ln("----- SPH Solver configuration -----");
1156 logger::raw_ln(nlohmann::json{*this}.dump(4));
1157 logger::raw_ln("------------------------------------");
1158 }
1159
1160 inline void check_config() {
1161 dust_config.check_config();
1162
1163 if (track_particles_id && false /*particle injection when added*/) {
1165 "particle injection is not yet compatible with particle id tracking");
1166 }
1167
1168 if (track_particles_id) {
1169 shamrock::experimental_feature_check("Particle tracking is experimental");
1170 }
1171
1172 if (!self_grav_config.is_none()) {
1174 "Self gravity is experimental, please enable experimental features to use it");
1175 }
1176 }
1177
1178 void set_layout(shamrock::patch::PatchDataLayerLayout &pdl);
1179 void set_ghost_layout(shamrock::patch::PatchDataLayerLayout &ghost_layout);
1180};
1181
1182namespace shammodels::sph {
1183
1190 template<class Tscal>
1191 inline void to_json(nlohmann::json &j, const CFLConfig<Tscal> &p) {
1192 j = nlohmann::json{
1193 {"cfl_cour", p.cfl_cour},
1194 {"cfl_force", p.cfl_force},
1195 {"cfl_multiplier_stiffness", p.cfl_multiplier_stiffness},
1196 {"eta_sink", p.eta_sink}};
1197 }
1198
1205 template<class Tscal>
1206 inline void from_json(const nlohmann::json &j, CFLConfig<Tscal> &p) {
1207 j.at("cfl_cour").get_to<Tscal>(p.cfl_cour);
1208 j.at("cfl_force").get_to<Tscal>(p.cfl_force);
1209 j.at("cfl_multiplier_stiffness").get_to<Tscal>(p.cfl_multiplier_stiffness);
1210
1211 if (j.contains("eta_sink")) {
1212 j.at("eta_sink").get_to<Tscal>(p.eta_sink);
1213 } else {
1214 // Already set to default value
1215 ON_RANK_0(shamlog_warn_ln(
1216 "SPHConfig", "eta_sink not found when deserializing, defaulting to", p.eta_sink));
1217 }
1218 }
1219
1220 // JSON serialization for ParticleKillingConfig
1221 template<class Tvec>
1222 inline void to_json(nlohmann::json &j, const ParticleKillingConfig<Tvec> &p) {
1223 j = nlohmann::json::array();
1224 for (const auto &kill : p.kill_list) {
1225 if (std::holds_alternative<typename ParticleKillingConfig<Tvec>::Sphere>(kill)) {
1226 const auto &sphere = std::get<typename ParticleKillingConfig<Tvec>::Sphere>(kill);
1227 j.push_back(
1228 {{"type", "sphere"}, {"center", sphere.center}, {"radius", sphere.radius}});
1229 }
1230 // If more types are added to kill_t, handle them here
1231 }
1232 }
1233
1234 template<class Tvec>
1235 inline void from_json(const nlohmann::json &j, ParticleKillingConfig<Tvec> &p) {
1236 p.kill_list.clear();
1237 for (const auto &item : j) {
1238 std::string type = item.at("type").get<std::string>();
1239 if (type == "sphere") {
1241 item.at("center").get_to(sphere.center);
1242 item.at("radius").get_to(sphere.radius);
1243 p.kill_list.push_back(sphere);
1244 }
1245 // If more types are added to kill_t, handle them here
1246 }
1247 }
1248
1249 // JSON serialization for SmoothingLengthConfig
1250 inline void to_json(nlohmann::json &j, const SmoothingLengthConfig &p) {
1252 = std::get_if<SmoothingLengthConfig::DensityBased>(&p.config)) {
1253 j = {
1254 {"type", "density_based"},
1255 };
1256
1257 } else if (
1259 = std::get_if<SmoothingLengthConfig::DensityBasedNeighLim>(&p.config)) {
1260
1261 j = {
1262 {"type", "density_based_neigh_lim"},
1263 {"max_neigh_count", conf->max_neigh_count},
1264 };
1265 } else {
1267 }
1268 }
1269
1270 inline void from_json(const nlohmann::json &j, SmoothingLengthConfig &p) {
1271 if (j.at("type").get<std::string>() == "density_based") {
1273 } else if (j.at("type").get<std::string>() == "density_based_neigh_lim") {
1274 p.config
1275 = SmoothingLengthConfig::DensityBasedNeighLim{j.at("max_neigh_count").get<u32>()};
1276 } else {
1278 }
1279 }
1280
1282 inline void to_json(nlohmann::json &j, const SelfGravConfig &p) {
1283 if (const SelfGravConfig::SFMM *conf = std::get_if<SelfGravConfig::SFMM>(&p.config)) {
1284 j = {
1285 {"type", "sfmm"},
1286 {"order", conf->order},
1287 {"opening_angle", conf->opening_angle},
1288 {"reduction_level", conf->reduction_level},
1289 {"leaf_lowering", conf->leaf_lowering},
1290 };
1291 } else if (const SelfGravConfig::FMM *conf = std::get_if<SelfGravConfig::FMM>(&p.config)) {
1292 j = {
1293 {"type", "fmm"},
1294 {"order", conf->order},
1295 {"opening_angle", conf->opening_angle},
1296 {"reduction_level", conf->reduction_level},
1297 };
1298 } else if (const SelfGravConfig::MM *conf = std::get_if<SelfGravConfig::MM>(&p.config)) {
1299 j = {
1300 {"type", "mm"},
1301 {"order", conf->order},
1302 {"opening_angle", conf->opening_angle},
1303 {"reduction_level", conf->reduction_level},
1304 };
1305 } else if (
1306 const SelfGravConfig::Direct *conf = std::get_if<SelfGravConfig::Direct>(&p.config)) {
1307 j = {
1308 {"type", "direct"},
1309 {"reference_mode", conf->reference_mode},
1310 };
1311 } else if (
1312 const SelfGravConfig::None *conf = std::get_if<SelfGravConfig::None>(&p.config)) {
1313 j = {
1314 {"type", "none"},
1315 };
1316 }
1317
1318 if (const SelfGravConfig::SofteningPlummer *conf
1319 = std::get_if<SelfGravConfig::SofteningPlummer>(&p.softening_mode)) {
1320 j["softening_mode"] = "plummer";
1321 j["softening_length"] = conf->epsilon;
1322 } else {
1324 }
1325 }
1326
1328 inline void from_json(const nlohmann::json &j, SelfGravConfig &p) {
1329 if (j.at("type").get<std::string>() == "sfmm") {
1330 p.config = SelfGravConfig::SFMM{
1331 .order = j.at("order").get<u32>(),
1332 .opening_angle = j.at("opening_angle").get<f64>(),
1333 .leaf_lowering = j.at("leaf_lowering").get<bool>(),
1334 .reduction_level = j.at("reduction_level").get<u32>()};
1335 } else if (j.at("type").get<std::string>() == "fmm") {
1336 p.config = SelfGravConfig::FMM{
1337 .order = j.at("order").get<u32>(),
1338 .opening_angle = j.at("opening_angle").get<f64>(),
1339 .reduction_level = j.at("reduction_level").get<u32>()};
1340 } else if (j.at("type").get<std::string>() == "mm") {
1341 p.config = SelfGravConfig::MM{
1342 .order = j.at("order").get<u32>(),
1343 .opening_angle = j.at("opening_angle").get<f64>(),
1344 .reduction_level = j.at("reduction_level").get<u32>()};
1345 } else if (j.at("type").get<std::string>() == "direct") {
1346 p.config = SelfGravConfig::Direct{j.at("reference_mode").get<bool>()};
1347 } else if (j.at("type").get<std::string>() == "none") {
1348 p.config = SelfGravConfig::None{};
1349 } else {
1351 "Invalid self gravity type: " + j.at("type").get<std::string>());
1352 }
1353
1354 if (j.contains("softening_mode")) {
1355 std::string softening_mode = j.at("softening_mode").get<std::string>();
1356 if (softening_mode == "plummer") {
1357 p.softening_mode
1358 = SelfGravConfig::SofteningPlummer{j.at("softening_length").get<f64>()};
1359 } else {
1361 "Invalid softening mode: " + softening_mode);
1362 }
1363 }
1364 }
1365
1366 // JSON serialization for DustConfig
1367 template<class Tvec>
1368 inline void to_json(nlohmann::json &j, const DustConfig<Tvec> &p) {
1369 j = {};
1370
1371 p.mode_to_json(j["mode"]);
1372 p.drag_mode_to_json(j["drag_mode"]);
1373 p.evol_mode_to_json(j["evol_mode"]);
1374 j["ballabio_ts_limiter"] = p.ballabio_ts_limiter;
1375 }
1376
1377 template<class Tvec>
1378 inline void from_json(const nlohmann::json &j, DustConfig<Tvec> &p) {
1379 p.mode_from_json(j.at("mode"));
1380 p.drag_mode_from_json(j.at("drag_mode"));
1381 if (j.contains("evol_mode")) {
1382 p.evol_mode_from_json(j.at("evol_mode"));
1383 }
1384 p.ballabio_ts_limiter = j.value("ballabio_ts_limiter", false);
1385 }
1386
1393 template<class Tvec, template<class> class SPHKernel>
1394 inline void to_json(nlohmann::json &j, const SolverConfig<Tvec, SPHKernel> &p) {
1396 using Tkernel = typename T::Kernel;
1397
1398 std::string kernel_id = shambase::get_type_name<Tkernel>();
1399 std::string type_id = shambase::get_type_name<Tvec>();
1400
1401 j = nlohmann::json{
1402 // used for type checking
1403 {"kernel_id", kernel_id},
1404 {"type_id", type_id},
1405 // scheduler config
1406 {"scheduler_config", p.scheduler_conf},
1407 // actual data stored in the json
1408 {"gpart_mass", p.gpart_mass},
1409 {"cfl_config", p.cfl_config},
1410 {"unit_sys", p.unit_sys},
1411 {"show_cfl_detail", p.show_cfl_detail},
1412 // mhd config
1413 {"mhd_config", p.mhd_config},
1414 // dust config
1415 {"dust_config", p.dust_config},
1416 // self gravity config
1417 {"self_grav_config", p.self_grav_config},
1418 // tree config
1419 {"tree_reduction_level", p.tree_reduction_level},
1420 {shammodels::neigh_cache_strategy_json_key, p.neigh_cache_strategy},
1421 {"show_neigh_stats", p.show_neigh_stats},
1422 // solver behavior config
1423 {"combined_dtdiv_divcurlv_compute", p.combined_dtdiv_divcurlv_compute},
1424 {"htol_up_coarse_cycle", p.htol_up_coarse_cycle},
1425 {"htol_up_fine_cycle", p.htol_up_fine_cycle},
1426 {"epsilon_h", p.epsilon_h},
1427 {"smoothing_length_config", p.smoothing_length_config},
1428 {"h_iter_per_subcycles", p.h_iter_per_subcycles},
1429 {"h_max_subcycles_count", p.h_max_subcycles_count},
1430
1431 {"enable_particle_reordering", p.enable_particle_reordering},
1432 {"particle_reordering_step_freq", p.particle_reordering_step_freq},
1433
1434 {"save_dt_to_fields", p.save_dt_to_fields},
1435 {"show_ghost_zone_graph", p.show_ghost_zone_graph},
1436
1437 {"eos_config", p.eos_config},
1438
1439 {"artif_viscosity", p.artif_viscosity},
1440 {"boundary_config", p.boundary_config},
1441 {"ext_force_config", p.ext_force_config},
1442
1443 {"do_debug_dump", p.do_debug_dump},
1444 {"debug_dump_filename", p.debug_dump_filename},
1445 // particle killing config
1446 {"particle_killing", p.particle_killing},
1447 };
1448 }
1449
1456 template<class Tvec, template<class> class SPHKernel>
1457 inline void from_json(const nlohmann::json &j, SolverConfig<Tvec, SPHKernel> &p) {
1459 using Tkernel = typename T::Kernel;
1460
1461 // type checking
1462 if (j.contains("kernel_id")) {
1463
1464 std::string kernel_id = j.at("kernel_id").get<std::string>();
1465
1466 if (kernel_id != shambase::get_type_name<Tkernel>()) {
1468 "Invalid type to deserialize, wanted " + shambase::get_type_name<Tvec>()
1469 + " but got " + kernel_id);
1470 }
1471 }
1472
1473 if (j.contains("type_id")) {
1474
1475 std::string type_id = j.at("type_id").get<std::string>();
1476
1477 if (type_id != shambase::get_type_name<Tvec>()) {
1479 "Invalid type to deserialize, wanted " + shambase::get_type_name<Tvec>()
1480 + " but got " + type_id);
1481 }
1482 }
1483
1484 bool has_used_defaults = false;
1485 bool has_updated_config = false;
1486
1487 auto _get_to_if_contains = [&](const std::string &key, auto &value) {
1488 shamrock::get_to_if_contains(j, key, value, has_used_defaults);
1489 };
1490
1491 auto _get_to_if_contains_fallbacks = [&](const std::string &key,
1492 auto &value,
1493 std::initializer_list<const char *> fallbacks) {
1495 j, key, value, fallbacks, has_used_defaults, has_updated_config);
1496 };
1497
1498 _get_to_if_contains("scheduler_config", p.scheduler_conf);
1499
1500 // actual data stored in the json
1501 _get_to_if_contains("gpart_mass", p.gpart_mass);
1502 _get_to_if_contains("cfl_config", p.cfl_config);
1503 _get_to_if_contains("unit_sys", p.unit_sys);
1504 _get_to_if_contains("show_cfl_detail", p.show_cfl_detail);
1505 _get_to_if_contains("mhd_config", p.mhd_config);
1506 _get_to_if_contains("dust_config", p.dust_config);
1507 _get_to_if_contains("self_grav_config", p.self_grav_config);
1508 _get_to_if_contains("tree_reduction_level", p.tree_reduction_level);
1509 // Reads the new enum key, falling back on the legacy `use_two_stage_search` boolean
1511 j, p.neigh_cache_strategy, "SPH::SolverConfig", has_used_defaults, has_updated_config);
1512 _get_to_if_contains("show_neigh_stats", p.show_neigh_stats);
1513 _get_to_if_contains("combined_dtdiv_divcurlv_compute", p.combined_dtdiv_divcurlv_compute);
1514
1515 // Try new names first, fall back to old names for backward compatibility
1516 _get_to_if_contains_fallbacks(
1517 "htol_up_coarse_cycle", p.htol_up_coarse_cycle, {"htol_up_tol"});
1518 _get_to_if_contains_fallbacks("htol_up_fine_cycle", p.htol_up_fine_cycle, {"htol_up_iter"});
1519
1520 _get_to_if_contains("epsilon_h", p.epsilon_h);
1521 _get_to_if_contains("smoothing_length_config", p.smoothing_length_config);
1522 _get_to_if_contains("h_iter_per_subcycles", p.h_iter_per_subcycles);
1523 _get_to_if_contains("h_max_subcycles_count", p.h_max_subcycles_count);
1524 _get_to_if_contains("enable_particle_reordering", p.enable_particle_reordering);
1525 _get_to_if_contains("particle_reordering_step_freq", p.particle_reordering_step_freq);
1526 _get_to_if_contains("save_dt_to_fields", p.save_dt_to_fields);
1527 _get_to_if_contains("show_ghost_zone_graph", p.show_ghost_zone_graph);
1528 _get_to_if_contains("eos_config", p.eos_config);
1529 _get_to_if_contains("artif_viscosity", p.artif_viscosity);
1530 _get_to_if_contains("boundary_config", p.boundary_config);
1531 _get_to_if_contains("ext_force_config", p.ext_force_config);
1532 _get_to_if_contains("do_debug_dump", p.do_debug_dump);
1533 _get_to_if_contains("debug_dump_filename", p.debug_dump_filename);
1534 _get_to_if_contains("particle_killing", p.particle_killing);
1535
1536 if (has_used_defaults || has_updated_config) {
1537 if (shamcomm::world_rank() == 0) {
1539 "SPH::SolverConfig",
1540 shamrock::log_json_changes(p, j, has_used_defaults, has_updated_config));
1541 }
1542 }
1543 }
1544
1545} // namespace shammodels::sph
Header file describing a Node Instance.
MPI scheduler.
double f64
Alias for double.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
A Compressed Leaf Bounding Volume Hierarchy (CLBVH) for neighborhood queries.
Defines a unit system.
Neighbour cache build strategy 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.
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
overloaded(Ts...) -> overloaded< Ts... >
Deduction guide so overloaded{lambda1, lambda2, ...} deduces Ts... from the lambdas.
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.
i32 world_rank()
Gives the rank of the current process in the MPI communicator.
Definition worldInfo.cpp:41
namespace for the sph model
constexpr const char * neigh_cache_strategy_json_key
Json key holding the neighbour cache strategy.
void get_to_neigh_cache_strategy(const nlohmann::json &j, NeighCacheStrategy &value, const std::string &log_ctx, bool &has_used_defaults, bool &has_updated_config)
Deserialize the neighbour cache strategy, falling back on the legacy boolean key.
NeighCacheStrategy neigh_cache_strategy_from_two_stage_search(bool use_two_stage_search)
Map the legacy use_two_stage_search boolean onto the strategy enum.
NeighCacheStrategy
Strategy used to build the neighbour cache out of the tree traversal.
@ TwoStage
Two stage neighbours search (see shamrock paper).
void get_to_if_contains(const nlohmann::json &j, const std::string &key, T &value, bool &has_used_defaults)
void experimental_feature_check(const std::string &message, SourceLocation loc=SourceLocation{})
Check if experimental features are enabled, if not throw with the given message.
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.
bool are_experimental_features_allowed()
Allow the use of experimental features.
void get_to_if_contains_fallbacks(const nlohmann::json &j, const std::string &key, T &value, std::initializer_list< const char * > fallbacks, bool &has_used_defaults, bool &has_updated_config)
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:89
void info_ln(std::string module_name, Types... var2)
Prints a log message with multiple arguments followed by a newline.
Definition logs.hpp:132
void warn_ln(std::string module_name, Types... var2)
Prints a log message with multiple arguments followed by a newline.
Definition logs.hpp:132
sph kernels
Locally isothermal equation of state configuration.
Definition EOSConfig.hpp:61
Configuration struct for the equation of state used in the hydrodynamic models.
Definition EOSConfig.hpp:42
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_Fermi< Tscal > Fermi
Fermi equation of state configuration.
Definition EOSConfig.hpp:73
shamphys::EOS_Config_Adiabatic< Tscal > Adiabatic
Adiabatic equation of state configuration.
Definition EOSConfig.hpp:52
The configuration for the CFL condition.
Tscal eta_sink
eta sink to control the sink integrator
Tscal cfl_cour
The CFL condition for the courant factor.
Tscal cfl_multiplier_stiffness
The CFL multiplier stiffness.
Tscal cfl_force
The CFL condition for the force.
std::variant< None, MonofluidTVA, MonofluidComplete > Variant
Variant type to store the EOS configuration.
The configuration for a sph solver.
bool ghost_has_soundspeed()
Whether the ghost cells have a sound speed (i.e. the eos is locally isothermal).
AVConfig artif_viscosity
Configuration for the Artificial Viscosity (AV).
void set_eos_isothermal(Tscal cs)
Set the EOS configuration to an isothermal equation of state.
Tscal gpart_mass
The mass of each gas particle.
u32 h_max_subcycles_count
Maximum number of subcycles before solver crash.
bool compute_luminosity
Whether to store luminosity.
void print_status()
Print the current status of the solver config.
void set_eos_adiabatic(Tscal gamma)
Set the EOS configuration to an adiabatic equation of state.
bool has_field_uint()
Whether the solver has a field for the particle's uint.
bool is_eos_isothermal()
Check if the EOS is an isothermal equation of state.
BCConfig boundary_config
Boundary condition configuration.
bool has_field_psi_on_ch()
Whether the solver has a field for psi_on_ch.
void set_cfl_mult_stiffness(Tscal cstiff)
Set the CFL multiplier for the stiffness.
bool has_field_dtdivB()
Whether the solver has a field for dt divB.
bool has_axyz_in_ghost()
Whether the solver has a field for ax, ay, az in ghost cells.
void set_eos_locally_isothermalLP07(Tscal cs0, Tscal q, Tscal r0)
Set the EOS configuration to a locally isothermal equation of state from Lodato Price 2007.
CFLConfig< Tscal > cfl_config
The configuration for the CFL condition.
bool has_field_divB()
Whether the solver has a field for divB.
void set_artif_viscosity_VaryingMM97(typename AVConfig::VaryingMM97 v)
Set the artificial viscosity configuration to a varying value using the prescription of Monaghan & Gi...
void add_ext_force_lense_thirring(Tscal central_mass, Tscal Racc, Tscal a_spin, Tvec dir_spin, Tvec central_pos=Tvec{})
Add a Lense-Thirring external force.
Tscal epsilon_h
Convergence criteria for the smoothing length.
SPHKernel< Tscal > Kernel
The type of the kernel used for the SPH interactions.
bool has_field_curlB()
Whether the solver has a field for curlB.
bool do_debug_dump
Whether to dump debug information to file.
bool has_field_divv()
Whether the solver has a field for divv.
bool compute_gw
Whether to compute GW.
shambase::VecComponent< Tvec > Tscal
The type of the scalar used to represent the quantities.
Tscal get_cfl_mult_stiffness()
Get the CFL multiplier for the stiffness.
bool has_field_alphaAV()
Whether the solver has a field for alpha AV.
void set_debug_dump(bool _do_debug_dump, std::string _debug_dump_filename)
Set whether to dump debug information to file.
u32 h_iter_per_subcycles
Maximum number of iterations per subcycle.
shammodels::ExtForceConfig< Tvec > ExtForceConfig
External force configuration.
bool is_eos_adiabatic()
Check if the EOS is an adiabatic equation of state.
void set_artif_viscosity_VaryingCD10(typename AVConfig::VaryingCD10 v)
Set the artificial viscosity configuration to a varying value using the prescription of Cullen & Dehn...
void add_ext_force_point_mass(Tscal central_mass, Tscal Racc, Tvec central_pos=Tvec{})
Add a point mass external force.
void set_neigh_cache_strategy(NeighCacheStrategy strategy)
Setter for the neighbours cache strategy.
void set_two_stage_search(bool enable)
Setter for the two stage search.
void set_boundary_free()
Set the boundary condition to free boundary.
bool has_field_curlv()
Whether the solver has a field for curlv.
bool has_field_dtdivv()
Whether the solver has a field for dt divv.
std::string debug_dump_filename
The filename to dump debug information in.
void add_ext_force_paczynski_wiita(Tscal central_mass, Tvec central_pos, Tscal Racc)
Add a post-newtonian Paczynski-Wiita potential.
bool is_eos_locally_isothermal()
Check if the EOS is a locally isothermal equation of state.
static constexpr Tscal Rkern
The radius of the sph kernel.
void set_eos_locally_isothermalFA2014_extended(Tscal cs0, Tscal q, Tscal r0, u32 n_sinks)
Set the EOS configuration to a locally isothermal equation of state from Farris 2014 extended to q !...
void set_eos_locally_isothermal()
Set the EOS configuration to a locally isothermal equation of state.
Tscal get_constant_G()
Retrieves the value of the constant G based on the unit system.
void set_eos_locally_isothermalFA2014(Tscal h_over_r)
Set the EOS configuration to a locally isothermal equation of state fromFarris 2014.
u32 u_morton
The type of the Morton code for the tree.
Tscal get_constant_mu_0()
Retrieves the value of the constant mu_0 based on the unit system.
void set_units(shamunits::UnitSystem< Tscal > new_sys)
Set the unit system of the simulation.
void set_artif_viscosity_None()
Set the artificial viscosity configuration to None.
bool is_eos_fermi()
Check if the EOS is a Fermi equation of state.
void set_IdealMHD(typename MHDConfig::IdealMHD_constrained_hyper_para v)
Enable the ideal MHD hydro solver.
void set_tree_reduction_level(u32 level)
Setter for the tree reduction level.
NeighCacheStrategy neigh_cache_strategy
Strategy used to build the neighbours cache out of the tree traversal.
static constexpr u32 dim
The dimension of the problem.
void set_eos_polytropic(Tscal K, Tscal gamma)
Set the EOS configuration to an polytropic equation of state.
Tscal get_constant_c()
Retrieves the value of the constant c based on the unit system.
void set_artif_viscosity_Constant(typename AVConfig::Constant v)
Set the artificial viscosity configuration to a constant value.
bool is_eos_polytropic()
Check if the EOS is a polytropic equation of state.
AVConfig< Tvec > AVConfig
Configuration for the Artificial Viscosity (AV).
BCConfig< Tvec > BCConfig
Configuration of the boundary conditions.
void set_boundary_shearing_periodic(i32_3 shear_base, i32_3 shear_dir, Tscal speed)
Set the boundary condition to shearing periodic boundary.
Tscal htol_up_fine_cycle
Maximum factor of the smoothing length evolution per subcycles.
void set_boundary_periodic()
Set the boundary condition to periodic boundary.
u32 tree_reduction_level
Reduction level to be used in the tree build.
bool has_field_B_on_rho()
Whether the solver has a field for B_on_rho.
constexpr bool do_MHD_debug()
Whether to add debug fields to the pdl.
std::optional< shamunits::UnitSystem< Tscal > > unit_sys
The unit system of the simulation.
EOSConfig eos_config
EOS configuration.
shammodels::EOSConfig< Tvec > EOSConfig
Alias to EOSConfig type.
bool has_field_soundspeed()
Whether the solver has a field for sound speed.
void set_noMHD()
disable MHD in the SPH solver
ExtForceConfig ext_force_config
External force configuration.
void add_ext_force_shearing_box(Tscal Omega_0, Tscal eta, Tscal q)
Add a shearing box external force.
void set_artif_viscosity_ConstantDisc(typename AVConfig::ConstantDisc v)
Set the artificial viscosity configuration to a constant value in the disc plane.
void set_eos_fermi(Tscal mu_e)
Set the EOS configuration to a Fermi equation of state.
Physical constants.
constexpr T c()
get c in the current unit system units (m.s-1)
constexpr T G()
get the value of G in the current unit system units
constexpr T mu_0()
get the value of mu_0 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