Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 : #include <limits>
8 : #include <optional>
9 :
10 : #include "DataStructures/DataBox/Tag.hpp"
11 : #include "NumericalAlgorithms/DiscontinuousGalerkin/Tags/OptionsGroup.hpp"
12 : #include "Options/Auto.hpp"
13 : #include "Options/String.hpp"
14 : #include "Utilities/TMPL.hpp"
15 :
16 : /// \cond
17 : namespace PUP {
18 : class er;
19 : } // namespace PUP
20 : /// \endcond
21 :
22 : namespace grmhd::ValenciaDivClean::subcell {
23 : /*!
24 : * \brief Class holding options using by the GRMHD-specific parts of the
25 : * troubled-cell indicator.
26 : */
27 1 : struct TciOptions {
28 : private:
29 0 : struct DoNotCheckMagneticField {};
30 :
31 : public:
32 : /// \brief Minimum value of rest-mass density times Lorentz factor before we
33 : /// switch to subcell. Used to identify places where the density has suddenly
34 : /// become negative
35 1 : struct MinimumValueOfD {
36 0 : using type = double;
37 0 : static type lower_bound() { return 0.0; }
38 0 : static constexpr Options::String help = {
39 : "Minimum value of rest-mass density times Lorentz factor before we "
40 : "switch to subcell."};
41 : };
42 : /// \brief Minimum value of \f$Y_e\f$ before we switch to subcell.
43 : /// Used to identify places where the electron fraction has suddenly become
44 : // negative
45 1 : struct MinimumValueOfYe {
46 0 : using type = double;
47 0 : static type lower_bound() { return 0.0; }
48 0 : static constexpr Options::String help = {
49 : "Minimum value of Y_e before we switch to subcell."};
50 : };
51 : /// \brief Minimum value of \f$\tilde{\tau}\f$ before we switch to subcell.
52 : /// Used to identify places where the energy has suddenly become negative
53 1 : struct MinimumValueOfTildeTau {
54 0 : using type = double;
55 0 : static type lower_bound() { return 0.0; }
56 0 : static constexpr Options::String help = {
57 : "Minimum value of tilde tau before we switch to subcell."};
58 : };
59 : /// \brief The density cutoff where if the maximum value of the density in the
60 : /// DG element is below this value we skip primitive recovery and treat the
61 : /// cell as atmosphere.
62 1 : struct AtmosphereDensity {
63 0 : using type = double;
64 0 : static type lower_bound() { return 0.0; }
65 0 : static constexpr Options::String help = {
66 : "The density cutoff where if the maximum value of the density in the "
67 : "DG element is below this value we skip primitive recovery and treat "
68 : "the cell as atmosphere."};
69 : };
70 : /// \brief Safety factor \f$\epsilon_B\f$.
71 : ///
72 : /// See the documentation for TciOnDgGrid for details on what this parameter
73 : /// controls.
74 1 : struct SafetyFactorForB {
75 0 : using type = double;
76 0 : static type lower_bound() { return 0.0; }
77 0 : static constexpr Options::String help = {
78 : "Safety factor for magnetic field bound."};
79 : };
80 : /// \brief The cutoff where if the maximum of the magnetic field in an element
81 : /// is below this value we do not apply the Persson TCI to the magnetic field.
82 1 : struct MagneticFieldCutoff {
83 0 : using type = Options::Auto<double, DoNotCheckMagneticField>;
84 0 : static constexpr Options::String help = {
85 : "The cutoff where if the maximum of the magnetic field in an element "
86 : "is below this value we do not apply the Persson TCI to the magnetic "
87 : "field. This is to avoid switching to subcell in regions where there's "
88 : "no magnetic field.\n"
89 : "To disable the magnetic field check, set to "
90 : "'DoNotCheckMagneticField'."};
91 : };
92 :
93 0 : using options =
94 : tmpl::list<MinimumValueOfD, MinimumValueOfYe, MinimumValueOfTildeTau,
95 : AtmosphereDensity, SafetyFactorForB, MagneticFieldCutoff>;
96 0 : static constexpr Options::String help = {
97 : "Options for the troubled-cell indicator."};
98 :
99 0 : TciOptions();
100 0 : TciOptions(double minimum_rest_mass_density_times_lorentz_factor_in,
101 : double minimum_ye_in, double minimum_tilde_tau_in,
102 : double atmosphere_density_in,
103 : double safety_factor_for_magnetic_field_in,
104 : std::optional<double> magnetic_field_cutoff_in);
105 :
106 : // NOLINTNEXTLINE(google-runtime-references)
107 0 : void pup(PUP::er& p);
108 :
109 0 : double minimum_rest_mass_density_times_lorentz_factor{
110 : std::numeric_limits<double>::signaling_NaN()};
111 0 : double minimum_ye{std::numeric_limits<double>::signaling_NaN()};
112 0 : double minimum_tilde_tau{std::numeric_limits<double>::signaling_NaN()};
113 0 : double atmosphere_density{std::numeric_limits<double>::signaling_NaN()};
114 0 : double safety_factor_for_magnetic_field{
115 : std::numeric_limits<double>::signaling_NaN()};
116 : // The signaling_NaN default is chosen so that users hit an error/FPE if the
117 : // cutoff is not specified, rather than silently defaulting to ignoring the
118 : // magnetic field.
119 0 : std::optional<double> magnetic_field_cutoff{
120 : std::numeric_limits<double>::signaling_NaN()};
121 : };
122 :
123 0 : namespace OptionTags {
124 0 : struct TciOptions {
125 0 : using type = subcell::TciOptions;
126 0 : static constexpr Options::String help = "GRMHD-specific options for the TCI.";
127 0 : using group = ::dg::OptionTags::DiscontinuousGalerkinGroup;
128 : };
129 : } // namespace OptionTags
130 :
131 0 : namespace Tags {
132 0 : struct TciOptions : db::SimpleTag {
133 0 : using type = subcell::TciOptions;
134 :
135 0 : using option_tags = tmpl::list<OptionTags::TciOptions>;
136 0 : static constexpr bool pass_metavariables = false;
137 0 : static type create_from_options(const type& tci_options) {
138 : return tci_options;
139 : }
140 : };
141 : } // namespace Tags
142 : } // namespace grmhd::ValenciaDivClean::subcell
|