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 : 9 : #include "DataStructures/Tensor/TypeAliases.hpp" 10 : #include "Options/String.hpp" 11 : #include "PointwiseFunctions/Hydro/EquationsOfState/EquationOfState.hpp" 12 : #include "PointwiseFunctions/Hydro/TagsDeclarations.hpp" 13 : #include "Utilities/GenerateInstantiations.hpp" 14 : #include "Utilities/Gsl.hpp" 15 : #include "Utilities/TMPL.hpp" 16 : 17 : /// \cond 18 : namespace PUP { 19 : class er; 20 : } // namespace PUP 21 : class DataVector; 22 : namespace domain { 23 : namespace Tags { 24 : template <size_t Dim, typename Frame> 25 : struct Coordinates; 26 : } // namespace Tags 27 : } // namespace domain 28 : namespace hydro { 29 : namespace Tags { 30 : template <typename DataType> 31 : struct Pressure; 32 : template <typename DataType> 33 : struct RestMassDensity; 34 : template <typename DataType> 35 : struct SpecificInternalEnergy; 36 : template <typename DataType> 37 : struct Temperature; 38 : template <typename DataType> 39 : struct ElectronFraction; 40 : } // namespace Tags 41 : } // namespace hydro 42 : /// \endcond 43 : 44 : /// Contains all variable fixers. 45 : namespace VariableFixing { 46 : 47 : /// \ingroup VariableFixingGroup 48 : /// \brief Applies a pressure and density floor dependent on the distance 49 : /// to the origin. 50 : /// 51 : /// Applies the floors: 52 : /// \f$\rho(r) \geq \rho_{\mathrm{fl}}(r) = C_\rho r^{k_\rho}\f$ 53 : /// and \f$P(r) \geq P_{\mathrm{fl}}(r) = C_p r^{k_p}\f$ 54 : /// when \f$ r > r_{min}\f$, where \f$C_\rho\f$ is given by the option 55 : /// `ScaleDensityFloor`, \f$k_\rho\f$ is given by the option 56 : /// `PowerDensityFloor`, \f$C_p\f$ is given by the option 57 : /// `ScalePressureFloor`, \f$k_p\f$ is given by the option 58 : /// `PowerPressureFloor`, and \f$r_{min}\f$ is given by the option 59 : /// `MinimumRadius`. 60 : /// 61 : /// \note In \cite Porth2016rfi, the following floors are applied: 62 : /// \f$\rho(r) \geq \rho_{\mathrm{fl}}(r) = 10^{-5}r^{-3/2}\f$ 63 : /// and \f$P(r) \geq P_{\mathrm{fl}}(r) = \frac{1}{3} \times 10^{-7}r^{-5/2}\f$ 64 : /// 65 : /// \note For 3d equations of state we treat the product \f$\rho T\f$ as the 66 : /// "pressure" that we floor and then compute the pressure from the 67 : /// temperature. The floor is applied after flooring the density. 68 : template <size_t Dim> 69 1 : class RadiallyFallingFloor { 70 : public: 71 : /// \brief The minimum radius at which to begin applying the floors on the 72 : /// density and pressure. 73 1 : struct MinimumRadius { 74 0 : static constexpr Options::String help = 75 : "The radius at which to begin applying the lower bound."; 76 0 : using type = double; 77 0 : static double lower_bound() { return 0.0; } 78 : }; 79 : 80 : /// \brief The scale of the floor of the rest mass density. 81 1 : struct ScaleDensityFloor { 82 0 : static constexpr Options::String help = 83 : "The rest mass density floor at r = 1."; 84 0 : using type = double; 85 0 : static double lower_bound() { return 0.0; } 86 : }; 87 : 88 : /// \brief The power of the radius of the floor of the rest mass density. 89 1 : struct PowerDensityFloor { 90 0 : static constexpr Options::String help = 91 : "Radial power for the floor of the rest mass density."; 92 0 : using type = double; 93 : }; 94 : 95 : /// \brief The scale of the floor of the pressure. 96 1 : struct ScalePressureFloor { 97 0 : static constexpr Options::String help = "The pressure floor at r = 1."; 98 0 : using type = double; 99 0 : static double lower_bound() { return 0.0; } 100 : }; 101 : 102 : /// \brief The power of the radius of the floor of the pressure. 103 1 : struct PowerPressureFloor { 104 0 : static constexpr Options::String help = 105 : "The radial power for the floor of the pressure."; 106 0 : using type = double; 107 : }; 108 : 109 0 : using options = 110 : tmpl::list<MinimumRadius, ScaleDensityFloor, PowerDensityFloor, 111 : ScalePressureFloor, PowerPressureFloor>; 112 0 : static constexpr Options::String help = { 113 : "Applies a pressure and density floor dependent on the distance to the " 114 : "origin."}; 115 : 116 0 : RadiallyFallingFloor(double minimum_radius_at_which_to_apply_floor, 117 : double rest_mass_density_scale, 118 : double rest_mass_density_power, double pressure_scale, 119 : double pressure_power); 120 : 121 0 : RadiallyFallingFloor() = default; 122 0 : RadiallyFallingFloor(const RadiallyFallingFloor& /*rhs*/) = default; 123 0 : RadiallyFallingFloor& operator=(const RadiallyFallingFloor& /*rhs*/) = 124 : default; 125 0 : RadiallyFallingFloor(RadiallyFallingFloor&& /*rhs*/) = default; 126 0 : RadiallyFallingFloor& operator=(RadiallyFallingFloor&& /*rhs*/) = default; 127 0 : ~RadiallyFallingFloor() = default; 128 : 129 : // NOLINTNEXTLINE(google-runtime-references) 130 0 : void pup(PUP::er& p); 131 : 132 0 : using return_tags = 133 : tmpl::list<hydro::Tags::RestMassDensity<DataVector>, 134 : hydro::Tags::Pressure<DataVector>, 135 : hydro::Tags::SpecificInternalEnergy<DataVector>, 136 : hydro::Tags::Temperature<DataVector>, 137 : hydro::Tags::ElectronFraction<DataVector>>; 138 0 : using argument_tags = 139 : tmpl::list<domain::Tags::Coordinates<Dim, Frame::Inertial>, 140 : hydro::Tags::GrmhdEquationOfState>; 141 : 142 : template <size_t ThermodynamicDim> 143 0 : void operator()( 144 : gsl::not_null<Scalar<DataVector>*> density, 145 : gsl::not_null<Scalar<DataVector>*> pressure, 146 : gsl::not_null<Scalar<DataVector>*> specific_internal_energy, 147 : gsl::not_null<Scalar<DataVector>*> temperature, 148 : gsl::not_null<Scalar<DataVector>*> electron_fraction, 149 : const tnsr::I<DataVector, Dim, Frame::Inertial>& coords, 150 : const EquationsOfState::EquationOfState<true, ThermodynamicDim>& 151 : equation_of_state) const; 152 : 153 : private: 154 : template <size_t LocalDim> 155 : // NOLINTNEXTLINE(readability-redundant-declaration) 156 0 : friend bool operator==(const RadiallyFallingFloor<LocalDim>& lhs, 157 : const RadiallyFallingFloor<LocalDim>& rhs); 158 : 159 0 : double minimum_radius_at_which_to_apply_floor_{ 160 : std::numeric_limits<double>::signaling_NaN()}; 161 0 : double rest_mass_density_scale_{std::numeric_limits<double>::signaling_NaN()}; 162 0 : double rest_mass_density_power_{std::numeric_limits<double>::signaling_NaN()}; 163 0 : double pressure_scale_{std::numeric_limits<double>::signaling_NaN()}; 164 0 : double pressure_power_{std::numeric_limits<double>::signaling_NaN()}; 165 : }; 166 : 167 : template <size_t Dim> 168 0 : bool operator!=(const RadiallyFallingFloor<Dim>& lhs, 169 : const RadiallyFallingFloor<Dim>& rhs); 170 : 171 : } // namespace VariableFixing