SpECTRE Documentation Coverage Report
Current view: top level - PointwiseFunctions/Hydro - Tags.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 37.9 % 87 33
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 <cstddef>
       7              : #include <string>
       8              : 
       9              : #include "DataStructures/DataBox/Tag.hpp"
      10              : #include "DataStructures/Tensor/IndexType.hpp"
      11              : #include "DataStructures/Tensor/TypeAliases.hpp"
      12              : #include "Evolution/TypeTraits.hpp"
      13              : #include "Options/Auto.hpp"
      14              : #include "Options/String.hpp"
      15              : #include "PointwiseFunctions/Hydro/EquationsOfState/EquationOfState.hpp"
      16              : #include "PointwiseFunctions/Hydro/EquationsOfState/Factory.hpp"
      17              : #include "PointwiseFunctions/Hydro/EquationsOfState/PolytropicFluid.hpp"
      18              : #include "PointwiseFunctions/Hydro/TagsDeclarations.hpp"
      19              : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp"
      20              : #include "PointwiseFunctions/InitialDataUtilities/Tags/InitialData.hpp"
      21              : #include "Utilities/ErrorHandling/Error.hpp"
      22              : /// \ingroup EvolutionSystemsGroup
      23              : /// \brief Items related to hydrodynamic systems.
      24              : namespace hydro {
      25              : 
      26              : /// %Tags for options of hydrodynamic systems.
      27            1 : namespace OptionTags {
      28              : /// The equation of state of the fluid.
      29              : template <bool IsRelativistic, size_t ThermoDim>
      30            1 : struct InitialDataEquationOfState {
      31            0 :   using type = std::unique_ptr<
      32              :       EquationsOfState::EquationOfState<IsRelativistic, ThermoDim>>;
      33            0 :   static std::string name() { return "EquationOfState"; }
      34            0 :   static constexpr Options::String help = {
      35              :       "Options for the equation of state used for the initial data."};
      36              : };
      37              : 
      38              : /// The equation of state of the fluid.
      39              : template <bool IsRelativistic, size_t ThermoDim>
      40            1 : struct EquationOfState {
      41            0 :   struct FromInitialData {};
      42            0 :   using type = Options::Auto<std::unique_ptr<EquationsOfState::EquationOfState<
      43              :                                  IsRelativistic, ThermoDim>>,
      44              :                              FromInitialData>;
      45              : 
      46            0 :   static constexpr Options::String help = {
      47              :       "The equation of state to use during the evolution."};
      48              : };
      49              : 
      50            0 : struct GrmhdEquationOfState {
      51            0 :   struct FromInitialData {};
      52            0 :   using type =
      53              :       Options::Auto<std::unique_ptr<EquationsOfState::EquationOfState<true, 3>>,
      54              :                     FromInitialData>;
      55            0 :   static std::string name() { return "EquationOfState"; }
      56            0 :   static constexpr Options::String help = {
      57              :       "Options for the equation of state used for relativistic"
      58              :       "hydro simulations using GRMHD executables."};
      59              : };
      60              : }  // namespace OptionTags
      61              : 
      62              : /// %Tags for hydrodynamic systems.
      63              : namespace Tags {
      64              : 
      65              : /// The Alfvén speed squared \f$v_A^2\f$.
      66              : template <typename DataType>
      67            1 : struct AlfvenSpeedSquared : db::SimpleTag {
      68            0 :   using type = Scalar<DataType>;
      69              : };
      70              : 
      71              : /// The magnetic field \f$b^\mu = u_\nu {}^\star\!F^{\mu \nu}\f$
      72              : /// measured by an observer comoving with the fluid with 4-velocity
      73              : /// \f$u_\nu\f$ where \f${}^\star\!F^{\mu \nu}\f$
      74              : /// is the dual of the Faraday tensor.  Note that \f$b^\mu\f$ has a
      75              : /// time component (that is, \f$b^\mu n_\mu \neq 0\f$, where \f$n_\mu\f$ is
      76              : /// the normal to the spacelike hypersurface).
      77              : template <typename DataType, size_t Dim, typename Fr>
      78            1 : struct ComovingMagneticField : db::SimpleTag {
      79            0 :   using type = tnsr::A<DataType, Dim, Fr>;
      80            0 :   static std::string name() {
      81              :     return Frame::prefix<Fr>() + "ComovingMagneticField";
      82              :   }
      83              : };
      84              : 
      85              : /// The square of the comoving magnetic field, \f$b^\mu b_\mu\f$
      86              : template <typename DataType>
      87            1 : struct ComovingMagneticFieldSquared : db::SimpleTag {
      88            0 :   using type = Scalar<DataType>;
      89              : };
      90              : 
      91              : /// The magnitude of the comoving magnetic field, \f$\sqrt{b^\mu b_\mu}\f$
      92              : template <typename DataType>
      93            1 : struct ComovingMagneticFieldMagnitude : db::SimpleTag {
      94            0 :   using type = Scalar<DataType>;
      95              : };
      96              : 
      97              : /// The divergence-cleaning field \f$\Phi\f$.
      98              : template <typename DataType>
      99            1 : struct DivergenceCleaningField : db::SimpleTag {
     100            0 :   using type = Scalar<DataType>;
     101              : };
     102              : 
     103              : /// The electron fraction \f$Y_e\f$.
     104              : template <typename DataType>
     105            1 : struct ElectronFraction : db::SimpleTag {
     106            0 :   using type = Scalar<DataType>;
     107              : };
     108              : 
     109              : /// The equation of state retrieved from the analytic solution / data in the
     110              : /// input file
     111              : template <bool IsRelativistic, size_t ThermodynamicDim>
     112            1 : struct EquationOfState : db::SimpleTag {
     113            0 :   using type = std::unique_ptr<
     114              :       EquationsOfState::EquationOfState<IsRelativistic, ThermodynamicDim>>;
     115              : 
     116              :   template <typename Metavariables>
     117            0 :   using option_tags =
     118              :       tmpl::list<OptionTags::EquationOfState<IsRelativistic, ThermodynamicDim>,
     119              :                  ::evolution::initial_data::OptionTags::InitialData>;
     120            0 :   static constexpr bool pass_metavariables = true;
     121              : 
     122              :   template <typename Metavariables>
     123            0 :   static type create_from_options(
     124              :       const std::optional<type>& eos,
     125              :       const std::unique_ptr<::evolution::initial_data::InitialData>&
     126              :           initial_data) {
     127              :     if (eos.has_value()) {
     128              :       return eos.value()->get_clone();
     129              :     } else {
     130              :       return call_with_dynamic_type<
     131              :           type,
     132              :           tmpl::at<typename Metavariables::factory_creation::factory_classes,
     133              :                    ::evolution::initial_data::InitialData>>(
     134              :           initial_data.get(), [](const auto* const derived_initial_data) {
     135              :             if constexpr (::evolution::is_numeric_initial_data_v<
     136              :                               std::decay_t<decltype(*derived_initial_data)>>) {
     137              :               ERROR(
     138              :                   "Equation of State cannot currently be parsed from numeric"
     139              :                   "initial data, please explicitly specify the equation of "
     140              :                   "state for the evolution in the input file.");
     141              :               if constexpr (ThermodynamicDim == 1) {
     142              :                 return std::make_unique<
     143              :                     EquationsOfState::PolytropicFluid<IsRelativistic>>(100.0,
     144              :                                                                        2.0);
     145              :               } else if constexpr (ThermodynamicDim == 2) {
     146              :                 return std::make_unique<
     147              :                     EquationsOfState::IdealFluid<IsRelativistic>>(2.0);
     148              :               } else if constexpr (ThermodynamicDim == 3) {
     149              :                 return std::make_unique<EquationsOfState::Barotropic3D<
     150              :                     EquationsOfState::PolytropicFluid<IsRelativistic>>>(
     151              :                     EquationsOfState::PolytropicFluid<IsRelativistic>(100.0,
     152              :                                                                       2.0));
     153              :               }
     154              :             } else {
     155              :               if constexpr (ThermodynamicDim == 3) {
     156              :                 return derived_initial_data->equation_of_state()
     157              :                     .promote_to_3d_eos();
     158              :               } else if constexpr (ThermodynamicDim == 2) {
     159              :                 return derived_initial_data->equation_of_state()
     160              :                     .promote_to_2d_eos();
     161              :               } else {
     162              :                 return derived_initial_data->equation_of_state().get_clone();
     163              :               }
     164              :             }
     165              :           });
     166              :     }
     167              :   }
     168              : };
     169              : 
     170              : /// The inverse plasma beta \f$\beta^{-1} = b^2 / (2 p)\f$, where
     171              : ///// \f$b^2\f$ is the square of the comoving magnetic field amplitude
     172              : ///// and \f$p\f$ is the fluid pressure.
     173              : template <typename DataType>
     174            1 : struct InversePlasmaBeta : db::SimpleTag {
     175            0 :   using type = Scalar<DataType>;
     176              : };
     177              : 
     178              : /// The Lorentz factor \f$W = (1-v^iv_i)^{-1/2}\f$, where \f$v^i\f$ is
     179              : /// the spatial velocity of the fluid.
     180              : template <typename DataType>
     181            1 : struct LorentzFactor : db::SimpleTag {
     182            0 :   using type = Scalar<DataType>;
     183              : };
     184              : 
     185              : /// The square of the Lorentz factor \f$W^2\f$.
     186              : template <typename DataType>
     187            1 : struct LorentzFactorSquared : db::SimpleTag {
     188            0 :   using type = Scalar<DataType>;
     189              : };
     190              : 
     191              : /// The magnetic field \f$B^i = n_\mu {}^\star\!F^{i \mu}\f$ measured by an
     192              : /// Eulerian observer, where \f$n_\mu\f$ is the normal to the spatial
     193              : /// hypersurface and \f${}^\star\!F^{\mu \nu}\f$ is the dual of the
     194              : /// Faraday tensor.  Note that \f$B^i\f$ is purely spatial, and it
     195              : /// can be lowered using the spatial metric.
     196              : template <typename DataType, size_t Dim, typename Fr>
     197            1 : struct MagneticField : db::SimpleTag {
     198            0 :   using type = tnsr::I<DataType, Dim, Fr>;
     199            0 :   static std::string name() { return Frame::prefix<Fr>() + "MagneticField"; }
     200              : };
     201              : 
     202              : /// The magnetic field dotted into the spatial velocity, \f$B^iv_i\f$ where
     203              : /// \f$v_i\f$ is the spatial velocity one-form.
     204              : template <typename DataType>
     205            1 : struct MagneticFieldDotSpatialVelocity : db::SimpleTag {
     206            0 :   using type = Scalar<DataType>;
     207              : };
     208              : 
     209              : /// The one-form of the magnetic field.  Note that \f$B^i\f$ is raised
     210              : /// and lowered with the spatial metric.
     211              : /// \see hydro::Tags::MagneticField
     212              : template <typename DataType, size_t Dim, typename Fr>
     213            1 : struct MagneticFieldOneForm : db::SimpleTag {
     214            0 :   using type = tnsr::i<DataType, Dim, Fr>;
     215            0 :   static std::string name() {
     216              :     return Frame::prefix<Fr>() + "MagneticFieldOneForm";
     217              :   }
     218              : };
     219              : 
     220              : /// The square of the magnetic field, \f$B^iB_i\f$
     221              : template <typename DataType>
     222            1 : struct MagneticFieldSquared : db::SimpleTag {
     223            0 :   using type = Scalar<DataType>;
     224              : };
     225              : 
     226              : /// The magnetic pressure \f$p_m\f$.
     227              : template <typename DataType>
     228            1 : struct MagneticPressure : db::SimpleTag {
     229            0 :   using type = Scalar<DataType>;
     230              : };
     231              : 
     232              : /// The fluid pressure \f$p\f$.
     233              : template <typename DataType>
     234            1 : struct Pressure : db::SimpleTag {
     235            0 :   using type = Scalar<DataType>;
     236              : };
     237              : 
     238              : /// The rest-mass density \f$\rho\f$.
     239              : template <typename DataType>
     240            1 : struct RestMassDensity : db::SimpleTag {
     241            0 :   using type = Scalar<DataType>;
     242              : };
     243              : 
     244              : /// The sound speed squared \f$c_s^2\f$.
     245              : template <typename DataType>
     246            1 : struct SoundSpeedSquared : db::SimpleTag {
     247            0 :   using type = Scalar<DataType>;
     248              : };
     249              : 
     250              : /// The spatial velocity \f$v^i\f$ of the fluid,
     251              : /// where \f$v^i=u^i/W + \beta^i/\alpha\f$.
     252              : /// Here \f$u^i\f$ is the spatial part of the 4-velocity of the fluid,
     253              : /// \f$W\f$ is the Lorentz factor, \f$\beta^i\f$ is the shift vector,
     254              : /// and \f$\alpha\f$ is the lapse function. Note that \f$v^i\f$ is raised
     255              : /// and lowered with the spatial metric.
     256              : template <typename DataType, size_t Dim, typename Fr>
     257            1 : struct SpatialVelocity : db::SimpleTag {
     258            0 :   using type = tnsr::I<DataType, Dim, Fr>;
     259            0 :   static std::string name() { return Frame::prefix<Fr>() + "SpatialVelocity"; }
     260              : };
     261              : 
     262              : /// The spatial velocity one-form \f$v_i\f$, where \f$v_i\f$ is raised
     263              : /// and lowered with the spatial metric.
     264              : template <typename DataType, size_t Dim, typename Fr>
     265            1 : struct SpatialVelocityOneForm : db::SimpleTag {
     266            0 :   using type = tnsr::i<DataType, Dim, Fr>;
     267            0 :   static std::string name() {
     268              :     return Frame::prefix<Fr>() + "SpatialVelocityOneForm";
     269              :   }
     270              : };
     271              : 
     272              : /// The spatial velocity squared \f$v^2 = v_i v^i\f$.
     273              : template <typename DataType>
     274            1 : struct SpatialVelocitySquared : db::SimpleTag {
     275            0 :   using type = Scalar<DataType>;
     276              : };
     277              : 
     278              : /// The specific entropy \f$s\f$.
     279              : template <typename DataType>
     280            1 : struct SpecificEntropy : db::SimpleTag {
     281            0 :   using type = Scalar<DataType>;
     282              : };
     283              : 
     284              : /// The relativistic specific enthalpy \f$h\f$.
     285              : template <typename DataType>
     286            1 : struct SpecificEnthalpy : db::SimpleTag {
     287            0 :   using type = Scalar<DataType>;
     288              : };
     289              : 
     290              : /// The specific internal energy \f$\epsilon\f$.
     291              : template <typename DataType>
     292            1 : struct SpecificInternalEnergy : db::SimpleTag {
     293            0 :   using type = Scalar<DataType>;
     294              : };
     295              : 
     296              : /// The temperature \f$T\f$ of the fluid.
     297              : template <typename DataType>
     298            1 : struct Temperature : db::SimpleTag {
     299            0 :   using type = Scalar<DataType>;
     300              : };
     301              : 
     302              : /// \brief Tag containing the transport velocity.
     303              : ///
     304              : /// The transport velocity is defined as \f$v_t^i=\alpha v^i-\beta^i\f$,
     305              : /// with $v^i$ being the spatial velocity, $\alpha$ the lapse, and
     306              : /// $\beta^i$ the shift.
     307              : template <typename DataType, size_t Dim, typename Fr>
     308            1 : struct TransportVelocity : db::SimpleTag {
     309            0 :   using type = tnsr::I<DataType, Dim, Fr>;
     310              : };
     311              : 
     312              : /// The spatial components of the four-velocity one-form \f$u_i\f$.
     313              : template <typename DataType, size_t Dim, typename Fr>
     314            1 : struct LowerSpatialFourVelocity : db::SimpleTag {
     315            0 :   using type = tnsr::i<DataType, Dim, Fr>;
     316              : };
     317              : 
     318              : /// The Lorentz factor \f$W\f$ times the spatial velocity \f$v^i\f$.
     319              : template <typename DataType, size_t Dim, typename Fr>
     320            1 : struct LorentzFactorTimesSpatialVelocity : db::SimpleTag {
     321            0 :   using type = tnsr::I<DataType, Dim, Fr>;
     322              : };
     323              : 
     324              : /// The vector \f$J^i\f$ in \f$\dot{M} = -\int J^i s_i d^2S\f$,
     325              : /// representing the mass flux through a surface with normal \f$s_i\f$.
     326              : ///
     327              : /// Note that the integral is understood
     328              : /// as a flat-space integral: all metric factors are included in \f$J^i\f$.
     329              : /// In particular, if the integral is done over a Strahlkorper, the
     330              : /// `gr::surfaces::euclidean_area_element` of the Strahlkorper should be used,
     331              : /// and \f$s_i\f$ is
     332              : /// the normal one-form to the Strahlkorper normalized with the flat metric,
     333              : /// \f$s_is_j\delta^{ij}=1\f$.
     334              : ///
     335              : /// The formula is
     336              : /// \f$ J^i = \rho W \sqrt{\gamma}(\alpha v^i-\beta^i)\f$,
     337              : /// where \f$\rho\f$ is the mass density, \f$W\f$ is the Lorentz factor,
     338              : /// \f$v^i\f$ is the spatial velocity of the fluid,
     339              : /// \f$\gamma\f$ is the determinant of the 3-metric \f$\gamma_{ij}\f$,
     340              : /// \f$\alpha\f$ is the lapse, and \f$\beta^i\f$ is the shift.
     341              : template <typename DataType, size_t Dim, typename Fr>
     342            1 : struct MassFlux : db::SimpleTag {
     343            0 :   using type = tnsr::I<DataType, Dim, Fr>;
     344            0 :   static std::string name() { return Frame::prefix<Fr>() + "MassFlux"; }
     345              : };
     346              : 
     347              : /// The equation of state retrieved from the analytic solution / data in the
     348              : /// input file
     349            1 : struct GrmhdEquationOfState : db::SimpleTag {
     350            0 :   using type = std::unique_ptr<EquationsOfState::EquationOfState<true, 3>>;
     351              : 
     352              :   template <typename Metavariables>
     353            0 :   using option_tags =
     354              :       tmpl::list<OptionTags::GrmhdEquationOfState,
     355              :                  ::evolution::initial_data::OptionTags::InitialData>;
     356            0 :   static constexpr bool pass_metavariables = true;
     357              : 
     358              :   template <typename Metavariables>
     359            0 :   static type create_from_options(
     360              :       const std::optional<type>& eos,
     361              :       const std::unique_ptr<::evolution::initial_data::InitialData>&
     362              :           initial_data) {
     363              :     if (eos.has_value()) {
     364              :       return eos.value()->get_clone();
     365              :     } else {
     366              :       return call_with_dynamic_type<
     367              :           type,
     368              :           tmpl::at<typename Metavariables::factory_creation::factory_classes,
     369              :                    ::evolution::initial_data::InitialData>>(
     370              :           initial_data.get(), [](const auto* const derived_initial_data) {
     371              :             using id_type = std::decay_t<decltype(*derived_initial_data)>;
     372              :             if constexpr (::evolution::is_numeric_initial_data_v<id_type>) {
     373              :               ERROR(
     374              :                   "Equation of State cannot currently be parsed from numeric"
     375              :                   "initial data, please explicitly specify the equation of "
     376              :                   "state for the evolution in the input file.");
     377              :               return std::make_unique<EquationsOfState::Barotropic3D<
     378              :                   EquationsOfState::PolytropicFluid<true>>>(
     379              :                   EquationsOfState::PolytropicFluid<true>(100.0, 2.0));
     380              :             } else {
     381              :               using eos_type = std::decay_t<decltype(
     382              :                   std::declval<id_type>().equation_of_state())>;
     383              :               const auto& derived_eos =
     384              :                   derived_initial_data->equation_of_state();
     385              :               if constexpr (eos_type::thermodynamic_dim < 3) {
     386              :                 return (derived_eos.promote_to_3d_eos());
     387              :               }
     388              :               else {
     389              :                 return derived_eos.get_clone();
     390              :               }
     391              :             }
     392              :           });
     393              :     }
     394              :   }
     395              : };
     396              : }  // namespace Tags
     397              : 
     398              : }  // namespace hydro
        

Generated by: LCOV version 2.0-1