SpECTRE Documentation Coverage Report
Current view: top level - PointwiseFunctions/AnalyticData/GrMhd - RiemannProblem.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 17.0 % 88 15
Test Date: 2026-10-22 17:29:42
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/TaggedTuple.hpp"
      11              : #include "DataStructures/Tensor/TypeAliases.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"
      17              : #include "PointwiseFunctions/Hydro/TagsDeclarations.hpp"
      18              : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp"
      19              : #include "Utilities/Serialization/CharmPupable.hpp"
      20              : #include "Utilities/TMPL.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 2.0-1