SpECTRE Documentation Coverage Report
Current view: top level - PointwiseFunctions/Hydro/EquationsOfState - EquationOfState.hpp Hit Total Coverage
Commit: 2ae2b99409ac582030d56a4560a92a3e066a7e54 Lines: 38 61 62.3 %
Date: 2022-01-15 08:40:38
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 <boost/preprocessor/arithmetic/sub.hpp>
       7             : #include <boost/preprocessor/list/for_each.hpp>
       8             : #include <boost/preprocessor/punctuation/comma_if.hpp>
       9             : #include <boost/preprocessor/repetition/repeat.hpp>
      10             : #include <boost/preprocessor/tuple/enum.hpp>
      11             : #include <boost/preprocessor/tuple/to_list.hpp>
      12             : 
      13             : #include "DataStructures/Tensor/TypeAliases.hpp"
      14             : #include "Parallel/CharmPupable.hpp"
      15             : #include "Utilities/TMPL.hpp"
      16             : #include "Utilities/TypeTraits.hpp"
      17             : 
      18             : /// \cond
      19             : class DataVector;
      20             : namespace EquationsOfState {
      21             : template <bool IsRelativistic>
      22             : class DarkEnergyFluid;
      23             : template <bool IsRelativistic>
      24             : class IdealFluid;
      25             : template <bool IsRelativistic>
      26             : class PolytropicFluid;
      27             : }  // namespace EquationsOfState
      28             : /// \endcond
      29             : 
      30             : /// Contains all equations of state, including base class
      31             : namespace EquationsOfState {
      32             : 
      33             : namespace detail {
      34             : template <bool IsRelativistic, size_t ThermodynamicDim>
      35             : struct DerivedClasses;
      36             : 
      37             : template <bool IsRelativistic>
      38             : struct DerivedClasses<IsRelativistic, 1> {
      39             :   using type = tmpl::list<PolytropicFluid<IsRelativistic>>;
      40             : };
      41             : 
      42             : template <>
      43             : struct DerivedClasses<true, 2> {
      44             :   using type = tmpl::list<DarkEnergyFluid<true>, IdealFluid<true>>;
      45             : };
      46             : 
      47             : template <>
      48             : struct DerivedClasses<false, 2> {
      49             :   using type = tmpl::list<IdealFluid<false>>;
      50             : };
      51             : }  // namespace detail
      52             : 
      53             : /*!
      54             :  * \ingroup EquationsOfStateGroup
      55             :  * \brief Base class for equations of state depending on whether or not the
      56             :  * system is relativistic, and the number of independent thermodynamic variables
      57             :  * (`ThermodynamicDim`) needed to determine the pressure.
      58             :  *
      59             :  * The template parameter `IsRelativistic` is `true` for relativistic equations
      60             :  * of state and `false` for non-relativistic equations of state.
      61             :  */
      62             : template <bool IsRelativistic, size_t ThermodynamicDim>
      63           1 : class EquationOfState;
      64             : 
      65             : /*!
      66             :  * \ingroup EquationsOfStateGroup
      67             :  * \brief Base class for equations of state which need one thermodynamic
      68             :  * variable in order to determine the pressure.
      69             :  *
      70             :  * The template parameter `IsRelativistic` is `true` for relativistic equations
      71             :  * of state and `false` for non-relativistic equations of state.
      72             :  */
      73             : template <bool IsRelativistic>
      74           1 : class EquationOfState<IsRelativistic, 1>
      75             :     : public PUP::able {
      76             :  public:
      77           0 :   static constexpr bool is_relativistic = IsRelativistic;
      78           0 :   static constexpr size_t thermodynamic_dim = 1;
      79           0 :   using creatable_classes =
      80             :       typename detail::DerivedClasses<IsRelativistic, 1>::type;
      81             : 
      82           0 :   EquationOfState() = default;
      83           0 :   EquationOfState(const EquationOfState&) = default;
      84           0 :   EquationOfState& operator=(const EquationOfState&) = default;
      85           0 :   EquationOfState(EquationOfState&&) = default;
      86           0 :   EquationOfState& operator=(EquationOfState&&) = default;
      87           0 :   ~EquationOfState() override = default;
      88             : 
      89           0 :   WRAPPED_PUPable_abstract(EquationOfState);  // NOLINT
      90             : 
      91             :   /// @{
      92             :   /*!
      93             :    * Computes the pressure \f$p\f$ from the rest mass density \f$\rho\f$.
      94             :    */
      95           1 :   virtual Scalar<double> pressure_from_density(
      96             :       const Scalar<double>& /*rest_mass_density*/) const = 0;
      97           1 :   virtual Scalar<DataVector> pressure_from_density(
      98             :       const Scalar<DataVector>& /*rest_mass_density*/) const = 0;
      99             :   /// @}
     100             : 
     101             :   /// @{
     102             :   /*!
     103             :    * Computes the rest mass density \f$\rho\f$ from the specific enthalpy
     104             :    * \f$h\f$.
     105             :    */
     106           1 :   virtual Scalar<double> rest_mass_density_from_enthalpy(
     107             :       const Scalar<double>& /*specific_enthalpy*/) const = 0;
     108           1 :   virtual Scalar<DataVector> rest_mass_density_from_enthalpy(
     109             :       const Scalar<DataVector>& /*specific_enthalpy*/) const = 0;
     110             :   /// @}
     111             : 
     112             :   /// @{
     113             :   /*!
     114             :    * Computes the specific enthalpy \f$h\f$ from the rest mass density
     115             :    * \f$\rho\f$.
     116             :    */
     117           1 :   virtual Scalar<double> specific_enthalpy_from_density(
     118             :       const Scalar<double>& /*rest_mass_density*/) const = 0;
     119           1 :   virtual Scalar<DataVector> specific_enthalpy_from_density(
     120             :       const Scalar<DataVector>& /*rest_mass_density*/) const = 0;
     121             :   /// @}
     122             : 
     123             :   /// @{
     124             :   /*!
     125             :    * Computes the specific internal energy \f$\epsilon\f$ from the rest mass
     126             :    * density \f$\rho\f$.
     127             :    */
     128           1 :   virtual Scalar<double> specific_internal_energy_from_density(
     129             :       const Scalar<double>& /*rest_mass_density*/) const = 0;
     130           1 :   virtual Scalar<DataVector> specific_internal_energy_from_density(
     131             :       const Scalar<DataVector>& /*rest_mass_density*/) const = 0;
     132             :   /// @}
     133             : 
     134             :   /// @{
     135             :   /*!
     136             :    * Computes \f$\chi=\partial p / \partial \rho\f$ from \f$\rho\f$, where
     137             :    * \f$p\f$ is the pressure and \f$\rho\f$ is the rest mass density.
     138             :    */
     139           1 :   virtual Scalar<double> chi_from_density(
     140             :       const Scalar<double>& /*rest_mass_density*/) const = 0;
     141           1 :   virtual Scalar<DataVector> chi_from_density(
     142             :       const Scalar<DataVector>& /*rest_mass_density*/) const = 0;
     143             :   /// @}
     144             : 
     145             :   /// @{
     146             :   /*!
     147             :    * Computes \f$\kappa p/\rho^2=(p/\rho^2)\partial p / \partial \epsilon\f$
     148             :    * from \f$\rho\f$, where \f$p\f$ is the pressure, \f$\rho\f$ is the rest mass
     149             :    * density, and \f$\epsilon\f$ is the specific internal energy.
     150             :    *
     151             :    * The reason for not returning just
     152             :    * \f$\kappa=\partial p / \partial \epsilon\f$ is to avoid division by zero
     153             :    * for small values of \f$\rho\f$ when assembling the speed of sound with
     154             :    * some equations of state.
     155             :    */
     156           1 :   virtual Scalar<double> kappa_times_p_over_rho_squared_from_density(
     157             :       const Scalar<double>& /*rest_mass_density*/) const = 0;
     158           1 :   virtual Scalar<DataVector> kappa_times_p_over_rho_squared_from_density(
     159             :       const Scalar<DataVector>& /*rest_mass_density*/) const = 0;
     160             : 
     161             :   /// The lower bound of the rest mass density that is valid for this EOS
     162           1 :   virtual double rest_mass_density_lower_bound() const = 0;
     163             : 
     164             :   /// The upper bound of the rest mass density that is valid for this EOS
     165           1 :   virtual double rest_mass_density_upper_bound() const = 0;
     166             : 
     167             :   /// The lower bound of the specific internal energy that is valid for this EOS
     168             :   /// at the given rest mass density \f$\rho\f$
     169           1 :   virtual double specific_internal_energy_lower_bound(
     170             :       const double rest_mass_density) const = 0;
     171             : 
     172             :   /// The upper bound of the specific internal energy that is valid for this EOS
     173             :   /// at the given rest mass density \f$\rho\f$
     174           1 :   virtual double specific_internal_energy_upper_bound(
     175             :       const double rest_mass_density) const = 0;
     176             : 
     177             :   /// The lower bound of the specific enthalpy that is valid for this EOS
     178           1 :   virtual double specific_enthalpy_lower_bound() const = 0;
     179             : };
     180             : 
     181             : /*!
     182             :  * \ingroup EquationsOfStateGroup
     183             :  * \brief Base class for equations of state which need two independent
     184             :  * thermodynamic variables in order to determine the pressure.
     185             :  *
     186             :  * The template parameter `IsRelativistic` is `true` for relativistic equations
     187             :  * of state and `false` for non-relativistic equations of state.
     188             :  */
     189             : template <bool IsRelativistic>
     190           1 : class EquationOfState<IsRelativistic, 2>
     191             :     : public PUP::able {
     192             :  public:
     193           0 :   static constexpr bool is_relativistic = IsRelativistic;
     194           0 :   static constexpr size_t thermodynamic_dim = 2;
     195           0 :   using creatable_classes =
     196             :       typename detail::DerivedClasses<IsRelativistic, 2>::type;
     197             : 
     198           0 :   EquationOfState() = default;
     199           0 :   EquationOfState(const EquationOfState&) = default;
     200           0 :   EquationOfState& operator=(const EquationOfState&) = default;
     201           0 :   EquationOfState(EquationOfState&&) = default;
     202           0 :   EquationOfState& operator=(EquationOfState&&) = default;
     203           0 :   ~EquationOfState() override = default;
     204             : 
     205           0 :   WRAPPED_PUPable_abstract(EquationOfState);  // NOLINT
     206             : 
     207             :   /// @{
     208             :   /*!
     209             :    * Computes the pressure \f$p\f$ from the rest mass density \f$\rho\f$ and the
     210             :    * specific internal energy \f$\epsilon\f$.
     211             :    */
     212           1 :   virtual Scalar<double> pressure_from_density_and_energy(
     213             :       const Scalar<double>& /*rest_mass_density*/,
     214             :       const Scalar<double>& /*specific_internal_energy*/) const = 0;
     215           1 :   virtual Scalar<DataVector> pressure_from_density_and_energy(
     216             :       const Scalar<DataVector>& /*rest_mass_density*/,
     217             :       const Scalar<DataVector>& /*specific_internal_energy*/) const = 0;
     218             :   /// @}
     219             : 
     220             :   /// @{
     221             :   /*!
     222             :    * Computes the pressure \f$p\f$ from the rest mass density \f$\rho\f$ and the
     223             :    * specific enthalpy \f$h\f$.
     224             :    */
     225           1 :   virtual Scalar<double> pressure_from_density_and_enthalpy(
     226             :       const Scalar<double>& /*rest_mass_density*/,
     227             :       const Scalar<double>& /*specific_enthalpy*/) const = 0;
     228           1 :   virtual Scalar<DataVector> pressure_from_density_and_enthalpy(
     229             :       const Scalar<DataVector>& /*rest_mass_density*/,
     230             :       const Scalar<DataVector>& /*specific_enthalpy*/) const = 0;
     231             :   /// @}
     232             : 
     233             :   /// @{
     234             :   /*!
     235             :    * Computes the specific enthalpy \f$h\f$ from the rest mass density
     236             :    * \f$\rho\f$ and the specific internal energy \f$\epsilon\f$.
     237             :    */
     238           1 :   virtual Scalar<double> specific_enthalpy_from_density_and_energy(
     239             :       const Scalar<double>& /*rest_mass_density*/,
     240             :       const Scalar<double>& /*specific_internal_energy*/) const = 0;
     241           1 :   virtual Scalar<DataVector> specific_enthalpy_from_density_and_energy(
     242             :       const Scalar<DataVector>& /*rest_mass_density*/,
     243             :       const Scalar<DataVector>& /*specific_internal_energy*/) const = 0;
     244             :   /// @}
     245             : 
     246             :   /// @{
     247             :   /*!
     248             :    * Computes the specific internal energy \f$\epsilon\f$ from the rest mass
     249             :    * density \f$\rho\f$ and the pressure \f$p\f$.
     250             :    */
     251           1 :   virtual Scalar<double> specific_internal_energy_from_density_and_pressure(
     252             :       const Scalar<double>& /*rest_mass_density*/,
     253             :       const Scalar<double>& /*pressure*/) const = 0;
     254           1 :   virtual Scalar<DataVector> specific_internal_energy_from_density_and_pressure(
     255             :       const Scalar<DataVector>& /*rest_mass_density*/,
     256             :       const Scalar<DataVector>& /*pressure*/) const = 0;
     257             :   /// @}
     258             : 
     259             :   /// @{
     260             :   /*!
     261             :    * Computes \f$\chi=\partial p / \partial \rho\f$ from the \f$\rho\f$ and
     262             :    * \f$\epsilon\f$, where \f$p\f$ is the pressure, \f$\rho\f$ is the rest mass
     263             :    * density, and \f$\epsilon\f$ is the specific internal energy.
     264             :    */
     265           1 :   virtual Scalar<double> chi_from_density_and_energy(
     266             :       const Scalar<double>& /*rest_mass_density*/,
     267             :       const Scalar<double>& /*specific_internal_energy*/) const = 0;
     268           1 :   virtual Scalar<DataVector> chi_from_density_and_energy(
     269             :       const Scalar<DataVector>& /*rest_mass_density*/,
     270             :       const Scalar<DataVector>& /*specific_internal_energy*/) const = 0;
     271             :   /// @}
     272             : 
     273             :   /// @{
     274             :   /*!
     275             :    * Computes \f$\kappa p/\rho^2=(p/\rho^2)\partial p / \partial \epsilon\f$
     276             :    * from \f$\rho\f$ and \f$\epsilon\f$, where \f$p\f$ is the pressure,
     277             :    * \f$\rho\f$ is the rest mass density, and \f$\epsilon\f$ is the specific
     278             :    * internal energy.
     279             :    *
     280             :    * The reason for not returning just
     281             :    * \f$\kappa=\partial p / \partial \epsilon\f$ is to avoid division by zero
     282             :    * for small values of \f$\rho\f$ when assembling the speed of sound with
     283             :    * some equations of state.
     284             :    */
     285           1 :   virtual Scalar<double> kappa_times_p_over_rho_squared_from_density_and_energy(
     286             :       const Scalar<double>& /*rest_mass_density*/,
     287             :       const Scalar<double>& /*specific_internal_energy*/) const = 0;
     288             :   virtual Scalar<DataVector>
     289           1 :   kappa_times_p_over_rho_squared_from_density_and_energy(
     290             :       const Scalar<DataVector>& /*rest_mass_density*/,
     291             :       const Scalar<DataVector>& /*specific_internal_energy*/) const = 0;
     292             :   /// @}
     293             : 
     294             :   /// The lower bound of the rest mass density that is valid for this EOS
     295           1 :   virtual double rest_mass_density_lower_bound() const = 0;
     296             : 
     297             :   /// The upper bound of the rest mass density that is valid for this EOS
     298           1 :   virtual double rest_mass_density_upper_bound() const = 0;
     299             : 
     300             :   /// The lower bound of the specific internal energy that is valid for this EOS
     301             :   /// at the given rest mass density \f$\rho\f$
     302           1 :   virtual double specific_internal_energy_lower_bound(
     303             :       const double rest_mass_density) const = 0;
     304             : 
     305             :   /// The upper bound of the specific internal energy that is valid for this EOS
     306             :   /// at the given rest mass density \f$\rho\f$
     307           1 :   virtual double specific_internal_energy_upper_bound(
     308             :       const double rest_mass_density) const = 0;
     309             : 
     310             :   /// The lower bound of the specific enthalpy that is valid for this EOS
     311           1 :   virtual double specific_enthalpy_lower_bound() const = 0;
     312             : };
     313             : }  // namespace EquationsOfState
     314             : 
     315             : /// \cond
     316             : #define EQUATION_OF_STATE_FUNCTIONS_1D                                    \
     317             :   (pressure_from_density, rest_mass_density_from_enthalpy,                \
     318             :    specific_enthalpy_from_density, specific_internal_energy_from_density, \
     319             :    chi_from_density, kappa_times_p_over_rho_squared_from_density)
     320             : 
     321             : #define EQUATION_OF_STATE_FUNCTIONS_2D                                   \
     322             :   (pressure_from_density_and_energy, pressure_from_density_and_enthalpy, \
     323             :    specific_enthalpy_from_density_and_energy,                            \
     324             :    specific_internal_energy_from_density_and_pressure,                   \
     325             :    chi_from_density_and_energy,                                          \
     326             :    kappa_times_p_over_rho_squared_from_density_and_energy)
     327             : 
     328             : #define EQUATION_OF_STATE_ARGUMENTS_EXPAND(z, n, type) \
     329             :   BOOST_PP_COMMA_IF(n) const Scalar<type>&
     330             : 
     331             : #define EQUATION_OF_STATE_FORWARD_DECLARE_MEMBERS_HELPER(r, DIM,        \
     332             :                                                          FUNCTION_NAME) \
     333             :   Scalar<double> FUNCTION_NAME(BOOST_PP_REPEAT(                         \
     334             :       DIM, EQUATION_OF_STATE_ARGUMENTS_EXPAND, double)) const override; \
     335             :   Scalar<DataVector> FUNCTION_NAME(BOOST_PP_REPEAT(                     \
     336             :       DIM, EQUATION_OF_STATE_ARGUMENTS_EXPAND, DataVector)) const override;
     337             : 
     338             : /// \endcond
     339             : 
     340             : /*!
     341             :  * \ingroup EquationsOfStateGroup
     342             :  * \brief Macro used to generate forward declarations of member functions in
     343             :  * derived classes
     344             :  */
     345           1 : #define EQUATION_OF_STATE_FORWARD_DECLARE_MEMBERS(DERIVED, DIM)               \
     346             :   BOOST_PP_LIST_FOR_EACH(                                                     \
     347             :       EQUATION_OF_STATE_FORWARD_DECLARE_MEMBERS_HELPER, DIM,                  \
     348             :       BOOST_PP_TUPLE_TO_LIST(BOOST_PP_TUPLE_ELEM(                             \
     349             :           BOOST_PP_SUB(DIM, 1),                                               \
     350             :           (EQUATION_OF_STATE_FUNCTIONS_1D, EQUATION_OF_STATE_FUNCTIONS_2D)))) \
     351             :                                                                               \
     352             :   /* clang-tidy: do not use non-const references */                           \
     353             :   void pup(PUP::er& p) override; /* NOLINT */                                 \
     354             :                                                                               \
     355             :   explicit DERIVED(CkMigrateMessage* /*unused*/);
     356             : 
     357             : /// \cond
     358             : #define EQUATION_OF_STATE_FORWARD_ARGUMENTS(z, n, unused) \
     359             :   BOOST_PP_COMMA_IF(n) arg##n
     360             : 
     361             : #define EQUATION_OF_STATE_ARGUMENTS_EXPAND_NAMED(z, n, type) \
     362             :   BOOST_PP_COMMA_IF(n) const Scalar<type>& arg##n
     363             : 
     364             : #define EQUATION_OF_STATE_MEMBER_DEFINITIONS_HELPER(                        \
     365             :     TEMPLATE, DERIVED, DATA_TYPE, DIM, FUNCTION_NAME)                       \
     366             :   TEMPLATE                                                                  \
     367             :   Scalar<DATA_TYPE> DERIVED::FUNCTION_NAME(BOOST_PP_REPEAT(                 \
     368             :       DIM, EQUATION_OF_STATE_ARGUMENTS_EXPAND_NAMED, DATA_TYPE)) const {    \
     369             :     return FUNCTION_NAME##_impl(                                            \
     370             :         BOOST_PP_REPEAT(DIM, EQUATION_OF_STATE_FORWARD_ARGUMENTS, UNUSED)); \
     371             :   }
     372             : 
     373             : #define EQUATION_OF_STATE_MEMBER_DEFINITIONS_HELPER_2(r, ARGS, FUNCTION_NAME) \
     374             :   EQUATION_OF_STATE_MEMBER_DEFINITIONS_HELPER(                                \
     375             :       BOOST_PP_TUPLE_ELEM(0, ARGS), BOOST_PP_TUPLE_ELEM(1, ARGS),             \
     376             :       BOOST_PP_TUPLE_ELEM(2, ARGS), BOOST_PP_TUPLE_ELEM(3, ARGS),             \
     377             :       FUNCTION_NAME)
     378             : /// \endcond
     379             : 
     380             : #define EQUATION_OF_STATE_MEMBER_DEFINITIONS(TEMPLATE, DERIVED, DATA_TYPE, \
     381           0 :                                              DIM)                          \
     382             :   BOOST_PP_LIST_FOR_EACH(                                                  \
     383             :       EQUATION_OF_STATE_MEMBER_DEFINITIONS_HELPER_2,                       \
     384             :       (TEMPLATE, DERIVED, DATA_TYPE, DIM),                                 \
     385             :       BOOST_PP_TUPLE_TO_LIST(BOOST_PP_TUPLE_ELEM(                          \
     386             :           BOOST_PP_SUB(DIM, 1),                                            \
     387             :           (EQUATION_OF_STATE_FUNCTIONS_1D, EQUATION_OF_STATE_FUNCTIONS_2D))))
     388             : 
     389             : /// \cond
     390             : #define EQUATION_OF_STATE_FORWARD_DECLARE_MEMBER_IMPLS_HELPER(r, DIM,        \
     391             :                                                               FUNCTION_NAME) \
     392             :   template <class DataType>                                                  \
     393             :   Scalar<DataType> FUNCTION_NAME##_impl(BOOST_PP_REPEAT(                     \
     394             :       DIM, EQUATION_OF_STATE_ARGUMENTS_EXPAND, DataType)) const;
     395             : /// \endcond
     396             : 
     397           0 : #define EQUATION_OF_STATE_FORWARD_DECLARE_MEMBER_IMPLS(DIM)       \
     398             :   BOOST_PP_LIST_FOR_EACH(                                         \
     399             :       EQUATION_OF_STATE_FORWARD_DECLARE_MEMBER_IMPLS_HELPER, DIM, \
     400             :       BOOST_PP_TUPLE_TO_LIST(BOOST_PP_TUPLE_ELEM(                 \
     401             :           BOOST_PP_SUB(DIM, 1),                                   \
     402             :           (EQUATION_OF_STATE_FUNCTIONS_1D, EQUATION_OF_STATE_FUNCTIONS_2D))))
     403             : 
     404             : #include "PointwiseFunctions/Hydro/EquationsOfState/DarkEnergyFluid.hpp"
     405             : #include "PointwiseFunctions/Hydro/EquationsOfState/IdealFluid.hpp"
     406             : #include "PointwiseFunctions/Hydro/EquationsOfState/PolytropicFluid.hpp"

Generated by: LCOV version 1.14