Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <boost/preprocessor/arithmetic/dec.hpp> 7 : #include <boost/preprocessor/arithmetic/inc.hpp> 8 : #include <boost/preprocessor/control/expr_iif.hpp> 9 : #include <boost/preprocessor/list/adt.hpp> 10 : #include <boost/preprocessor/repetition/for.hpp> 11 : #include <boost/preprocessor/repetition/repeat.hpp> 12 : #include <boost/preprocessor/tuple/to_list.hpp> 13 : #include <cstddef> 14 : #include <limits> 15 : #include <memory> 16 : #include <pup.h> 17 : 18 : #include "DataStructures/Tensor/Tensor.hpp" 19 : #include "DataStructures/Tensor/TypeAliases.hpp" 20 : #include "Options/String.hpp" 21 : #include "PointwiseFunctions/Hydro/EquationsOfState/EquationOfState.hpp" 22 : #include "PointwiseFunctions/Hydro/Units.hpp" 23 : #include "Utilities/Serialization/CharmPupable.hpp" 24 : #include "Utilities/TMPL.hpp" 25 : 26 : namespace EquationsOfState { 27 : /*! 28 : * \ingroup EquationsOfStateGroup 29 : * \brief A 3D equation of state representing a fluid in compositional 30 : * equalibrium. 31 : * 32 : * 33 : * The equation of state takes the form 34 : * 35 : * \f[ 36 : * p = p (T, rho, Y_e) = p(T, rho, Y_e= Y_{e, \beta}) 37 : * \f] 38 : * 39 : * where \f$\rho\f$ is the rest mass density and \f$T\f$ is the 40 : * temperaturee; \f$Y_e\f$ the electron fraction, is not 41 : * used, and therefore this evaluating this EoS at any arbtirary 42 : * electron fraction is equivalent to evaluating it in beta equalibrium 43 : * 44 : */ 45 : template <typename EquilEos> 46 1 : class Equilibrium3D : public EquationOfState<EquilEos::is_relativistic, 3> { 47 : public: 48 0 : static constexpr size_t thermodynamic_dim = 3; 49 0 : static constexpr bool is_relativistic = EquilEos::is_relativistic; 50 0 : static std::string name() { 51 : return "Equilibrium3D(" + pretty_type::name<EquilEos>() + ")"; 52 : } 53 0 : static constexpr Options::String help = { 54 : "An 3D EoS which is independent of electron fraction. " 55 : "Contains an underlying 2D EoS which is dependent only " 56 : "on rest mass density and temperature/internal energy."}; 57 : 58 0 : struct UnderlyingEos { 59 0 : using type = EquilEos; 60 0 : static std::string name() { return pretty_type::short_name<EquilEos>(); } 61 0 : static constexpr Options::String help{ 62 : "The underlying Eos which is being represented as a " 63 : "3D Eos. Must be a 2D EoS"}; 64 : }; 65 : 66 0 : using options = tmpl::list<UnderlyingEos>; 67 : 68 0 : Equilibrium3D() = default; 69 0 : Equilibrium3D(const Equilibrium3D&) = default; 70 0 : Equilibrium3D& operator=(const Equilibrium3D&) = default; 71 0 : Equilibrium3D(Equilibrium3D&&) = default; 72 0 : Equilibrium3D& operator=(Equilibrium3D&&) = default; 73 0 : ~Equilibrium3D() override = default; 74 : 75 0 : explicit Equilibrium3D(const EquilEos& underlying_eos) 76 : : underlying_eos_(underlying_eos){}; 77 : 78 : EQUATION_OF_STATE_FORWARD_DECLARE_MEMBERS(Equilibrium3D, 3) 79 : 80 0 : std::unique_ptr<EquationOfState<EquilEos::is_relativistic, 3>> get_clone() 81 : const override; 82 : 83 0 : bool is_equal( 84 : const EquationOfState<EquilEos::is_relativistic, 3>& rhs) const override; 85 : 86 : /// \brief Returns `true` if the EOS is barotropic 87 1 : bool is_barotropic() const override { return false; } 88 : 89 : /// \brief Returns `true` if the EOS is in beta-equilibrium 90 1 : bool is_equilibrium() const override { return true; } 91 : 92 0 : bool operator==(const Equilibrium3D<EquilEos>& rhs) const; 93 : 94 0 : bool operator!=(const Equilibrium3D<EquilEos>& rhs) const; 95 : /// @{ 96 : /*! 97 : * Computes the electron fraction in beta-equilibrium \f$Y_e^{\rm eq}\f$ from 98 : * the rest mass density \f$\rho\f$ and the temperature \f$T\f$. 99 : */ 100 1 : Scalar<double> equilibrium_electron_fraction_from_density_temperature( 101 : const Scalar<double>& rest_mass_density, 102 : const Scalar<double>& temperature) const override{ 103 : return underlying_eos_ 104 : .equilibrium_electron_fraction_from_density_temperature( 105 : rest_mass_density, temperature); 106 : } 107 : 108 1 : Scalar<DataVector> equilibrium_electron_fraction_from_density_temperature( 109 : const Scalar<DataVector>& rest_mass_density, 110 : const Scalar<DataVector>& temperature) const override { 111 : return underlying_eos_ 112 : .equilibrium_electron_fraction_from_density_temperature( 113 : rest_mass_density, temperature); 114 : } 115 : /// @} 116 : // 117 : 118 0 : WRAPPED_PUPable_decl_base_template( // NOLINT 119 : SINGLE_ARG(EquationOfState<EquilEos::is_relativistic, 3>), Equilibrium3D); 120 : 121 : /// The lower bound of the electron fraction that is valid for this EOS 122 1 : double electron_fraction_lower_bound() const override { return 0.0; } 123 : 124 : /// The upper bound of the electron fraction that is valid for this EOS 125 1 : double electron_fraction_upper_bound() const override { return 1.0; } 126 : 127 : /// The lower bound of the rest mass density that is valid for this EOS 128 1 : double rest_mass_density_lower_bound() const override { 129 : return underlying_eos_.rest_mass_density_lower_bound(); 130 : } 131 : 132 : /// The upper bound of the rest mass density that is valid for this EOS 133 1 : double rest_mass_density_upper_bound() const override { 134 : return underlying_eos_.rest_mass_density_upper_bound(); 135 : } 136 : 137 : /// The lower bound of the temperature that is valid for this EOS 138 1 : double temperature_lower_bound() const override { 139 : return underlying_eos_.temperature_lower_bound(); 140 : } 141 : 142 : /// The upper bound of the temperature that is valid for this EOS 143 1 : double temperature_upper_bound() const override { 144 : return underlying_eos_.temperature_upper_bound(); 145 : } 146 : 147 : /// The lower bound of the specific internal energy that is valid for this EOS 148 : /// at the given rest mass density \f$\rho\f$ and electron fraction \f$Y_e\f$ 149 1 : double specific_internal_energy_lower_bound( 150 : const double rest_mass_density, 151 : const double /*electron_fraction*/) const override { 152 : return underlying_eos_.specific_internal_energy_lower_bound( 153 : rest_mass_density); 154 : } 155 : 156 : /// The upper bound of the specific internal energy that is valid for this EOS 157 : /// at the given rest mass density \f$\rho\f$ 158 1 : double specific_internal_energy_upper_bound( 159 : const double rest_mass_density, 160 : const double /*electron_fraction*/) const override { 161 : return underlying_eos_.specific_internal_energy_upper_bound( 162 : rest_mass_density); 163 : } 164 : 165 : /// The lower bound of the specific enthalpy that is valid for this EOS 166 1 : double specific_enthalpy_lower_bound() const override { 167 : return underlying_eos_.specific_enthalpy_lower_bound(); 168 : } 169 : 170 : /// The baryon mass for this EoS 171 1 : double baryon_mass() const override { return underlying_eos_.baryon_mass(); } 172 : 173 : private: 174 : EQUATION_OF_STATE_FORWARD_DECLARE_MEMBER_IMPLS(3) 175 0 : EquilEos underlying_eos_; 176 : }; 177 : /// \cond 178 : template <typename EquilEos> 179 : PUP::able::PUP_ID EquationsOfState::Equilibrium3D<EquilEos>::my_PUP_ID = 0; 180 : /// \endcond 181 : } // namespace EquationsOfState