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 barotropic fluid.
30 : *
31 : *
32 : * The equation of state takes the form
33 : *
34 : * \f[
35 : * p = p (\rho , T, Y_e) = p(\rho, 0, Y_e= Y_{e, \beta})
36 : * \f]
37 : *
38 : * where \f$\rho\f$ is the rest mass density, \f$T\f$ the
39 : * temperature , and \f$Y_e\f$ the electron fraction. The temperature and
40 : * electron fraction are not used, so evaluating this EoS at any arbtirary
41 : * temeperature or electron fraction is equivalent to evaluating it at
42 : * zero temperature and in beta equalibrium.
43 : */
44 : template <typename ColdEquilEos>
45 1 : class Barotropic3D : public EquationOfState<ColdEquilEos::is_relativistic, 3> {
46 : public:
47 0 : static constexpr size_t thermodynamic_dim = 3;
48 0 : static constexpr bool is_relativistic = ColdEquilEos::is_relativistic;
49 :
50 0 : static std::string name() {
51 : return "Barotropic3D(" + pretty_type::name<ColdEquilEos>() + ")";
52 : }
53 0 : static constexpr Options::String help = {
54 : "An 3D EoS which is independent of electron fraction and temperature. "
55 : "Contains an underlying 1D EoS which is dependent only "
56 : "on rest mass density."};
57 0 : struct UnderlyingEos {
58 0 : using type = ColdEquilEos;
59 0 : static std::string name() {
60 : return pretty_type::short_name<ColdEquilEos>();
61 : }
62 0 : static constexpr Options::String help{
63 : "The underlying Eos which is being represented as a "
64 : "3D Eos. Must be a 1D EoS"};
65 : };
66 :
67 0 : using options = tmpl::list<UnderlyingEos>;
68 :
69 0 : Barotropic3D() = default;
70 0 : Barotropic3D(const Barotropic3D&) = default;
71 0 : Barotropic3D& operator=(const Barotropic3D&) = default;
72 0 : Barotropic3D(Barotropic3D&&) = default;
73 0 : Barotropic3D& operator=(Barotropic3D&&) = default;
74 0 : ~Barotropic3D() override = default;
75 :
76 0 : explicit Barotropic3D(const ColdEquilEos& underlying_eos)
77 : : underlying_eos_(underlying_eos){};
78 :
79 : EQUATION_OF_STATE_FORWARD_DECLARE_MEMBERS(Barotropic3D, 3)
80 :
81 0 : std::unique_ptr<EquationOfState<ColdEquilEos::is_relativistic, 3>> get_clone()
82 : const override;
83 :
84 0 : bool is_equal(const EquationOfState<ColdEquilEos::is_relativistic, 3>& rhs)
85 : const override;
86 :
87 : /// \brief Returns `true` if the EOS is barotropic
88 1 : bool is_barotropic() const override { return true; }
89 :
90 : /// \brief Returns `true` if the EOS is in beta-equilibrium
91 1 : bool is_equilibrium() const override { return false; }
92 :
93 0 : bool operator==(const Barotropic3D<ColdEquilEos>& rhs) const;
94 :
95 0 : bool operator!=(const Barotropic3D<ColdEquilEos>& rhs) const;
96 : /// @{
97 : /*!
98 : * Computes the electron fraction in beta-equilibrium \f$Y_e^{\rm eq}\f$ from
99 : * the rest mass density \f$\rho\f$ and the temperature \f$T\f$.
100 : */
101 1 : Scalar<double> equilibrium_electron_fraction_from_density_temperature(
102 : const Scalar<double>& rest_mass_density,
103 : const Scalar<double>& temperature) const override {
104 : return underlying_eos_
105 : .equilibrium_electron_fraction_from_density_temperature(
106 : rest_mass_density, temperature);
107 : }
108 :
109 1 : Scalar<DataVector> equilibrium_electron_fraction_from_density_temperature(
110 : const Scalar<DataVector>& rest_mass_density,
111 : const Scalar<DataVector>& temperature) const override {
112 : return underlying_eos_
113 : .equilibrium_electron_fraction_from_density_temperature(
114 : rest_mass_density, temperature);
115 : }
116 : /// @}
117 : //
118 :
119 0 : WRAPPED_PUPable_decl_base_template( // NOLINT
120 : SINGLE_ARG(EquationOfState<ColdEquilEos::is_relativistic, 3>),
121 : Barotropic3D);
122 :
123 : /// The lower bound of the electron fraction that is valid for this EOS
124 1 : double electron_fraction_lower_bound() const override { return 0.0; }
125 :
126 : /// The upper bound of the electron fraction that is valid for this EOS
127 1 : double electron_fraction_upper_bound() const override { return 1.0; }
128 :
129 : /// The lower bound of the rest mass density that is valid for this EOS
130 1 : double rest_mass_density_lower_bound() const override {
131 : return underlying_eos_.rest_mass_density_lower_bound();
132 : }
133 :
134 : /// The upper bound of the rest mass density that is valid for this EOS
135 1 : double rest_mass_density_upper_bound() const override {
136 : return underlying_eos_.rest_mass_density_upper_bound();
137 : }
138 :
139 : /// The lower bound of the temperature that is valid for this EOS
140 1 : double temperature_lower_bound() const override { return 0.0; }
141 :
142 : /// The upper bound of the temperature that is valid for this EOS
143 1 : double temperature_upper_bound() const override {
144 : return std::numeric_limits<double>::max();
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 : }
154 :
155 : /// The upper bound of the specific internal energy that is valid for this EOS
156 : /// at the given rest mass density \f$\rho\f$
157 1 : double specific_internal_energy_upper_bound(
158 : const double /*rest_mass_density*/,
159 : const double /*electron_fraction*/) const override {
160 : return underlying_eos_.specific_internal_energy_upper_bound();
161 : }
162 :
163 : /// The lower bound of the specific enthalpy that is valid for this EOS
164 1 : double specific_enthalpy_lower_bound() const override {
165 : return underlying_eos_.specific_enthalpy_lower_bound();
166 : }
167 :
168 : /// The baryon mass for this EoS
169 1 : double baryon_mass() const override { return underlying_eos_.baryon_mass(); }
170 :
171 : private:
172 : EQUATION_OF_STATE_FORWARD_DECLARE_MEMBER_IMPLS(3)
173 0 : ColdEquilEos underlying_eos_;
174 : };
175 : /// \cond
176 : template <typename ColdEquilEos>
177 : PUP::able::PUP_ID EquationsOfState::Barotropic3D<ColdEquilEos>::my_PUP_ID = 0;
178 : /// \endcond
179 : } // namespace EquationsOfState
|