MagnetizedFmDisk.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 #include <limits>
8 
10 #include "Options/Options.hpp"
11 #include "PointwiseFunctions/AnalyticSolutions/RelativisticEuler/FishboneMoncriefDisk.hpp"
12 #include "PointwiseFunctions/GeneralRelativity/KerrSchildCoords.hpp"
13 #include "PointwiseFunctions/Hydro/EquationsOfState/PolytropicFluid.hpp" // IWYU pragma: keep
14 #include "PointwiseFunctions/Hydro/Tags.hpp"
15 #include "Utilities/TMPL.hpp"
17 
18 // IWYU pragma: no_include <pup.h>
19 
20 /// \cond
21 namespace PUP {
22 class er; // IWYU pragma: keep
23 } // namespace PUP
24 /// \endcond
25 
26 namespace grmhd {
27 namespace AnalyticData {
28 
29 /*!
30  * \brief Magnetized fluid disk orbiting a Kerr black hole.
31  *
32  * In the context of simulating accretion disks, this class implements a widely
33  * used (e.g. \cite Gammie2003, \cite Porth2016rfi, \cite White2015omx)
34  * initial setup for the GRMHD variables, consisting of a Fishbone-Moncrief disk
35  * \cite Fishbone1976apj (see also
36  * RelativisticEuler::Solutions::FishboneMoncriefDisk),
37  * threaded by a weak poloidal magnetic field. The magnetic field is constructed
38  * from an axially symmetric toroidal magnetic potential which, in Kerr
39  * ("spherical Kerr-Schild") coordinates, has the form
40  *
41  * \f{align*}
42  * A_\phi(r,\theta) \propto \text{max}(\rho(r,\theta) - \rho_\text{thresh}, 0),
43  * \f}
44  *
45  * where \f$\rho_\text{thresh}\f$ is a user-specified threshold density that
46  * confines the magnetic flux to exist inside of the fluid disk only. A commonly
47  * used value for this parameter is
48  * \f$\rho_\text{thresh} = 0.2\rho_\text{max}\f$, where \f$\rho_\text{max}\f$
49  * is the maximum value of
50  * the rest mass density in the disk. Using this potential, the Eulerian
51  * magnetic field takes the form
52  *
53  * \f{align*}
54  * B^r = \frac{F_{\theta\phi}}{\sqrt{\gamma}},\quad
55  * B^\theta = \frac{F_{\phi r}}{\sqrt{\gamma}},\quad B^\phi = 0,
56  * \f}
57  *
58  * where \f$F_{ij} = \partial_i A_j - \partial_j A_i\f$ are the spatial
59  * components of the Faraday tensor, and \f$\gamma\f$ is the determinant of the
60  * spatial metric. The magnetic field is then normalized so that the
61  * plasma-\f$\beta\f$ parameter, \f$\beta = 2p/b^2\f$, equals some value
62  * specified by the user. Here, \f$p\f$ is the fluid pressure, and
63  *
64  * \f{align*}
65  * b^2 = b^\mu b_\mu = \frac{B_iB^i}{W^2} + (B^iv_i)^2
66  * \f}
67  *
68  * is the norm of the magnetic field in the fluid frame, with \f$v_i\f$ being
69  * the spatial velocity, and \f$W\f$ the Lorentz factor.
70  */
73  private:
75 
76  public:
77  /// The rest mass density (in units of the maximum rest mass density in the
78  /// disk) below which the matter in the disk is initially unmagetized.
80  using type = double;
81  static constexpr OptionString help = {
82  "Frac. rest mass density below which B-field vanishes."};
83  static type lower_bound() { return 0.0; }
84  static type upper_bound() { return 1.0; }
85  };
86  /// The maximum-magnetic-pressure-to-maximum-fluid-pressure ratio.
88  using type = double;
89  static constexpr OptionString help = {
90  "Ratio of max magnetic pressure to max fluid pressure."};
91  static type lower_bound() { return 0.0; }
92  };
93  /// Grid resolution used in magnetic field normalization.
95  using type = size_t;
96  static constexpr OptionString help = {
97  "Grid Resolution for b-field normalization."};
98  static type default_value() { return 255; }
99  static type lower_bound() { return 4; }
100  };
101 
102  using options = tmpl::push_back<fm_disk::options, ThresholdDensity,
104 
105  static constexpr OptionString help = {"Magnetized Fishbone-Moncrief disk."};
106 
107  MagnetizedFmDisk() = default;
108  MagnetizedFmDisk(const MagnetizedFmDisk& /*rhs*/) = delete;
109  MagnetizedFmDisk& operator=(const MagnetizedFmDisk& /*rhs*/) = delete;
110  MagnetizedFmDisk(MagnetizedFmDisk&& /*rhs*/) noexcept = default;
111  MagnetizedFmDisk& operator=(MagnetizedFmDisk&& /*rhs*/) noexcept = default;
112  ~MagnetizedFmDisk() = default;
113 
114  MagnetizedFmDisk(double bh_mass, double bh_dimless_spin,
115  double inner_edge_radius, double max_pressure_radius,
116  double polytropic_constant, double polytropic_exponent,
117  double threshold_density, double inverse_plasma_beta,
118  size_t normalization_grid_res =
119  BFieldNormGridRes::default_value()) noexcept;
120 
121  // Overload the variables function from the base class.
122  using fm_disk::variables;
123 
124  // @{
125  /// The grmhd variables in Cartesian Kerr-Schild coordinates at `(x, t)`
126  ///
127  /// \note The functions are optimized for retrieving the hydro variables
128  /// before the metric variables.
129  template <typename DataType, typename... Tags>
130  tuples::TaggedTuple<Tags...> variables(const tnsr::I<DataType, 3>& x,
131  tmpl::list<Tags...> /*meta*/) const
132  noexcept {
133  // Can't store IntermediateVariables as member variable because we
134  // need to be threadsafe.
135  constexpr double dummy_time = 0.0;
137  DataType,
139  cpp17::is_same_v<Tags, hydro::Tags::SpatialVelocity<DataType, 3>> or
140  cpp17::is_same_v<Tags, hydro::Tags::LorentzFactor<DataType>> or
141  not tmpl::list_contains_v<hydro::grmhd_tags<DataType>, Tags>)...>>
142  vars(bh_spin_a_, background_spacetime_, x, dummy_time,
143  index_helper(
144  tmpl::index_of<tmpl::list<Tags...>,
146  index_helper(
147  tmpl::index_of<tmpl::list<Tags...>,
149  return {std::move(get<Tags>(
150  variables(x, tmpl::list<Tags>{}, vars,
151  tmpl::index_of<tmpl::list<Tags...>, Tags>::value)))...};
152  }
153 
154  template <typename DataType, typename Tag>
155  tuples::TaggedTuple<Tag> variables(const tnsr::I<DataType, 3>& x,
156  tmpl::list<Tag> /*meta*/) const noexcept {
157  // Can't store IntermediateVariables as member variable because we need to
158  // be threadsafe.
159  constexpr double dummy_time = 0.0;
161  DataType,
162  cpp17::is_same_v<Tag, hydro::Tags::SpatialVelocity<DataType, 3>> or
163  cpp17::is_same_v<Tag, hydro::Tags::LorentzFactor<DataType>> or
164  not tmpl::list_contains_v<hydro::grmhd_tags<DataType>, Tag>>
165  intermediate_vars(bh_spin_a_, background_spacetime_, x, dummy_time,
168  return variables(x, tmpl::list<Tag>{}, intermediate_vars, 0);
169  }
170  // @}
171 
172  // clang-tidy: no runtime references
173  void pup(PUP::er& /*p*/) noexcept; // NOLINT
174 
175  private:
176  template <typename DataType, bool NeedSpacetime>
177  auto variables(
178  const tnsr::I<DataType, 3>& x,
179  tmpl::list<
182  size_t index) const noexcept
185 
186  template <typename DataType>
187  tnsr::I<DataType, 3, Frame::Inertial> unnormalized_magnetic_field(
188  const tnsr::I<DataType, 3, Frame::Inertial>& x) const noexcept;
189 
190  friend bool operator==(const MagnetizedFmDisk& lhs,
191  const MagnetizedFmDisk& rhs) noexcept;
192 
193  double threshold_density_ = std::numeric_limits<double>::signaling_NaN();
194  double inverse_plasma_beta_ = std::numeric_limits<double>::signaling_NaN();
195  double b_field_normalization_ = std::numeric_limits<double>::signaling_NaN();
196  size_t normalization_grid_res_ = 255;
197  gr::KerrSchildCoords kerr_schild_coords_{};
198 };
199 
200 bool operator!=(const MagnetizedFmDisk& lhs,
201  const MagnetizedFmDisk& rhs) noexcept;
202 
203 } // namespace AnalyticData
204 } // namespace grmhd
The rest mass density (in units of the maximum rest mass density in the disk) below which the matter ...
Definition: MagnetizedFmDisk.hpp:79
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, tmpl::list< Tags... >) const noexcept
The grmhd variables in Cartesian Kerr-Schild coordinates at (x, t)
Definition: MagnetizedFmDisk.hpp:130
Grid resolution used in magnetic field normalization.
Definition: MagnetizedFmDisk.hpp:94
constexpr bool flat_any_v
A non-short-circuiting logical OR between bools &#39;B"".
Definition: TMPL.hpp:528
T signaling_NaN(T... args)
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
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:27
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:272
The Lorentz factor , where is the spatial velocity of the fluid.
Definition: Tags.hpp:68
Definition: DataBoxTag.hpp:29
tuples::TaggedTuple< Tag > variables(const tnsr::I< DataType, 3 > &x, tmpl::list< Tag >) const noexcept
The grmhd variables in Cartesian Kerr-Schild coordinates at (x, t)
Definition: MagnetizedFmDisk.hpp:155
Defines a list of useful type aliases for tensors.
Fluid disk orbiting a Kerr black hole.
Definition: FishboneMoncriefDisk.hpp:151
Magnetized fluid disk orbiting a Kerr black hole.
Definition: MagnetizedFmDisk.hpp:71
Wraps the template metaprogramming library used (brigand)
The maximum-magnetic-pressure-to-maximum-fluid-pressure ratio.
Definition: MagnetizedFmDisk.hpp:87
Items related to general relativistic magnetohydrodynamics (GRMHD)
Definition: Characteristics.hpp:34