SpECTRE Documentation Coverage Report
Current view: top level - PointwiseFunctions/AnalyticData/GrMhd - RiemannProblem.hpp Hit Total Coverage
Commit: f23e75c235cae5144b8ac7ce01280be5b8cd2c8a Lines: 15 88 17.0 %
Date: 2024-09-07 06:21:00
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             : #include <string>
       9             : 
      10             : #include "DataStructures/Tensor/TypeAliases.hpp"
      11             : #include "Options/String.hpp"
      12             : #include "PointwiseFunctions/AnalyticData/AnalyticData.hpp"
      13             : #include "PointwiseFunctions/AnalyticData/GrMhd/AnalyticData.hpp"
      14             : #include "PointwiseFunctions/AnalyticSolutions/GeneralRelativity/Minkowski.hpp"
      15             : #include "PointwiseFunctions/Hydro/EquationsOfState/IdealFluid.hpp"
      16             : #include "PointwiseFunctions/Hydro/TagsDeclarations.hpp"
      17             : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp"
      18             : #include "Utilities/Serialization/CharmPupable.hpp"
      19             : #include "Utilities/TMPL.hpp"
      20             : #include "Utilities/TaggedTuple.hpp"
      21             : 
      22             : /// \cond
      23             : namespace PUP {
      24             : class er;
      25             : }  // namespace PUP
      26             : /// \endcond
      27             : 
      28             : namespace grmhd::AnalyticData {
      29             : /*!
      30             :  * \brief Initial conditions for relativistic MHD Riemann problems
      31             :  *
      32             :  * The standard problems were first collected in \cite Balsara2001. A complete
      33             :  * Riemann solver for the RMHD equations is presented in \cite Giacomazzo2006
      34             :  * and can be downloaded from https://www.brunogiacomazzo.org/?page_id=395
      35             :  *
      36             :  * The domain is from \f$[-0.5,0.5]^3\f$ with periodic boundary conditions in
      37             :  * \f$y\f$ and \f$z\f$. The problems are usually run at a resolution of 1600
      38             :  * finite difference/finite volume grid points and the initial discontinuity is
      39             :  * located at \f$x=0\f$.
      40             :  *
      41             :  * While the problems were originally run in Minkowski space, changing the lapse
      42             :  * \f$\alpha\f$ to a non-unity constant value and/or the shift \f$\beta^x\f$ to
      43             :  * a non-zero constant value allows testing some of the metric terms in the
      44             :  * evolution equations in a fairly simple setup.
      45             :  *
      46             :  * Below are the initial conditions for the 5 different Balsara Riemann
      47             :  * problems. Please note that RP5 has a different final time than the rest, and
      48             :  * that RP1 has a different adiabatic index than the rest.
      49             :  *
      50             :  * RP1:
      51             :  *  - AdiabaticIndex: 2.0
      52             :  *  - LeftDensity: 1.0
      53             :  *  - LeftPressure: 1.0
      54             :  *  - LeftVelocity: [0.0, 0.0, 0.0]
      55             :  *  - LeftMagneticField: [0.5, 1.0, 0.0]
      56             :  *  - RightDensity: 0.125
      57             :  *  - RightPressure: 0.1
      58             :  *  - RightVelocity: [0.0, 0.0, 0.0]
      59             :  *  - RightMagneticField: [0.5, -1.0, 0.0]
      60             :  *  - Lapse: 1.0
      61             :  *  - ShiftX: 0.0
      62             :  *  - Final time: 0.4
      63             :  *
      64             :  * RP2:
      65             :  *  - AdiabaticIndex: 1.66666666666666666
      66             :  *  - LeftDensity: 1.0
      67             :  *  - LeftPressure: 30.0
      68             :  *  - LeftVelocity: [0.0, 0.0, 0.0]
      69             :  *  - LeftMagneticField: [5.0, 6.0, 6.0]
      70             :  *  - RightDensity: 1.0
      71             :  *  - RightPressure: 1.0
      72             :  *  - RightVelocity: [0.0, 0.0, 0.0]
      73             :  *  - RightMagneticField: [5.0, 0.7, 0.7]
      74             :  *  - Lapse: 1.0
      75             :  *  - ShiftX: 0.0
      76             :  *  - Final time: 0.4
      77             :  *
      78             :  * RP3:
      79             :  *  - AdiabaticIndex: 1.66666666666666666
      80             :  *  - LeftDensity: 1.0
      81             :  *  - LeftPressure: 1000.0
      82             :  *  - LeftVelocity: [0.0, 0.0, 0.0]
      83             :  *  - LeftMagneticField: [10.0, 7.0, 7.0]
      84             :  *  - RightDensity: 1.0
      85             :  *  - RightPressure: 0.1
      86             :  *  - RightVelocity: [0.0, 0.0, 0.0]
      87             :  *  - RightMagneticField: [10.0, 0.7, 0.7]
      88             :  *  - Lapse: 1.0
      89             :  *  - ShiftX: 0.0
      90             :  *  - Final time: 0.4
      91             :  *
      92             :  * RP4:
      93             :  *  - AdiabaticIndex: 1.66666666666666666
      94             :  *  - LeftDensity: 1.0
      95             :  *  - LeftPressure: 0.1
      96             :  *  - LeftVelocity: [0.999, 0.0, 0.0]
      97             :  *  - LeftMagneticField: [10.0, 7.0, 7.0]
      98             :  *  - RightDensity: 1.0
      99             :  *  - RightPressure: 0.1
     100             :  *  - RightVelocity: [-0.999, 0.0, 0.0]
     101             :  *  - RightMagneticField: [10.0, -7.0, -7.0]
     102             :  *  - Lapse: 1.0
     103             :  *  - ShiftX: 0.0
     104             :  *  - Final time: 0.4
     105             :  *
     106             :  * RP5:
     107             :  *  - AdiabaticIndex: 1.66666666666666666
     108             :  *  - LeftDensity: 1.08
     109             :  *  - LeftPressure: 0.95
     110             :  *  - LeftVelocity: [0.4, 0.3, 0.2]
     111             :  *  - LeftMagneticField: [2.0, 0.3, 0.3]
     112             :  *  - RightDensity: 1.0
     113             :  *  - RightPressure: 1.0
     114             :  *  - RightVelocity: [-0.45, -0.2, 0.2]
     115             :  *  - RightMagneticField: [2.0, -0.7, 0.5]
     116             :  *  - Lapse: 1.0
     117             :  *  - ShiftX: 0.0
     118             :  *  - Final time: 0.55
     119             :  */
     120           1 : class RiemannProblem : public evolution::initial_data::InitialData,
     121             :                        public AnalyticDataBase,
     122             :                        public hydro::TemperatureInitialization<RiemannProblem>,
     123             :                        public MarkAsAnalyticData {
     124             :  public:
     125           0 :   using equation_of_state_type = EquationsOfState::IdealFluid<true>;
     126             : 
     127           0 :   struct AdiabaticIndex {
     128           0 :     using type = double;
     129           0 :     static constexpr Options::String help = {
     130             :         "The adiabatic index of the ideal fluid"};
     131           0 :     static type lower_bound() { return 1.0; }
     132             :   };
     133           0 :   struct LeftRestMassDensity {
     134           0 :     using type = double;
     135           0 :     static std::string name() { return "LeftDensity"; };
     136           0 :     static constexpr Options::String help = {
     137             :         "Fluid rest mass density in the left half-domain"};
     138           0 :     static type lower_bound() { return 0.0; }
     139             :   };
     140           0 :   struct RightRestMassDensity {
     141           0 :     using type = double;
     142           0 :     static std::string name() { return "RightDensity"; };
     143           0 :     static constexpr Options::String help = {
     144             :         "Fluid rest mass density in the right half-domain"};
     145           0 :     static type lower_bound() { return 0.0; }
     146             :   };
     147           0 :   struct LeftPressure {
     148           0 :     using type = double;
     149           0 :     static constexpr Options::String help = {
     150             :         "Fluid pressure in the left half-domain"};
     151           0 :     static type lower_bound() { return 0.0; }
     152             :   };
     153           0 :   struct RightPressure {
     154           0 :     using type = double;
     155           0 :     static constexpr Options::String help = {
     156             :         "Fluid pressure in the right half-domain"};
     157           0 :     static type lower_bound() { return 0.0; }
     158             :   };
     159           0 :   struct LeftSpatialVelocity {
     160           0 :     using type = std::array<double, 3>;
     161           0 :     static std::string name() { return "LeftVelocity"; };
     162           0 :     static constexpr Options::String help = {
     163             :         "Fluid spatial velocity in the left half-domain"};
     164             :   };
     165           0 :   struct RightSpatialVelocity {
     166           0 :     using type = std::array<double, 3>;
     167           0 :     static std::string name() { return "RightVelocity"; };
     168           0 :     static constexpr Options::String help = {
     169             :         "Fluid spatial velocity in the right half-domain"};
     170             :   };
     171           0 :   struct LeftMagneticField {
     172           0 :     using type = std::array<double, 3>;
     173           0 :     static constexpr Options::String help = {
     174             :         "Magnetic field in the left half-domain"};
     175             :   };
     176           0 :   struct RightMagneticField {
     177           0 :     using type = std::array<double, 3>;
     178           0 :     static constexpr Options::String help = {
     179             :         "Magnetic field in the right half-domain"};
     180             :   };
     181           0 :   struct Lapse {
     182           0 :     using type = double;
     183           0 :     static constexpr Options::String help = {
     184             :         "The value of the lapse. Standard is 1."};
     185           0 :     static type lower_bound() { return 0.0; }
     186             :   };
     187           0 :   struct ShiftX {
     188           0 :     using type = double;
     189           0 :     static constexpr Options::String help = {
     190             :         "The value of the x-component of the shift, beta^x. Standard is 0."};
     191             :   };
     192             : 
     193           0 :   using options =
     194             :       tmpl::list<AdiabaticIndex, LeftRestMassDensity, RightRestMassDensity,
     195             :                  LeftPressure, RightPressure, LeftSpatialVelocity,
     196             :                  RightSpatialVelocity, LeftMagneticField, RightMagneticField,
     197             :                  Lapse, ShiftX>;
     198             : 
     199           0 :   static constexpr Options::String help = {
     200             :       "Analytic initial data for a GRMHD Riemann problem. The fluid variables "
     201             :       "are set homogeneously on either half of the domain left and right of "
     202             :       "x=0."};
     203             : 
     204           0 :   RiemannProblem() = default;
     205           0 :   RiemannProblem(const RiemannProblem& /*rhs*/) = default;
     206           0 :   RiemannProblem& operator=(const RiemannProblem& /*rhs*/) = default;
     207           0 :   RiemannProblem(RiemannProblem&& /*rhs*/) = default;
     208           0 :   RiemannProblem& operator=(RiemannProblem&& /*rhs*/) = default;
     209           0 :   ~RiemannProblem() override = default;
     210             : 
     211           0 :   RiemannProblem(double adiabatic_index, double left_rest_mass_density,
     212             :                  double right_rest_mass_density, double left_pressure,
     213             :                  double right_pressure,
     214             :                  const std::array<double, 3>& left_spatial_velocity,
     215             :                  const std::array<double, 3>& right_spatial_velocity,
     216             :                  const std::array<double, 3>& left_magnetic_field,
     217             :                  const std::array<double, 3>& right_magnetic_field,
     218             :                  double lapse, double shift);
     219             : 
     220           0 :   auto get_clone() const
     221             :       -> std::unique_ptr<evolution::initial_data::InitialData> override;
     222             : 
     223             :   /// \cond
     224             :   explicit RiemannProblem(CkMigrateMessage* msg);
     225             :   using PUP::able::register_constructor;
     226             :   WRAPPED_PUPable_decl_template(RiemannProblem);
     227             :   /// \endcond
     228             : 
     229             :   /// @{
     230             :   /// Retrieve the GRMHD variables at a given position.
     231             :   template <typename DataType>
     232           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     233             :                  tmpl::list<hydro::Tags::RestMassDensity<DataType>> /*meta*/)
     234             :       const -> tuples::TaggedTuple<hydro::Tags::RestMassDensity<DataType>>;
     235             : 
     236             :   template <typename DataType>
     237           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     238             :                  tmpl::list<hydro::Tags::ElectronFraction<DataType>> /*meta*/)
     239             :       const -> tuples::TaggedTuple<hydro::Tags::ElectronFraction<DataType>>;
     240             : 
     241             :   template <typename DataType>
     242           1 :   auto variables(
     243             :       const tnsr::I<DataType, 3>& x,
     244             :       tmpl::list<hydro::Tags::SpecificInternalEnergy<DataType>> /*meta*/) const
     245             :       -> tuples::TaggedTuple<hydro::Tags::SpecificInternalEnergy<DataType>>;
     246             : 
     247             :   template <typename DataType>
     248           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     249             :                  tmpl::list<hydro::Tags::Pressure<DataType>> /*meta*/) const
     250             :       -> tuples::TaggedTuple<hydro::Tags::Pressure<DataType>>;
     251             : 
     252             :   template <typename DataType>
     253           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     254             :                  tmpl::list<hydro::Tags::SpatialVelocity<DataType, 3>> /*meta*/)
     255             :       const -> tuples::TaggedTuple<hydro::Tags::SpatialVelocity<DataType, 3>>;
     256             : 
     257             :   template <typename DataType>
     258           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     259             :                  tmpl::list<hydro::Tags::MagneticField<DataType, 3>> /*meta*/)
     260             :       const -> tuples::TaggedTuple<hydro::Tags::MagneticField<DataType, 3>>;
     261             : 
     262             :   template <typename DataType>
     263           1 :   auto variables(
     264             :       const tnsr::I<DataType, 3>& x,
     265             :       tmpl::list<hydro::Tags::DivergenceCleaningField<DataType>> /*meta*/) const
     266             :       -> tuples::TaggedTuple<hydro::Tags::DivergenceCleaningField<DataType>>;
     267             : 
     268             :   template <typename DataType>
     269           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     270             :                  tmpl::list<hydro::Tags::LorentzFactor<DataType>> /*meta*/)
     271             :       const -> tuples::TaggedTuple<hydro::Tags::LorentzFactor<DataType>>;
     272             : 
     273             :   template <typename DataType>
     274           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     275             :                  tmpl::list<hydro::Tags::SpecificEnthalpy<DataType>> /*meta*/)
     276             :       const -> tuples::TaggedTuple<hydro::Tags::SpecificEnthalpy<DataType>>;
     277             : 
     278             :   template <typename DataType>
     279           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     280             :                  tmpl::list<gr::Tags::Lapse<DataType>> /*meta*/) const
     281             :       -> tuples::TaggedTuple<gr::Tags::Lapse<DataType>>;
     282             : 
     283             :   template <typename DataType>
     284           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     285             :                  tmpl::list<gr::Tags::Shift<DataType, 3>> /*meta*/) const
     286             :       -> tuples::TaggedTuple<gr::Tags::Shift<DataType, 3>>;
     287             : 
     288             :   template <typename DataType>
     289           1 :   auto variables(const tnsr::I<DataType, 3>& x,
     290             :                  tmpl::list<hydro::Tags::Temperature<DataType>> /*meta*/) const
     291             :       -> tuples::TaggedTuple<hydro::Tags::Temperature<DataType>> {
     292             :     return TemperatureInitialization::variables(
     293             :         x, tmpl::list<hydro::Tags::Temperature<DataType>>{});
     294             :   }
     295             :   /// @}
     296             : 
     297             :   /// Retrieve a collection of hydrodynamic variables at position x
     298             :   template <typename DataType, typename Tag1, typename Tag2, typename... Tags>
     299           1 :   tuples::TaggedTuple<Tag1, Tag2, Tags...> variables(
     300             :       const tnsr::I<DataType, 3>& x,
     301             :       tmpl::list<Tag1, Tag2, Tags...> /*meta*/) const {
     302             :     return {tuples::get<Tag1>(variables(x, tmpl::list<Tag1>{})),
     303             :             tuples::get<Tag2>(variables(x, tmpl::list<Tag2>{})),
     304             :             tuples::get<Tags>(variables(x, tmpl::list<Tags>{}))...};
     305             :   }
     306             : 
     307             :   /// Retrieve the metric variables
     308             :   template <typename DataType, typename Tag>
     309           1 :   tuples::TaggedTuple<Tag> variables(const tnsr::I<DataType, 3>& x,
     310             :                                      tmpl::list<Tag> /*meta*/) const {
     311             :     constexpr double dummy_time = 0.0;
     312             :     return background_spacetime_.variables(x, dummy_time, tmpl::list<Tag>{});
     313             :   }
     314             : 
     315           0 :   const EquationsOfState::IdealFluid<true>& equation_of_state() const {
     316             :     return equation_of_state_;
     317             :   }
     318             : 
     319             :   // NOLINTNEXTLINE(google-runtime-references)
     320           0 :   void pup(PUP::er& /*p*/) override;
     321             : 
     322             :  private:
     323           0 :   friend bool operator==(const RiemannProblem& lhs, const RiemannProblem& rhs);
     324             : 
     325           0 :   friend bool operator!=(const RiemannProblem& lhs, const RiemannProblem& rhs);
     326             : 
     327           0 :   EquationsOfState::IdealFluid<true> equation_of_state_{};
     328           0 :   gr::Solutions::Minkowski<3> background_spacetime_{};
     329             : 
     330           0 :   double adiabatic_index_ = std::numeric_limits<double>::signaling_NaN();
     331           0 :   double left_rest_mass_density_ = std::numeric_limits<double>::signaling_NaN();
     332           0 :   double right_rest_mass_density_ =
     333             :       std::numeric_limits<double>::signaling_NaN();
     334           0 :   double left_pressure_ = std::numeric_limits<double>::signaling_NaN();
     335           0 :   double right_pressure_ = std::numeric_limits<double>::signaling_NaN();
     336           0 :   static constexpr double discontinuity_location_ = 0.0;
     337           0 :   std::array<double, 3> left_spatial_velocity_{
     338             :       {std::numeric_limits<double>::signaling_NaN(),
     339             :        std::numeric_limits<double>::signaling_NaN(),
     340             :        std::numeric_limits<double>::signaling_NaN()}};
     341           0 :   std::array<double, 3> right_spatial_velocity_{
     342             :       {std::numeric_limits<double>::signaling_NaN(),
     343             :        std::numeric_limits<double>::signaling_NaN(),
     344             :        std::numeric_limits<double>::signaling_NaN()}};
     345           0 :   std::array<double, 3> left_magnetic_field_{
     346             :       {std::numeric_limits<double>::signaling_NaN(),
     347             :        std::numeric_limits<double>::signaling_NaN(),
     348             :        std::numeric_limits<double>::signaling_NaN()}};
     349           0 :   std::array<double, 3> right_magnetic_field_{
     350             :       {std::numeric_limits<double>::signaling_NaN(),
     351             :        std::numeric_limits<double>::signaling_NaN(),
     352             :        std::numeric_limits<double>::signaling_NaN()}};
     353           0 :   double lapse_ = std::numeric_limits<double>::signaling_NaN();
     354           0 :   double shift_ = std::numeric_limits<double>::signaling_NaN();
     355             : };
     356             : }  // namespace grmhd::AnalyticData

Generated by: LCOV version 1.14