CylindricalBlastWave.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <array>
7 #include <limits>
8 
10 #include "Options/Options.hpp"
11 #include "PointwiseFunctions/AnalyticSolutions/GeneralRelativity/Minkowski.hpp"
12 #include "PointwiseFunctions/Hydro/EquationsOfState/EquationOfState.hpp"
13 #include "PointwiseFunctions/Hydro/EquationsOfState/IdealFluid.hpp" // IWYU pragma: keep
14 #include "PointwiseFunctions/Hydro/Tags.hpp"
15 #include "Utilities/MakeArray.hpp" // IWYU pragma: keep
16 #include "Utilities/TMPL.hpp"
18 
19 // IWYU pragma: no_include <pup.h>
20 
21 /// \cond
22 namespace PUP {
23 class er; // IWYU pragma: keep
24 } // namespace PUP
25 /// \endcond
26 
27 namespace grmhd {
28 namespace AnalyticData {
29 
30 /*!
31  * \brief Analytic initial data for a cylindrical blast wave.
32  *
33  * This class implements analytic initial data for a cylindrical blast wave,
34  * as described, e.g., in \cite Kidder2016hev Sec. 6.2.3.
35  * A uniform magnetic field threads an ideal fluid. The solution begins with
36  * material at fixed (typically high) density and pressure at rest inside a
37  * cylinder of radius \f$r < r_{\rm in}\f$ and material at fixed (typically low)
38  * density and pressure at rest in a cylindrical shell with radius
39  * \f$r > r_{\rm out}\f$. In the region \f$ r_{\rm in} < r < r_{\rm out}\f$,
40  * the solution transitions such that the logarithms of the density and
41  * pressure vary linearly. E.g., if \f$\rho(r < r_{\rm in}) = \rho_{\rm in}\f$
42  * and \f$\rho(r > r_{\rm out}) = \rho_{\rm out}\f$, then
43  * \f[
44  * \log \rho = [(r_{\rm in} - r) \log(\rho_{\rm out})
45  * + (r - r_{\rm out}) \log(\rho_{\rm in})]
46  * / (r_{\rm in} - r_{\rm out}).
47  * \f]
48  * Note that the cylinder's axis is the \f$z\f$ axis. To evolve this analytic
49  * initial data, use a cubic or cylindrical domain with periodic boundary
50  * conditions applied to the outer boundaries whose normals are parallel or
51  * antiparallel to the z axis. In the transverse (e.g., x and y) dimensions, the
52  * domain should be large enough that the blast wave doesn't reach the boundary
53  * at the final time. E.g., if `InnerRadius = 0.8`, `OuterRadius = 1.0`, and
54  * the final time is 4.0, a good domain extends from `(x,y)=(-6.0, -6.0)` to
55  * `(x,y)=(6.0, 6.0)`.
56  */
58  public:
61 
62  /// Inside InnerRadius, density is InnerDensity.
63  struct InnerRadius {
64  using type = double;
65  static constexpr OptionString help = {
66  "Inside InnerRadius, density is InnerDensity."};
67  static type lower_bound() noexcept { return 0.0; }
68  };
69  /// Outside OuterRadius, density is OuterDensity.
70  struct OuterRadius {
71  using type = double;
72  static constexpr OptionString help = {
73  "Outside OuterRadius, density is OuterDensity."};
74  static type lower_bound() noexcept { return 0.0; }
75  };
76  /// Density at radii less than InnerRadius.
77  struct InnerDensity {
78  using type = double;
79  static constexpr OptionString help = {
80  "Density at radii less than InnerRadius."};
81  static type lower_bound() noexcept { return 0.0; }
82  };
83  /// Density at radii greater than OuterRadius.
84  struct OuterDensity {
85  using type = double;
86  static constexpr OptionString help = {
87  "Density at radii greater than OuterRadius."};
88  static type lower_bound() noexcept { return 0.0; }
89  };
90  /// Pressure at radii less than InnerRadius.
91  struct InnerPressure {
92  using type = double;
93  static constexpr OptionString help = {
94  "Pressure at radii less than InnerRadius."};
95  static type lower_bound() noexcept { return 0.0; }
96  };
97  /// Pressure at radii greater than OuterRadius.
98  struct OuterPressure {
99  using type = double;
100  static constexpr OptionString help = {
101  "Pressure at radii greater than OuterRadius."};
102  static type lower_bound() noexcept { return 0.0; }
103  };
104  /// The x,y,z components of the uniform magnetic field threading the matter.
105  struct MagneticField {
106  using type = std::array<double, 3>;
107  static constexpr OptionString help = {
108  "The x,y,z components of the uniform magnetic field."};
109  };
110  /// The adiabatic index of the ideal fluid.
111  struct AdiabaticIndex {
112  using type = double;
113  static constexpr OptionString help = {
114  "The adiabatic index of the ideal fluid."};
115  static type lower_bound() noexcept { return 1.0; }
116  };
117 
118  using options =
121 
122  static constexpr OptionString help = {
123  "Cylindrical blast wave analytic initial data."};
124 
125  CylindricalBlastWave() = default;
126  CylindricalBlastWave(const CylindricalBlastWave& /*rhs*/) = delete;
127  CylindricalBlastWave& operator=(const CylindricalBlastWave& /*rhs*/) = delete;
128  CylindricalBlastWave(CylindricalBlastWave&& /*rhs*/) noexcept = default;
129  CylindricalBlastWave& operator=(CylindricalBlastWave&& /*rhs*/) noexcept =
130  default;
131  ~CylindricalBlastWave() = default;
132 
134  InnerRadius::type inner_radius, OuterRadius::type outer_radius,
135  InnerDensity::type inner_density, OuterDensity::type outer_density,
136  InnerPressure::type inner_pressure, OuterPressure::type outer_pressure,
137  MagneticField::type magnetic_field, AdiabaticIndex::type adiabatic_index,
138  const OptionContext& context = {});
139 
140  explicit CylindricalBlastWave(CkMigrateMessage* /*unused*/) noexcept {}
141 
142  // @{
143  /// Retrieve the GRMHD variables at a given position.
144  template <typename DataType>
145  auto variables(
146  const tnsr::I<DataType, 3>& x,
147  tmpl::list<hydro::Tags::RestMassDensity<DataType>> /*meta*/) const
149 
150  template <typename DataType>
151  auto variables(
152  const tnsr::I<DataType, 3>& x,
153  tmpl::list<hydro::Tags::SpecificInternalEnergy<DataType>> /*meta*/) const
154  noexcept
156 
157  template <typename DataType>
158  auto variables(const tnsr::I<DataType, 3>& x,
159  tmpl::list<hydro::Tags::Pressure<DataType>> /*meta*/) const
161 
162  template <typename DataType>
163  auto variables(const tnsr::I<DataType, 3>& x,
164  tmpl::list<hydro::Tags::SpatialVelocity<
165  DataType, 3, Frame::Inertial>> /*meta*/) const noexcept
168 
169  template <typename DataType>
170  auto variables(const tnsr::I<DataType, 3>& x,
171  tmpl::list<hydro::Tags::MagneticField<
172  DataType, 3, Frame::Inertial>> /*meta*/) const noexcept
175 
176  template <typename DataType>
177  auto variables(
178  const tnsr::I<DataType, 3>& x,
179  tmpl::list<hydro::Tags::DivergenceCleaningField<DataType>> /*meta*/) const
180  noexcept
182 
183  template <typename DataType>
184  auto variables(
185  const tnsr::I<DataType, 3>& x,
186  tmpl::list<hydro::Tags::LorentzFactor<DataType>> /*meta*/) const noexcept
188 
189  template <typename DataType>
190  auto variables(
191  const tnsr::I<DataType, 3>& x,
192  tmpl::list<hydro::Tags::SpecificEnthalpy<DataType>> /*meta*/) const
194  // @}
195 
196  /// Retrieve a collection of hydrodynamic variables at position x
197  template <typename DataType, typename... Tags>
199  const tnsr::I<DataType, 3, Frame::Inertial>& x,
200  tmpl::list<Tags...> /*meta*/) const noexcept {
201  static_assert(sizeof...(Tags) > 1,
202  "The generic template will recurse infinitely if only one "
203  "tag is being retrieved.");
204  return {tuples::get<Tags>(variables(x, tmpl::list<Tags>{}))...};
205  }
206 
207  /// Retrieve the metric variables
208  template <typename DataType, typename Tag>
209  tuples::TaggedTuple<Tag> variables(const tnsr::I<DataType, 3>& x,
210  tmpl::list<Tag> /*meta*/) const noexcept {
211  constexpr double dummy_time = 0.0;
212  return background_spacetime_.variables(x, dummy_time, tmpl::list<Tag>{});
213  }
214 
215  const EquationsOfState::IdealFluid<true>& equation_of_state() const noexcept {
216  return equation_of_state_;
217  }
218 
219  // clang-tidy: no runtime references
220  void pup(PUP::er& /*p*/) noexcept; // NOLINT
221 
222  private:
223  InnerRadius::type inner_radius_ =
225  OuterRadius::type outer_radius_ =
227  InnerDensity::type inner_density_ =
229  OuterDensity::type outer_density_ =
231  InnerPressure::type inner_pressure_ =
233  OuterPressure::type outer_pressure_ =
235  MagneticField::type magnetic_field_ =
239  AdiabaticIndex::type adiabatic_index_ =
241  EquationsOfState::IdealFluid<true> equation_of_state_{};
242  gr::Solutions::Minkowski<3> background_spacetime_{};
243 
244  friend bool operator==(const CylindricalBlastWave& lhs,
245  const CylindricalBlastWave& rhs) noexcept;
246 
247  friend bool operator!=(const CylindricalBlastWave& lhs,
248  const CylindricalBlastWave& rhs) noexcept;
249 };
250 
251 } // namespace AnalyticData
252 } // namespace grmhd
Definition: Strahlkorper.hpp:14
Defines class tuples::TaggedTuple.
The spatial velocity .
Definition: Tags.hpp:144
The fluid pressure .
Definition: Tags.hpp:123
The specific internal energy .
Definition: Tags.hpp:176
T signaling_NaN(T... args)
Defines function make_array.
Defines classes and functions for making classes creatable from input files.
The magnetic field measured by an Eulerian observer, where is the normal to the spatial hypersurfac...
Definition: Tags.hpp:80
Density at radii less than InnerRadius.
Definition: CylindricalBlastWave.hpp:77
The divergence-cleaning field .
Definition: Tags.hpp:47
Pressure at radii greater than OuterRadius.
Definition: CylindricalBlastWave.hpp:98
auto variables(const tnsr::I< DataType, 3 > &x, tmpl::list< hydro::Tags::RestMassDensity< DataType >>) const noexcept -> tuples::TaggedTuple< hydro::Tags::RestMassDensity< DataType >>
Retrieve the GRMHD variables at a given position.
const char *const OptionString
The string used in option structs.
Definition: Options.hpp:26
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:272
Outside OuterRadius, density is OuterDensity.
Definition: CylindricalBlastWave.hpp:70
The adiabatic index of the ideal fluid.
Definition: CylindricalBlastWave.hpp:111
Analytic initial data for a cylindrical blast wave.
Definition: CylindricalBlastWave.hpp:57
The Lorentz factor .
Definition: Tags.hpp:64
Definition: DataBoxTag.hpp:29
tuples::TaggedTuple< Tags... > variables(const tnsr::I< DataType, 3, Frame::Inertial > &x, tmpl::list< Tags... >) const noexcept
Retrieve a collection of hydrodynamic variables at position x.
Definition: CylindricalBlastWave.hpp:198
Density at radii greater than OuterRadius.
Definition: CylindricalBlastWave.hpp:84
Defines a list of useful type aliases for tensors.
tuples::TaggedTuple< Tag > variables(const tnsr::I< DataType, 3 > &x, tmpl::list< Tag >) const noexcept
Retrieve the metric variables.
Definition: CylindricalBlastWave.hpp:209
Information about the nested operations being performed by the parser, for use in printing errors...
Definition: Options.hpp:35
Wraps the template metaprogramming library used (brigand)
Pressure at radii less than InnerRadius.
Definition: CylindricalBlastWave.hpp:91
The rest-mass density .
Definition: Tags.hpp:130
Definition: IndexType.hpp:44
Inside InnerRadius, density is InnerDensity.
Definition: CylindricalBlastWave.hpp:63
The x,y,z components of the uniform magnetic field threading the matter.
Definition: CylindricalBlastWave.hpp:105
The specific enthalpy .
Definition: Tags.hpp:169
Items related to general relativistic magnetohydrodynamics (GRMHD)
Definition: Characteristics.hpp:34