SpECTRE Documentation Coverage Report
Current view: top level - PointwiseFunctions/AnalyticData/GrMhd - BlastWave.hpp Hit Total Coverage
Commit: 3c072f0ce967e2e56649d3fa12aa2a0e4fe2a42e Lines: 22 76 28.9 %
Date: 2024-04-23 20:50:18
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 <array>
       7             : #include <limits>
       8             : 
       9             : #include "DataStructures/Tensor/TypeAliases.hpp"
      10             : #include "Options/Context.hpp"
      11             : #include "Options/Options.hpp"
      12             : #include "Options/String.hpp"
      13             : #include "PointwiseFunctions/AnalyticData/AnalyticData.hpp"
      14             : #include "PointwiseFunctions/AnalyticData/GrMhd/AnalyticData.hpp"
      15             : #include "PointwiseFunctions/AnalyticSolutions/GeneralRelativity/Minkowski.hpp"
      16             : #include "PointwiseFunctions/Hydro/EquationsOfState/IdealFluid.hpp"  // IWYU pragma: keep
      17             : #include "PointwiseFunctions/Hydro/TagsDeclarations.hpp"
      18             : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp"
      19             : #include "Utilities/Serialization/CharmPupable.hpp"
      20             : #include "Utilities/TMPL.hpp"
      21             : #include "Utilities/TaggedTuple.hpp"
      22             : 
      23             : // IWYU pragma:  no_include <pup.h>
      24             : 
      25             : /// \cond
      26             : namespace PUP {
      27             : class er;  // IWYU pragma: keep
      28             : }  // namespace PUP
      29             : /// \endcond
      30             : 
      31             : namespace grmhd::AnalyticData {
      32             : 
      33             : /*!
      34             :  * \brief Analytic initial data for a cylindrical or spherical blast wave.
      35             :  *
      36             :  * This class implements analytic initial data for a cylindrical blast wave,
      37             :  * as described, e.g., in \cite Kidder2016hev Sec. 6.2.3.
      38             :  * A uniform magnetic field threads an ideal fluid. The solution begins with
      39             :  * material at fixed (typically high) density and pressure at rest inside a
      40             :  * cylinder of radius \f$r < r_{\rm in}\f$ and material at fixed (typically low)
      41             :  * density and pressure at rest in a cylindrical shell with radius
      42             :  * \f$r > r_{\rm out}\f$. In the region \f$ r_{\rm in} < r < r_{\rm out}\f$,
      43             :  * the solution transitions such that the logarithms of the density and
      44             :  * pressure vary linearly. E.g., if \f$\rho(r < r_{\rm in}) = \rho_{\rm in}\f$
      45             :  * and \f$\rho(r > r_{\rm out}) = \rho_{\rm out}\f$, then
      46             :  * \f[
      47             :  * \log \rho = [(r_{\rm in} - r) \log(\rho_{\rm out})
      48             :  *              + (r - r_{\rm out}) \log(\rho_{\rm in})]
      49             :  *              / (r_{\rm in} - r_{\rm out}).
      50             :  * \f]
      51             :  * Note that the cylinder's axis is the \f$z\f$ axis. To evolve this analytic
      52             :  * initial data, use a cubic or cylindrical domain with periodic boundary
      53             :  * conditions applied to the outer boundaries whose normals are parallel or
      54             :  * antiparallel to the z axis. In the transverse (e.g., x and y) dimensions, the
      55             :  * domain should be large enough that the blast wave doesn't reach the boundary
      56             :  * at the final time. E.g., if `InnerRadius = 0.8`, `OuterRadius = 1.0`, and
      57             :  * the final time is 4.0, a good domain extends from `(x,y)=(-6.0, -6.0)` to
      58             :  * `(x,y)=(6.0, 6.0)`.
      59             :  *
      60             :  * An analogous problem with spherical geometry has also been used
      61             :  * \cite CerdaDuran2007 \cite CerdaDuran2008 \cite Cipolletta2019. The magnetic
      62             :  * field is chosen to be in the z-direction instead of the x-direction.
      63             :  */
      64           1 : class BlastWave : public evolution::initial_data::InitialData,
      65             :                   public MarkAsAnalyticData,
      66             :                   public AnalyticDataBase,
      67             :                   public hydro::TemperatureInitialization<BlastWave> {
      68             :  public:
      69           0 :   using equation_of_state_type = EquationsOfState::IdealFluid<true>;
      70             : 
      71           0 :   enum class Geometry { Cylindrical, Spherical };
      72             : 
      73             :   /// Inside InnerRadius, density is InnerDensity.
      74           1 :   struct InnerRadius {
      75           0 :     using type = double;
      76           0 :     static constexpr Options::String help = {
      77             :         "Inside InnerRadius, density is InnerDensity."};
      78           0 :     static type lower_bound() { return 0.0; }
      79             :   };
      80             :   /// Outside OuterRadius, density is OuterDensity.
      81           1 :   struct OuterRadius {
      82           0 :     using type = double;
      83           0 :     static constexpr Options::String help = {
      84             :         "Outside OuterRadius, density is OuterDensity."};
      85           0 :     static type lower_bound() { return 0.0; }
      86             :   };
      87             :   /// Density at radii less than InnerRadius.
      88           1 :   struct InnerDensity {
      89           0 :     using type = double;
      90           0 :     static constexpr Options::String help = {
      91             :         "Density at radii less than InnerRadius."};
      92           0 :     static type lower_bound() { return 0.0; }
      93             :   };
      94             :   /// Density at radii greater than OuterRadius.
      95           1 :   struct OuterDensity {
      96           0 :     using type = double;
      97           0 :     static constexpr Options::String help = {
      98             :         "Density at radii greater than OuterRadius."};
      99           0 :     static type lower_bound() { return 0.0; }
     100             :   };
     101             :   /// Pressure at radii less than InnerRadius.
     102           1 :   struct InnerPressure {
     103           0 :     using type = double;
     104           0 :     static constexpr Options::String help = {
     105             :         "Pressure at radii less than InnerRadius."};
     106           0 :     static type lower_bound() { return 0.0; }
     107             :   };
     108             :   /// Pressure at radii greater than OuterRadius.
     109           1 :   struct OuterPressure {
     110           0 :     using type = double;
     111           0 :     static constexpr Options::String help = {
     112             :         "Pressure at radii greater than OuterRadius."};
     113           0 :     static type lower_bound() { return 0.0; }
     114             :   };
     115             :   /// The x,y,z components of the uniform magnetic field threading the matter.
     116           1 :   struct MagneticField {
     117           0 :     using type = std::array<double, 3>;
     118           0 :     static constexpr Options::String help = {
     119             :         "The x,y,z components of the uniform magnetic field."};
     120             :   };
     121             :   /// The adiabatic index of the ideal fluid.
     122           1 :   struct AdiabaticIndex {
     123           0 :     using type = double;
     124           0 :     static constexpr Options::String help = {
     125             :         "The adiabatic index of the ideal fluid."};
     126           0 :     static type lower_bound() { return 1.0; }
     127             :   };
     128             :   /// The geometry of the blast wave, i.e. Cylindrical or Spherical.
     129           1 :   struct GeometryOption {
     130           0 :     static std::string name() { return "Geometry"; }
     131           0 :     using type = Geometry;
     132           0 :     static constexpr Options::String help = {
     133             :         "The geometry of the blast wave, i.e. Cylindrical or Spherical."};
     134             :   };
     135             : 
     136           0 :   using options = tmpl::list<InnerRadius, OuterRadius, InnerDensity,
     137             :                              OuterDensity, InnerPressure, OuterPressure,
     138             :                              MagneticField, AdiabaticIndex, GeometryOption>;
     139             : 
     140           0 :   static constexpr Options::String help = {
     141             :       "Cylindrical or spherical blast wave analytic initial data."};
     142             : 
     143           0 :   BlastWave() = default;
     144           0 :   BlastWave(const BlastWave& /*rhs*/) = default;
     145           0 :   BlastWave& operator=(const BlastWave& /*rhs*/) = default;
     146           0 :   BlastWave(BlastWave&& /*rhs*/) = default;
     147           0 :   BlastWave& operator=(BlastWave&& /*rhs*/) = default;
     148           0 :   ~BlastWave() override = default;
     149             : 
     150           0 :   BlastWave(double inner_radius, double outer_radius, double inner_density,
     151             :             double outer_density, double inner_pressure, double outer_pressure,
     152             :             const std::array<double, 3>& magnetic_field, double adiabatic_index,
     153             :             Geometry geometry, const Options::Context& context = {});
     154             : 
     155           0 :   auto get_clone() const
     156             :       -> std::unique_ptr<evolution::initial_data::InitialData> override;
     157             : 
     158             :   /// \cond
     159             :   explicit BlastWave(CkMigrateMessage* msg);
     160             :   using PUP::able::register_constructor;
     161             :   WRAPPED_PUPable_decl_template(BlastWave);
     162             :   /// \endcond
     163             : 
     164             :   /// @{
     165             :   /// Retrieve the GRMHD variables at a given position.
     166             :   template <typename DataType>
     167           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     168             :                  tmpl::list<hydro::Tags::RestMassDensity<DataType>> /*meta*/)
     169             :       const -> tuples::TaggedTuple<hydro::Tags::RestMassDensity<DataType>>;
     170             : 
     171             :   template <typename DataType>
     172           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     173             :                  tmpl::list<hydro::Tags::ElectronFraction<DataType>> /*meta*/)
     174             :       const -> tuples::TaggedTuple<hydro::Tags::ElectronFraction<DataType>>;
     175             : 
     176             :   template <typename DataType>
     177           1 :   auto variables(
     178             :       const tnsr::I<DataType, 3>& x,
     179             :       tmpl::list<hydro::Tags::SpecificInternalEnergy<DataType>> /*meta*/) const
     180             :       -> tuples::TaggedTuple<hydro::Tags::SpecificInternalEnergy<DataType>>;
     181             : 
     182             :   template <typename DataType>
     183           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     184             :                  tmpl::list<hydro::Tags::Pressure<DataType>> /*meta*/) const
     185             :       -> tuples::TaggedTuple<hydro::Tags::Pressure<DataType>>;
     186             : 
     187             :   template <typename DataType>
     188           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     189             :                  tmpl::list<hydro::Tags::SpatialVelocity<DataType, 3>> /*meta*/)
     190             :       const -> tuples::TaggedTuple<hydro::Tags::SpatialVelocity<DataType, 3>>;
     191             : 
     192             :   template <typename DataType>
     193           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     194             :                  tmpl::list<hydro::Tags::MagneticField<DataType, 3>> /*meta*/)
     195             :       const -> tuples::TaggedTuple<hydro::Tags::MagneticField<DataType, 3>>;
     196             : 
     197             :   template <typename DataType>
     198           1 :   auto variables(
     199             :       const tnsr::I<DataType, 3>& x,
     200             :       tmpl::list<hydro::Tags::DivergenceCleaningField<DataType>> /*meta*/) const
     201             :       -> tuples::TaggedTuple<hydro::Tags::DivergenceCleaningField<DataType>>;
     202             : 
     203             :   template <typename DataType>
     204           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     205             :                  tmpl::list<hydro::Tags::LorentzFactor<DataType>> /*meta*/)
     206             :       const -> tuples::TaggedTuple<hydro::Tags::LorentzFactor<DataType>>;
     207             : 
     208             :   template <typename DataType>
     209           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     210             :                  tmpl::list<hydro::Tags::SpecificEnthalpy<DataType>> /*meta*/)
     211             :       const -> tuples::TaggedTuple<hydro::Tags::SpecificEnthalpy<DataType>>;
     212             : 
     213             :   template <typename DataType>
     214           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     215             :                  tmpl::list<hydro::Tags::Temperature<DataType>> /*meta*/) const
     216             :       -> tuples::TaggedTuple<hydro::Tags::Temperature<DataType>> {
     217             :     return TemperatureInitialization::variables(
     218             :         x, tmpl::list<hydro::Tags::Temperature<DataType>>{});
     219             :   }
     220             : 
     221             :   /// @}
     222             : 
     223             :   /// Retrieve a collection of hydrodynamic variables at position x
     224             :   template <typename DataType, typename Tag1, typename Tag2, typename... Tags>
     225           1 :   tuples::TaggedTuple<Tag1, Tag2, Tags...> variables(
     226             :       const tnsr::I<DataType, 3>& x,
     227             :       tmpl::list<Tag1, Tag2, Tags...> /*meta*/) const {
     228             :     return {tuples::get<Tag1>(variables(x, tmpl::list<Tag1>{})),
     229             :             tuples::get<Tag2>(variables(x, tmpl::list<Tag2>{})),
     230             :             tuples::get<Tags>(variables(x, tmpl::list<Tags>{}))...};
     231             :   }
     232             : 
     233             :   /// Retrieve the metric variables
     234             :   template <typename DataType, typename Tag,
     235             :             Requires<tmpl::list_contains_v<
     236             :                 gr::analytic_solution_tags<3, DataType>, Tag>> = nullptr>
     237           1 :   tuples::TaggedTuple<Tag> variables(const tnsr::I<DataType, 3>& x,
     238             :                                      tmpl::list<Tag> /*meta*/) const {
     239             :     constexpr double dummy_time = 0.0;
     240             :     return background_spacetime_.variables(x, dummy_time, tmpl::list<Tag>{});
     241             :   }
     242             : 
     243           0 :   const EquationsOfState::IdealFluid<true>& equation_of_state() const {
     244             :     return equation_of_state_;
     245             :   }
     246             : 
     247             :   // NOLINTNEXTLINE(google-runtime-references)
     248           0 :   void pup(PUP::er& /*p*/) override;
     249             : 
     250             :  private:
     251           0 :   double inner_radius_ = std::numeric_limits<double>::signaling_NaN();
     252           0 :   double outer_radius_ = std::numeric_limits<double>::signaling_NaN();
     253           0 :   double inner_density_ = std::numeric_limits<double>::signaling_NaN();
     254           0 :   double outer_density_ = std::numeric_limits<double>::signaling_NaN();
     255           0 :   double inner_pressure_ = std::numeric_limits<double>::signaling_NaN();
     256           0 :   double outer_pressure_ = std::numeric_limits<double>::signaling_NaN();
     257           0 :   std::array<double, 3> magnetic_field_{
     258             :       {std::numeric_limits<double>::signaling_NaN(),
     259             :        std::numeric_limits<double>::signaling_NaN(),
     260             :        std::numeric_limits<double>::signaling_NaN()}};
     261           0 :   double adiabatic_index_ = std::numeric_limits<double>::signaling_NaN();
     262           0 :   Geometry geometry_ = Geometry::Cylindrical;
     263           0 :   EquationsOfState::IdealFluid<true> equation_of_state_{};
     264           0 :   gr::Solutions::Minkowski<3> background_spacetime_{};
     265             : 
     266           0 :   friend bool operator==(const BlastWave& lhs, const BlastWave& rhs);
     267             : 
     268           0 :   friend bool operator!=(const BlastWave& lhs, const BlastWave& rhs);
     269             : };
     270             : 
     271             : }  // namespace grmhd::AnalyticData
     272             : 
     273             : /// \cond
     274             : template <>
     275             : struct Options::create_from_yaml<grmhd::AnalyticData::BlastWave::Geometry> {
     276             :   template <typename Metavariables>
     277             :   static grmhd::AnalyticData::BlastWave::Geometry create(
     278             :       const Options::Option& options) {
     279             :     return create<void>(options);
     280             :   }
     281             : };
     282             : 
     283             : template <>
     284             : grmhd::AnalyticData::BlastWave::Geometry
     285             : Options::create_from_yaml<grmhd::AnalyticData::BlastWave::Geometry>::create<
     286             :     void>(const Options::Option& options);
     287             : /// \endcond

Generated by: LCOV version 1.14