BondiHoyleAccretion.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <limits>
7 
9 #include "Options/Options.hpp"
10 #include "PointwiseFunctions/AnalyticSolutions/GeneralRelativity/KerrSchild.hpp"
11 #include "PointwiseFunctions/GeneralRelativity/KerrSchildCoords.hpp"
12 #include "PointwiseFunctions/Hydro/EquationsOfState/EquationOfState.hpp"
13 #include "PointwiseFunctions/Hydro/EquationsOfState/PolytropicFluid.hpp" // IWYU pragma: keep
14 #include "PointwiseFunctions/Hydro/Tags.hpp"
15 #include "Utilities/Requires.hpp"
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 axially symmetric Bondi-Hoyle accretion.
32  *
33  * In the context of studying Bondi-Hoyle accretion, i.e. non-spherical
34  * accretion on to a Kerr black hole moving relative to a gas cloud, this class
35  * implements the method proposed by Font & Ibáñez (1998) \ref font_98 "[1]" to
36  * initialize the GRMHD variables. The fluid quantities are initialized with
37  * their (constant) values far from the black hole, e.g.
38  * \f$\rho = \rho_\infty\f$. Here we assume a
39  * polytropic equation of state, so only the rest mass density, as well as the
40  * polytropic constant and the polytropic exponent, are provided as inputs.
41  * The spatial velocity is initialized using a field that ensures that the
42  * injected gas reproduces a continuous parallel wind at large distances.
43  * The direction of this flow is chosen to be along the black hole spin.
44  * In Kerr (or "spherical Kerr-Schild", see gr::KerrSchildCoords) coordinates,
45  *
46  * \f{align*}
47  * v^r &= \frac{1}{\sqrt{\gamma_{rr}}}v_\infty \cos\theta\\
48  * v^\theta &= -\frac{1}{\sqrt{\gamma_{\theta\theta}}}v_\infty \sin\theta\\
49  * v^\phi &= 0.
50  * \f}
51  *
52  * where \f$\gamma_{ij} = g_{ij}\f$ is the spatial metric, and \f$v_\infty\f$
53  * is the flow speed far from the black hole. Note that
54  * \f$v_\infty^2 = v_i v^i\f$. Finally, following the work by
55  * Penner (2011) \ref penner_11 "[2]",
56  * the magnetic field is initialized using Wald's solution to Maxwell's
57  * equations in Kerr black hole spacetime. In Kerr ("spherical
58  * Kerr-Schild") coordinates, the spatial components of the Faraday tensor read
59  *
60  * \f{align*}
61  * F_{r\theta} &= a B_0 \left[1 + \frac{2Mr}{\Sigma^2}(r^2 - a^2)\right]
62  * \sin\theta\cos\theta\\
63  * F_{\theta\phi} &= B_0\left[\Delta +
64  * \frac{2Mr}{\Sigma^2}(r^4 - a^4)\right]\sin\theta\cos\theta\\
65  * F_{\phi r} &= - B_0\left[r + \frac{M a^2}{\Sigma^2}
66  * (r^2 - a^2\cos^2\theta)(1 + \cos^2\theta)\right]\sin^2\theta.
67  * \f}
68  *
69  * where \f$\Sigma = r^2 + a^2\cos^2\theta\f$ and \f$\Delta = r^2 - 2Mr +
70  * a^2\f$. The associated Eulerian magnetic field is
71  *
72  * \f{align*}
73  * B^r = \frac{F_{\theta\phi}}{\sqrt\gamma},\quad
74  * B^\theta = \frac{F_{\phi r}}{\sqrt\gamma},\quad
75  * B^\phi = \frac{F_{r\theta}}{\sqrt\gamma}.
76  * \f}
77  *
78  * where \f$\gamma = \text{det}(\gamma_{ij})\f$. Wald's solution reproduces a
79  * uniform magnetic field far from the black hole.
80  *
81  * \anchor font_98 [1] J.A. Font & J.M. Ibáñez, ApJ
82  * [494 (1998) 297](http://esoads.eso.org/abs/1998ApJ...494..297F)
83  *
84  * \anchor penner_11 [2] A.J. Penner, MNRAS
85  * [414 (2011) 1467](http://cdsads.u-strasbg.fr/abs/2011MNRAS.414.1467P)
86  */
90 
91  public:
92  /// The mass of the black hole, \f$M\f$.
93  struct BhMass {
94  using type = double;
95  static constexpr OptionString help = {"The mass of the black hole."};
96  static type lower_bound() noexcept { return 0.0; }
97  };
98  /// The dimensionless black hole spin, \f$a_* = a/M\f$.
99  struct BhDimlessSpin {
100  using type = double;
101  static constexpr OptionString help = {"The dimensionless black hole spin."};
102  static type lower_bound() noexcept { return -1.0; }
103  static type upper_bound() noexcept { return 1.0; }
104  };
105  /// The rest mass density of the fluid far from the black hole.
107  using type = double;
108  static constexpr OptionString help = {"The asymptotic rest mass density."};
109  static type lower_bound() noexcept { return 0.0; }
110  };
111  /// The magnitude of the spatial velocity far from the black hole.
112  struct FlowSpeed {
113  using type = double;
114  static constexpr OptionString help = {
115  "The magnitude of the asymptotic flow velocity."};
116  };
117  /// The strength of the magnetic field.
119  using type = double;
120  static constexpr OptionString help = {
121  "The strength of the magnetic field."};
122  };
123  /// The polytropic constant of the fluid.
125  using type = double;
126  static constexpr OptionString help = {
127  "The polytropic constant of the fluid."};
128  static type lower_bound() noexcept { return 0.0; }
129  };
130  /// The polytropic exponent of the fluid.
132  using type = double;
133  static constexpr OptionString help = {
134  "The polytropic exponent of the fluid."};
135  static type lower_bound() noexcept { return 1.0; }
136  };
137 
138  using options =
141 
142  static constexpr OptionString help = {
143  "Axially symmetric accretion on to a Kerr black hole."};
144 
145  BondiHoyleAccretion() = default;
146  BondiHoyleAccretion(const BondiHoyleAccretion& /*rhs*/) = delete;
147  BondiHoyleAccretion& operator=(const BondiHoyleAccretion& /*rhs*/) = delete;
148  BondiHoyleAccretion(BondiHoyleAccretion&& /*rhs*/) noexcept = default;
149  BondiHoyleAccretion& operator=(BondiHoyleAccretion&& /*rhs*/) noexcept =
150  default;
151  ~BondiHoyleAccretion() = default;
152 
153  BondiHoyleAccretion(BhMass::type bh_mass, BhDimlessSpin::type bh_dimless_spin,
154  RestMassDensity::type rest_mass_density,
155  FlowSpeed::type flow_speed,
156  MagFieldStrength::type magnetic_field_strength,
157  PolytropicConstant::type polytropic_constant,
158  PolytropicExponent::type polytropic_exponent) noexcept;
159 
160  // @{
161  /// Retrieve hydro variable at `x`
162  template <typename DataType>
163  auto variables(
164  const tnsr::I<DataType, 3>& x,
165  tmpl::list<hydro::Tags::RestMassDensity<DataType>> /*meta*/) const
167 
168  template <typename DataType>
169  auto variables(
170  const tnsr::I<DataType, 3>& x,
171  tmpl::list<hydro::Tags::SpecificInternalEnergy<DataType>> /*meta*/) const
172  noexcept
174 
175  template <typename DataType>
176  auto variables(const tnsr::I<DataType, 3>& x,
177  tmpl::list<hydro::Tags::Pressure<DataType>> /*meta*/) const
179 
180  template <typename DataType>
181  auto variables(const tnsr::I<DataType, 3>& x,
182  tmpl::list<hydro::Tags::SpatialVelocity<
183  DataType, 3, Frame::Inertial>> /*meta*/) const noexcept
186 
187  template <typename DataType>
188  auto variables(const tnsr::I<DataType, 3>& x,
189  tmpl::list<hydro::Tags::MagneticField<
190  DataType, 3, Frame::Inertial>> /*meta*/) const noexcept
193 
194  template <typename DataType>
195  auto variables(
196  const tnsr::I<DataType, 3>& x,
197  tmpl::list<hydro::Tags::DivergenceCleaningField<DataType>> /*meta*/) const
198  noexcept
200 
201  template <typename DataType>
202  auto variables(
203  const tnsr::I<DataType, 3>& x,
204  tmpl::list<hydro::Tags::LorentzFactor<DataType>> /*meta*/) const noexcept
206 
207  template <typename DataType>
208  auto variables(
209  const tnsr::I<DataType, 3>& x,
210  tmpl::list<hydro::Tags::SpecificEnthalpy<DataType>> /*meta*/) const
212  // @}
213 
214  /// Retrieve a collection of hydro variables at `x`
215  template <typename DataType, typename... Tags>
217  const tnsr::I<DataType, 3, Frame::Inertial>& x,
218  tmpl::list<Tags...> /*meta*/) const noexcept {
219  static_assert(sizeof...(Tags) > 1,
220  "The generic template will recurse infinitely if only one "
221  "tag is being retrieved.");
222  return {tuples::get<Tags>(variables(x, tmpl::list<Tags>{}))...};
223  }
224 
225  /// Retrieve the metric variables at `x`
226  template <typename DataType, typename Tag,
228  Tag>> = nullptr>
229  tuples::TaggedTuple<Tag> variables(const tnsr::I<DataType, 3>& x,
230  tmpl::list<Tag> /*meta*/) const noexcept {
231  constexpr double dummy_time = 0.0;
232  return {std::move(get<Tag>(background_spacetime_.variables(
233  x, dummy_time, gr::Solutions::KerrSchild::tags<DataType>{})))};
234  }
235 
236  // clang-tidy: no runtime references
237  void pup(PUP::er& /*p*/) noexcept; // NOLINT
238 
239  const EquationsOfState::PolytropicFluid<true>& equation_of_state() const
240  noexcept {
241  return equation_of_state_;
242  }
243 
244  private:
245  friend bool operator==(const BondiHoyleAccretion& lhs,
246  const BondiHoyleAccretion& rhs) noexcept;
247 
248  // compute the spatial velocity in spherical Kerr-Schild coordinates
249  template <typename DataType>
250  typename hydro::Tags::SpatialVelocity<DataType, 3, Frame::NoFrame>::type
251  spatial_velocity(const DataType& r_squared, const DataType& cos_theta,
252  const DataType& sin_theta) const noexcept;
253  // compute the magnetic field in spherical Kerr-Schild coordinates
254  template <typename DataType>
255  typename hydro::Tags::MagneticField<DataType, 3, Frame::NoFrame>::type
256  magnetic_field(const DataType& r_squared, const DataType& cos_theta,
257  const DataType& sin_theta) const noexcept;
258 
259  BhMass::type bh_mass_ = std::numeric_limits<double>::signaling_NaN();
260  BhDimlessSpin::type bh_spin_a_ = std::numeric_limits<double>::signaling_NaN();
261  RestMassDensity::type rest_mass_density_ =
263  FlowSpeed::type flow_speed_ = std::numeric_limits<double>::signaling_NaN();
264  MagFieldStrength::type magnetic_field_strength_ =
266  PolytropicConstant::type polytropic_constant_ =
268  PolytropicExponent::type polytropic_exponent_ =
270  EquationsOfState::PolytropicFluid<true> equation_of_state_{};
271  gr::Solutions::KerrSchild background_spacetime_{};
272  gr::KerrSchildCoords kerr_schild_coords_{};
273 };
274 
275 bool operator!=(const BondiHoyleAccretion& lhs,
276  const BondiHoyleAccretion& rhs) noexcept;
277 
278 } // namespace AnalyticData
279 } // namespace grmhd
The rest mass density of the fluid far from the black hole.
Definition: BondiHoyleAccretion.hpp:106
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)
The strength of the magnetic field.
Definition: BondiHoyleAccretion.hpp:118
tuples::TaggedTuple< Tag > variables(const tnsr::I< DataType, 3 > &x, tmpl::list< Tag >) const noexcept
Retrieve the metric variables at x
Definition: BondiHoyleAccretion.hpp:229
Defines classes and functions for making classes creatable from input files.
Contains helper functions for transforming tensors in Kerr spacetime to Kerr-Schild coordinates...
Definition: KerrSchildCoords.hpp:151
Defines the type alias Requires.
The magnetic field measured by an Eulerian observer, where is the normal to the spatial hypersurfac...
Definition: Tags.hpp:80
The divergence-cleaning field .
Definition: Tags.hpp:47
The mass of the black hole, .
Definition: BondiHoyleAccretion.hpp:93
Analytic initial data for axially symmetric Bondi-Hoyle accretion.
Definition: BondiHoyleAccretion.hpp:87
const char *const OptionString
The string used in option structs.
Definition: Options.hpp:27
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:272
The polytropic constant of the fluid.
Definition: BondiHoyleAccretion.hpp:124
The Lorentz factor .
Definition: Tags.hpp:64
Definition: DataBoxTag.hpp:29
Defines a list of useful type aliases for tensors.
Wraps the template metaprogramming library used (brigand)
Kerr black hole in Kerr-Schild coordinates.
Definition: KerrSchild.hpp:209
The magnitude of the spatial velocity far from the black hole.
Definition: BondiHoyleAccretion.hpp:112
tuples::TaggedTuple< Tags... > variables(const tnsr::I< DataType, 3, Frame::Inertial > &x, tmpl::list< Tags... >) const noexcept
Retrieve a collection of hydro variables at x
Definition: BondiHoyleAccretion.hpp:216
The rest-mass density .
Definition: Tags.hpp:130
typename Requires_detail::requires_impl< B >::template_error_type_failed_to_meet_requirements_on_template_parameters Requires
Express requirements on the template parameters of a function or class, replaces std::enable_if_t ...
Definition: Requires.hpp:67
Definition: IndexType.hpp:44
The specific enthalpy .
Definition: Tags.hpp:169
Items related to general relativistic magnetohydrodynamics (GRMHD)
Definition: Characteristics.hpp:34
The polytropic exponent of the fluid.
Definition: BondiHoyleAccretion.hpp:131
The dimensionless black hole spin, .
Definition: BondiHoyleAccretion.hpp:99