SpECTRE Documentation Coverage Report
Current view: top level - PointwiseFunctions/AnalyticData/GrMhd - BondiHoyleAccretion.hpp Hit Total Coverage
Commit: aabde07399ba7837e5db64eedfd0a21f31f96922 Lines: 20 68 29.4 %
Date: 2024-04-26 02:38:13
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : #pragma once
       5             : 
       6             : #include <limits>
       7             : 
       8             : #include "DataStructures/Tensor/TypeAliases.hpp"
       9             : #include "Options/String.hpp"
      10             : #include "PointwiseFunctions/AnalyticData/AnalyticData.hpp"
      11             : #include "PointwiseFunctions/AnalyticData/GrMhd/AnalyticData.hpp"
      12             : #include "PointwiseFunctions/AnalyticSolutions/GeneralRelativity/KerrSchild.hpp"
      13             : #include "PointwiseFunctions/GeneralRelativity/KerrSchildCoords.hpp"
      14             : #include "PointwiseFunctions/Hydro/EquationsOfState/PolytropicFluid.hpp"  // IWYU pragma: keep
      15             : #include "PointwiseFunctions/Hydro/TagsDeclarations.hpp"
      16             : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp"
      17             : #include "Utilities/Requires.hpp"
      18             : #include "Utilities/Serialization/CharmPupable.hpp"
      19             : #include "Utilities/TMPL.hpp"
      20             : #include "Utilities/TaggedTuple.hpp"
      21             : 
      22             : // IWYU pragma:  no_include <pup.h>
      23             : 
      24             : /// \cond
      25             : namespace PUP {
      26             : class er;  // IWYU pragma: keep
      27             : }  // namespace PUP
      28             : /// \endcond
      29             : 
      30             : namespace grmhd::AnalyticData {
      31             : 
      32             : /*!
      33             :  * \brief Analytic initial data for axially symmetric Bondi-Hoyle accretion.
      34             :  *
      35             :  * In the context of studying Bondi-Hoyle accretion, i.e. non-spherical
      36             :  * accretion on to a Kerr black hole moving relative to a gas cloud, this class
      37             :  * implements the method proposed by \cite Font1998 to initialize the GRMHD
      38             :  * variables. The fluid quantities are initialized with their (constant) values
      39             :  * far from the black hole, e.g. \f$\rho = \rho_\infty\f$. Here we assume a
      40             :  * polytropic equation of state, so only the rest mass density, as well as the
      41             :  * polytropic constant and the polytropic exponent, are provided as inputs.
      42             :  * The spatial velocity is initialized using a field that ensures that the
      43             :  * injected gas reproduces a continuous parallel wind at large distances.
      44             :  * The direction of this flow is chosen to be along the black hole spin.
      45             :  * In Kerr (or "spherical Kerr-Schild", see gr::KerrSchildCoords) coordinates,
      46             :  *
      47             :  * \f{align*}
      48             :  * v^r &= \frac{1}{\sqrt{\gamma_{rr}}}v_\infty \cos\theta\\
      49             :  * v^\theta &= -\frac{1}{\sqrt{\gamma_{\theta\theta}}}v_\infty \sin\theta\\
      50             :  * v^\phi &= 0.
      51             :  * \f}
      52             :  *
      53             :  * where \f$\gamma_{ij} = g_{ij}\f$ is the spatial metric, and \f$v_\infty\f$
      54             :  * is the flow speed far from the black hole. Note that
      55             :  * \f$v_\infty^2 = v_i v^i\f$. Finally, following the work by \cite Penner2011,
      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           1 : class BondiHoyleAccretion : public virtual evolution::initial_data::InitialData,
      82             :                             public MarkAsAnalyticData,
      83             :                             public AnalyticDataBase {
      84             :  public:
      85           0 :   using equation_of_state_type = EquationsOfState::PolytropicFluid<true>;
      86             : 
      87             :   /// The mass of the black hole, \f$M\f$.
      88           1 :   struct BhMass {
      89           0 :     using type = double;
      90           0 :     static constexpr Options::String help = {"The mass of the black hole."};
      91           0 :     static type lower_bound() { return 0.0; }
      92             :   };
      93             :   /// The dimensionless black hole spin, \f$a_* = a/M\f$.
      94           1 :   struct BhDimlessSpin {
      95           0 :     using type = double;
      96           0 :     static constexpr Options::String help = {
      97             :         "The dimensionless black hole spin."};
      98           0 :     static type lower_bound() { return -1.0; }
      99           0 :     static type upper_bound() { return 1.0; }
     100             :   };
     101             :   /// The rest mass density of the fluid far from the black hole.
     102           1 :   struct RestMassDensity {
     103           0 :     using type = double;
     104           0 :     static constexpr Options::String help = {
     105             :         "The asymptotic rest mass density."};
     106           0 :     static type lower_bound() { return 0.0; }
     107             :   };
     108             :   /// The magnitude of the spatial velocity far from the black hole.
     109           1 :   struct FlowSpeed {
     110           0 :     using type = double;
     111           0 :     static constexpr Options::String help = {
     112             :         "The magnitude of the asymptotic flow velocity."};
     113             :   };
     114             :   /// The strength of the magnetic field.
     115           1 :   struct MagFieldStrength {
     116           0 :     using type = double;
     117           0 :     static constexpr Options::String help = {
     118             :         "The strength of the magnetic field."};
     119             :   };
     120             :   /// The polytropic constant of the fluid.
     121           1 :   struct PolytropicConstant {
     122           0 :     using type = double;
     123           0 :     static constexpr Options::String help = {
     124             :         "The polytropic constant of the fluid."};
     125           0 :     static type lower_bound() { return 0.0; }
     126             :   };
     127             :   /// The polytropic exponent of the fluid.
     128           1 :   struct PolytropicExponent {
     129           0 :     using type = double;
     130           0 :     static constexpr Options::String help = {
     131             :         "The polytropic exponent of the fluid."};
     132           0 :     static type lower_bound() { return 1.0; }
     133             :   };
     134             : 
     135           0 :   using options =
     136             :       tmpl::list<BhMass, BhDimlessSpin, RestMassDensity, FlowSpeed,
     137             :                  MagFieldStrength, PolytropicConstant, PolytropicExponent>;
     138             : 
     139           0 :   static constexpr Options::String help = {
     140             :       "Axially symmetric accretion on to a Kerr black hole."};
     141             : 
     142           0 :   BondiHoyleAccretion() = default;
     143           0 :   BondiHoyleAccretion(const BondiHoyleAccretion& /*rhs*/) = default;
     144           0 :   BondiHoyleAccretion& operator=(const BondiHoyleAccretion& /*rhs*/) = default;
     145           0 :   BondiHoyleAccretion(BondiHoyleAccretion&& /*rhs*/) = default;
     146           0 :   BondiHoyleAccretion& operator=(BondiHoyleAccretion&& /*rhs*/) = default;
     147           0 :   ~BondiHoyleAccretion() override = default;
     148             : 
     149           0 :   BondiHoyleAccretion(double bh_mass, double bh_dimless_spin,
     150             :                       double rest_mass_density, double flow_speed,
     151             :                       double magnetic_field_strength,
     152             :                       double polytropic_constant, double polytropic_exponent);
     153             : 
     154           0 :   auto get_clone() const
     155             :       -> std::unique_ptr<evolution::initial_data::InitialData> override;
     156             : 
     157             :   /// \cond
     158             :   explicit BondiHoyleAccretion(CkMigrateMessage* msg);
     159             :   using PUP::able::register_constructor;
     160             :   WRAPPED_PUPable_decl_template(BondiHoyleAccretion);
     161             :   /// \endcond
     162             : 
     163             :   /// @{
     164             :   /// Retrieve hydro variable at `x`
     165             :   template <typename DataType>
     166           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     167             :                  tmpl::list<hydro::Tags::RestMassDensity<DataType>> /*meta*/)
     168             :       const -> tuples::TaggedTuple<hydro::Tags::RestMassDensity<DataType>>;
     169             : 
     170             :   template <typename DataType>
     171           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     172             :                  tmpl::list<hydro::Tags::ElectronFraction<DataType>> /*meta*/)
     173             :       const -> tuples::TaggedTuple<hydro::Tags::ElectronFraction<DataType>>;
     174             : 
     175             :   template <typename DataType>
     176           1 :   auto variables(
     177             :       const tnsr::I<DataType, 3>& x,
     178             :       tmpl::list<hydro::Tags::SpecificInternalEnergy<DataType>> /*meta*/) const
     179             :       -> tuples::TaggedTuple<hydro::Tags::SpecificInternalEnergy<DataType>>;
     180             : 
     181             :   template <typename DataType>
     182           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     183             :                  tmpl::list<hydro::Tags::Temperature<DataType>> /*meta*/) const
     184             :       -> tuples::TaggedTuple<hydro::Tags::Temperature<DataType>>;
     185             : 
     186             :   template <typename DataType>
     187           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     188             :                  tmpl::list<hydro::Tags::Pressure<DataType>> /*meta*/) const
     189             :       -> tuples::TaggedTuple<hydro::Tags::Pressure<DataType>>;
     190             : 
     191             :   template <typename DataType>
     192           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     193             :                  tmpl::list<hydro::Tags::SpatialVelocity<DataType, 3>> /*meta*/)
     194             :       const -> tuples::TaggedTuple<hydro::Tags::SpatialVelocity<DataType, 3>>;
     195             : 
     196             :   template <typename DataType>
     197           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     198             :                  tmpl::list<hydro::Tags::MagneticField<DataType, 3>> /*meta*/)
     199             :       const -> tuples::TaggedTuple<hydro::Tags::MagneticField<DataType, 3>>;
     200             : 
     201             :   template <typename DataType>
     202           1 :   auto variables(
     203             :       const tnsr::I<DataType, 3>& x,
     204             :       tmpl::list<hydro::Tags::DivergenceCleaningField<DataType>> /*meta*/) const
     205             :       -> tuples::TaggedTuple<hydro::Tags::DivergenceCleaningField<DataType>>;
     206             : 
     207             :   template <typename DataType>
     208           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     209             :                  tmpl::list<hydro::Tags::LorentzFactor<DataType>> /*meta*/)
     210             :       const -> tuples::TaggedTuple<hydro::Tags::LorentzFactor<DataType>>;
     211             : 
     212             :   template <typename DataType>
     213           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     214             :                  tmpl::list<hydro::Tags::SpecificEnthalpy<DataType>> /*meta*/)
     215             :       const -> tuples::TaggedTuple<hydro::Tags::SpecificEnthalpy<DataType>>;
     216             :   /// @}
     217             : 
     218             :   /// Retrieve a collection of hydro variables at `x`
     219             :   template <typename DataType, typename... Tags>
     220           1 :   tuples::TaggedTuple<Tags...> variables(const tnsr::I<DataType, 3>& x,
     221             :                                          tmpl::list<Tags...> /*meta*/) const {
     222             :     static_assert(sizeof...(Tags) > 1,
     223             :                   "The generic template will recurse infinitely if only one "
     224             :                   "tag is being retrieved.");
     225             :     return {tuples::get<Tags>(variables(x, tmpl::list<Tags>{}))...};
     226             :   }
     227             : 
     228             :   /// Retrieve the metric variables at `x`
     229             :   template <typename DataType, typename Tag,
     230             :             Requires<not tmpl::list_contains_v<
     231             :                 tmpl::push_back<hydro::grmhd_tags<DataType>,
     232             :                                 hydro::Tags::SpecificEnthalpy<DataType>>,
     233             :                 Tag>> = nullptr>
     234           1 :   tuples::TaggedTuple<Tag> variables(const tnsr::I<DataType, 3>& x,
     235             :                                      tmpl::list<Tag> /*meta*/) const {
     236             :     constexpr double dummy_time = 0.0;
     237             :     return {std::move(get<Tag>(background_spacetime_.variables(
     238             :         x, dummy_time, gr::Solutions::KerrSchild::tags<DataType>{})))};
     239             :   }
     240             : 
     241             :   // NOLINTNEXTLINE(google-runtime-references)
     242           0 :   void pup(PUP::er& /*p*/) override;
     243             : 
     244           0 :   const EquationsOfState::PolytropicFluid<true>& equation_of_state() const {
     245             :     return equation_of_state_;
     246             :   }
     247             : 
     248             :  private:
     249           0 :   friend bool operator==(const BondiHoyleAccretion& lhs,
     250             :                          const BondiHoyleAccretion& rhs);
     251             : 
     252             :   // compute the spatial velocity in spherical Kerr-Schild coordinates
     253             :   template <typename DataType>
     254           0 :   tnsr::I<DataType, 3, Frame::NoFrame> spatial_velocity(
     255             :       const DataType& r_squared, const DataType& cos_theta,
     256             :       const DataType& sin_theta) const;
     257             :   // compute the magnetic field in spherical Kerr-Schild coordinates
     258             :   template <typename DataType>
     259           0 :   tnsr::I<DataType, 3, Frame::NoFrame> magnetic_field(
     260             :       const DataType& r_squared, const DataType& cos_theta,
     261             :       const DataType& sin_theta) const;
     262             : 
     263           0 :   double bh_mass_ = std::numeric_limits<double>::signaling_NaN();
     264           0 :   double bh_spin_a_ = std::numeric_limits<double>::signaling_NaN();
     265           0 :   double rest_mass_density_ = std::numeric_limits<double>::signaling_NaN();
     266           0 :   double flow_speed_ = std::numeric_limits<double>::signaling_NaN();
     267           0 :   double magnetic_field_strength_ =
     268             :       std::numeric_limits<double>::signaling_NaN();
     269           0 :   double polytropic_constant_ = std::numeric_limits<double>::signaling_NaN();
     270           0 :   double polytropic_exponent_ = std::numeric_limits<double>::signaling_NaN();
     271           0 :   EquationsOfState::PolytropicFluid<true> equation_of_state_{};
     272           0 :   gr::Solutions::KerrSchild background_spacetime_{};
     273           0 :   gr::KerrSchildCoords kerr_schild_coords_{};
     274             : };
     275             : 
     276           0 : bool operator!=(const BondiHoyleAccretion& lhs, const BondiHoyleAccretion& rhs);
     277             : 
     278             : }  // namespace grmhd::AnalyticData

Generated by: LCOV version 1.14