TovStar.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <boost/preprocessor/list/for_each.hpp>
7 #include <boost/preprocessor/tuple/to_list.hpp>
8 #include <limits>
9 
12 #include "Options/Options.hpp"
13 #include "PointwiseFunctions/GeneralRelativity/Tags.hpp" // IWYU pragma: keep
14 #include "PointwiseFunctions/Hydro/EquationsOfState/EquationOfState.hpp"
15 #include "PointwiseFunctions/Hydro/EquationsOfState/PolytropicFluid.hpp" // IWYU pragma: keep
16 #include "PointwiseFunctions/Hydro/Tags.hpp" // IWYU pragma: keep
18 #include "Utilities/TMPL.hpp"
20 
21 /// \cond
22 namespace PUP {
23 class er; // IWYU pragma: keep
24 } // namespace PUP
25 /// \endcond
26 
27 // IWYU pragma: no_include <pup.h>
28 
29 // IWYU pragma: no_include "Utilities/GenerateInstantiations.hpp"
30 
31 namespace RelativisticEuler {
32 namespace Solutions {
33 
34 /*!
35  * \brief A static spherically symmetric star
36  *
37  * An analytic solution for a static, spherically-symmetric star found by
38  * solving the Tolman-Oppenheimer-Volkoff (TOV) equations. The equation of
39  * state is assumed to be that of a polytropic fluid.
40  *
41  * \tparam RadialSolution selects not only how the TOV equations are solved, but
42  * also the radial coordinate that the solution is given in (e.g. areal or
43  * isotropic). See the documentation of the specific `RadialSolution`s for
44  * more details.
45  */
46 template <typename RadialSolution>
47 class TovStar {
48  public:
49  /*!
50  * \brief The radial variables needed to compute the full `TOVStar` solution
51  *
52  * RadialSolution must provide a method that fills the radial variables
53  * given the equation of state and the Cartesian coordinates \f$x^i\f$
54  *
55  * If the spherically symmetric metric is written as
56  *
57  * \f[
58  * ds^2 = - e^{2 \Phi_t} dt^2 + e^{2 \Phi_r} dr^2 + e^{2 \Phi_\Omega} r^2
59  * d\Omega^2
60  * \f]
61  *
62  * where \f$r = \delta_{mn} x^m x^n\f$ is the `radial_coordinate` and
63  * \f$\Phi_t\f$, \f$\Phi_r\f$, and \f$\Phi_\Omega\f$ are respectvely the
64  * `metric_time_potential`, `metric_radial_potential`, and
65  * `metric_angular_potential`, then the lapse, shift, and spatial metric in
66  * the Cartesian coordinates are
67  *
68  * \f{align*}
69  * \alpha &= e^{\Phi_t} \\
70  * \beta^i &= 0 \\
71  * \gamma_{ij} &= \delta_{ij} e^{2 \Phi_r} + \delta_{im} \delta_{jn}
72  * \frac{x^m x^n}{r^2} \left( e^{2 \Phi_r} - e^{2 \Phi_\Omega} \right)
73  * \f}
74  *
75  */
76  template <typename DataType>
77  struct RadialVariables {
78  explicit RadialVariables(DataType radial_coordinate_in)
79  : radial_coordinate(std::move(radial_coordinate_in)),
80  rest_mass_density(
81  make_with_value<Scalar<DataType>>(radial_coordinate, 0.0)),
82  pressure(make_with_value<Scalar<DataType>>(radial_coordinate, 0.0)),
83  specific_internal_energy(
84  make_with_value<Scalar<DataType>>(radial_coordinate, 0.0)),
86  make_with_value<Scalar<DataType>>(radial_coordinate, 0.0)),
87  metric_time_potential(
88  make_with_value<DataType>(radial_coordinate, 0.0)),
89  dr_metric_time_potential(
90  make_with_value<DataType>(radial_coordinate, 0.0)),
91  metric_radial_potential(
92  make_with_value<DataType>(radial_coordinate, 0.0)),
93  dr_metric_radial_potential(
94  make_with_value<DataType>(radial_coordinate, 0.0)),
95  metric_angular_potential(
96  make_with_value<DataType>(radial_coordinate, 0.0)),
97  dr_metric_angular_potential(
98  make_with_value<DataType>(radial_coordinate, 0.0)) {}
99  DataType radial_coordinate{};
100  Scalar<DataType> rest_mass_density{};
101  Scalar<DataType> pressure{};
102  Scalar<DataType> specific_internal_energy{};
104  DataType metric_time_potential{};
105  DataType dr_metric_time_potential{};
106  DataType metric_radial_potential{};
107  DataType dr_metric_radial_potential{};
108  DataType metric_angular_potential{};
109  DataType dr_metric_angular_potential{};
110  };
111 
113 
114  /// The central density of the star.
115  struct CentralDensity {
116  using type = double;
117  static constexpr OptionString help = {"The central density of the star."};
118  static type lower_bound() noexcept { return 0.; }
119  };
120 
121  /// The polytropic constant of the polytropic fluid.
123  using type = double;
124  static constexpr OptionString help = {
125  "The polytropic constant of the fluid."};
126  static type lower_bound() noexcept { return 0.; }
127  };
128 
129  /// The polytropic exponent of the polytropic fluid.
131  using type = double;
132  static constexpr OptionString help = {
133  "The polytropic exponent of the fluid."};
134  static type lower_bound() noexcept { return 1.; }
135  };
136 
137  using options =
138  tmpl::list<CentralDensity, PolytropicConstant, PolytropicExponent>;
139 
140  static constexpr OptionString help = {
141  "A static, spherically-symmetric star found by solving the \n"
142  "Tolman-Oppenheimer-Volkoff (TOV) equations, with a given central \n"
143  "density and polytropic fluid."};
144 
145  TovStar() = default;
146  TovStar(const TovStar& /*rhs*/) = delete;
147  TovStar& operator=(const TovStar& /*rhs*/) = delete;
148  TovStar(TovStar&& /*rhs*/) noexcept = default;
149  TovStar& operator=(TovStar&& /*rhs*/) noexcept = default;
150  ~TovStar() = default;
151 
152  TovStar(double central_rest_mass_density, double polytropic_constant,
153  double polytropic_exponent) noexcept;
154 
155  /// Retrieve a collection of variables at `(x, t)`
156  template <typename DataType, typename... Tags>
157  tuples::TaggedTuple<Tags...> variables(const tnsr::I<DataType, 3>& x,
158  const double /*t*/,
159  tmpl::list<Tags...> /*meta*/) const
160  noexcept {
161  auto radial_vars =
162  radial_tov_solution().radial_variables(equation_of_state_, x);
163  return {get<Tags>(variables(x, tmpl::list<Tags>{}, radial_vars))...};
164  }
165 
166  // clang-tidy: no runtime references
167  void pup(PUP::er& /*p*/) noexcept; // NOLINT
168 
169  const EquationsOfState::PolytropicFluid<true>& equation_of_state() const
170  noexcept {
171  return equation_of_state_;
172  }
173 
174  private:
175  friend bool operator==(const TovStar& lhs, const TovStar& rhs) noexcept {
176  // there is no comparison operator for the EoS, but should be okay as
177  // the `polytropic_exponent`s and `polytropic_constant`s are compared
178  return lhs.central_rest_mass_density_ == rhs.central_rest_mass_density_ and
179  lhs.polytropic_constant_ == rhs.polytropic_constant_ and
180  lhs.polytropic_exponent_ == rhs.polytropic_exponent_;
181  }
182 
183  const RadialSolution& radial_tov_solution() const noexcept;
184 
185  template <typename DataType>
186  using SpatialVelocity =
188 
189  template <typename DataType>
190  using MagneticField =
192 
193  template <typename DataType>
194  using DerivLapse = ::Tags::deriv<gr::Tags::Lapse<DataType>, tmpl::size_t<3>,
196 
197  template <typename DataType>
199 
200  template <typename DataType>
201  using DerivShift =
202  ::Tags::deriv<gr::Tags::Shift<3, Frame::Inertial, DataType>,
203  tmpl::size_t<3>, Frame::Inertial>;
204 
205  template <typename DataType>
207 
208  template <typename DataType>
209  using DerivSpatialMetric =
210  ::Tags::deriv<gr::Tags::SpatialMetric<3, Frame::Inertial, DataType>,
211  tmpl::size_t<3>, Frame::Inertial>;
212 
213  template <typename DataType>
214  using InverseSpatialMetric =
216 
217  template <typename DataType>
218  using ExtrinsicCurvature =
220 
221 #define FUNC_DECL(r, data, elem) \
222  template <typename DataType> \
223  tuples::TaggedTuple<elem> variables( \
224  const tnsr::I<DataType, 3>& x, tmpl::list<elem> /*meta*/, \
225  const RadialVariables<DataType>& radial_vars) const noexcept;
226 
227 #define MY_LIST \
228  BOOST_PP_TUPLE_TO_LIST( \
229  17, (hydro::Tags::RestMassDensity<DataType>, \
230  hydro::Tags::SpecificInternalEnergy<DataType>, \
231  hydro::Tags::Pressure<DataType>, SpatialVelocity<DataType>, \
232  MagneticField<DataType>, \
233  hydro::Tags::DivergenceCleaningField<DataType>, \
234  hydro::Tags::LorentzFactor<DataType>, \
235  hydro::Tags::SpecificEnthalpy<DataType>, gr::Tags::Lapse<DataType>, \
236  DerivLapse<DataType>, Shift<DataType>, DerivShift<DataType>, \
237  SpatialMetric<DataType>, DerivSpatialMetric<DataType>, \
238  gr::Tags::SqrtDetSpatialMetric<DataType>, \
239  InverseSpatialMetric<DataType>, ExtrinsicCurvature<DataType>))
240 
241  BOOST_PP_LIST_FOR_EACH(FUNC_DECL, _, MY_LIST)
242 #undef MY_LIST
243 #undef FUNC_DECL
244 
245  double central_rest_mass_density_ =
247  double polytropic_constant_ = std::numeric_limits<double>::signaling_NaN();
248  double polytropic_exponent_ = std::numeric_limits<double>::signaling_NaN();
249  EquationsOfState::PolytropicFluid<true> equation_of_state_{};
250 };
251 
252 template <typename RadialSolution>
253 bool operator!=(const TovStar<RadialSolution>& lhs,
254  const TovStar<RadialSolution>& rhs) noexcept;
255 
256 } // namespace Solutions
257 } // namespace RelativisticEuler
The central density of the star.
Definition: TovStar.hpp:115
Definition: Strahlkorper.hpp:14
Defines class tuples::TaggedTuple.
The spatial velocity of the fluid, where . Here is the spatial part of the 4-velocity of the fluid...
Definition: Tags.hpp:156
tuples::TaggedTuple< Tags... > variables(const tnsr::I< DataType, 3 > &x, const double, tmpl::list< Tags... >) const noexcept
Retrieve a collection of variables at (x, t)
Definition: TovStar.hpp:157
T signaling_NaN(T... args)
A static spherically symmetric star.
Definition: TovStar.hpp:47
Items related to evolving the relativistic Euler system.
Definition: Characteristics.hpp:21
The radial variables needed to compute the full TOVStar solution.
Definition: TovStar.hpp:77
Defines classes and functions for making classes creatable from input files.
Inverse of the spatial metric.
Definition: Tags.hpp:36
The polytropic exponent of the polytropic fluid.
Definition: TovStar.hpp:130
Scalar< DataType > specific_enthalpy(const Scalar< DataType > &rest_mass_density, const Scalar< DataType > &specific_internal_energy, const Scalar< DataType > &pressure) noexcept
Computes the relativistic specific enthalpy as: where is the specific internal energy...
The magnetic field measured by an Eulerian observer, where is the normal to the spatial hypersurfac...
Definition: Tags.hpp:86
const char *const OptionString
The string used in option structs.
Definition: Options.hpp:29
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:272
std::remove_const_t< R > make_with_value(const T &input, const ValueType &value) noexcept
Given an object of type T, create an object of type R whose elements are initialized to value...
Definition: MakeWithValue.hpp:42
Definition: Tags.hpp:28
Defines functions computing partial derivatives.
Definition: Tags.hpp:54
Definition: DataBoxTag.hpp:29
The polytropic constant of the polytropic fluid.
Definition: TovStar.hpp:122
Defines a list of useful type aliases for tensors.
Wraps the template metaprogramming library used (brigand)
Definition: IndexType.hpp:44
Tensor< T, Symmetry<>, index_list<> > Scalar
Scalar type.
Definition: TypeAliases.hpp:21
Defines make_with_value.
Definition: Tags.hpp:148