SpECTRE Documentation Coverage Report
Current view: top level - PointwiseFunctions/Hydro/EquationsOfState - Tabulated3d.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 41.8 % 55 23
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 <boost/preprocessor/arithmetic/dec.hpp>
       7              : #include <boost/preprocessor/arithmetic/inc.hpp>
       8              : #include <boost/preprocessor/control/expr_iif.hpp>
       9              : #include <boost/preprocessor/list/adt.hpp>
      10              : #include <boost/preprocessor/repetition/for.hpp>
      11              : #include <boost/preprocessor/repetition/repeat.hpp>
      12              : #include <boost/preprocessor/tuple/to_list.hpp>
      13              : #include <limits>
      14              : #include <pup.h>
      15              : 
      16              : #include "DataStructures/Tensor/Tensor.hpp"
      17              : #include "DataStructures/Tensor/TypeAliases.hpp"
      18              : #include "IO/H5/EosTable.hpp"
      19              : #include "IO/H5/File.hpp"
      20              : #include "NumericalAlgorithms/Interpolation/MultiLinearSpanInterpolation.hpp"
      21              : #include "Options/String.hpp"
      22              : #include "PointwiseFunctions/Hydro/EquationsOfState/EquationOfState.hpp"
      23              : #include "PointwiseFunctions/Hydro/Units.hpp"
      24              : #include "Utilities/Serialization/CharmPupable.hpp"
      25              : #include "Utilities/TMPL.hpp"
      26              : 
      27              : /// \cond
      28              : class DataVector;
      29              : /// \endcond
      30              : 
      31              : namespace EquationsOfState {
      32              : /*!
      33              :  * \ingroup EquationsOfStateGroup
      34              :  * \brief Nuclear matter equation of state in tabulated form.
      35              :  *
      36              :  * The equation of state takes the form
      37              :  *
      38              :  * \f[
      39              :  * p = p (T, rho, Y_e)
      40              :  * \f]
      41              :  *
      42              :  * where \f$\rho\f$ is the rest mass density, \f$T\f$ is the
      43              :  * temperature, and \f$Y_e\f$ is the electron fraction.
      44              :  * The temperature is given in units of MeV.
      45              :  */
      46              : template <bool IsRelativistic>
      47            1 : class Tabulated3D : public EquationOfState<IsRelativistic, 3> {
      48              :  public:
      49            0 :   static constexpr size_t thermodynamic_dim = 3;
      50            0 :   static constexpr bool is_relativistic = IsRelativistic;
      51              : 
      52            0 :   static constexpr Options::String help = {
      53              :       "A tabulated three-dimensional equation of state.\n"
      54              :       "The energy density, pressure and sound speed "
      55              :       "are tabulated as a function of density, electron_fraction and "
      56              :       "temperature."};
      57              : 
      58            0 :   struct TableFilename {
      59            0 :     using type = std::string;
      60            0 :     static constexpr Options::String help{"File name of the EOS table"};
      61              :   };
      62              : 
      63            0 :   struct TableSubFilename {
      64            0 :     using type = std::string;
      65            0 :     static constexpr Options::String help{
      66              :         "Subfile name of the EOS table, e.g., 'dd2'."};
      67              :   };
      68              : 
      69            0 :   using options = tmpl::list<TableFilename, TableSubFilename>;
      70              : 
      71              :   /// Fields stored in the table
      72            0 :   enum : size_t {
      73              :     Epsilon = 0,
      74              :     Pressure,
      75              :     CsSquared,
      76              :     DeltaMu,
      77              :     Kappa,
      78              :     Zeta,
      79              :     SpecificEntropy,
      80              :     NumberOfVars
      81              :   };
      82              : 
      83            0 :   Tabulated3D() = default;
      84            0 :   Tabulated3D(const Tabulated3D&) = default;
      85            0 :   Tabulated3D& operator=(const Tabulated3D&) = default;
      86            0 :   Tabulated3D(Tabulated3D&&) = default;
      87            0 :   Tabulated3D& operator=(Tabulated3D&&) = default;
      88            0 :   ~Tabulated3D() override = default;
      89              : 
      90            0 :   explicit Tabulated3D(const std::string& filename,
      91              :                        const std::string& subfilename);
      92              : 
      93            0 :   explicit Tabulated3D(std::vector<double> electron_fraction,
      94              :                        std::vector<double> log_density,
      95              :                        std::vector<double> log_temperature,
      96              :                        std::vector<double> table_data, double energy_shift,
      97              :                        double enthalpy_minimum);
      98              : 
      99            0 :   explicit Tabulated3D(const h5::EosTable& spectre_eos);
     100              : 
     101              :   EQUATION_OF_STATE_FORWARD_DECLARE_MEMBERS(Tabulated3D, 3)
     102              : 
     103              :   template <class DataType>
     104            0 :   void convert_to_table_quantities(
     105              :       const gsl::not_null<Scalar<DataType>*> converted_electron_fraction,
     106              :       const gsl::not_null<Scalar<DataType>*> log_rest_mass_density,
     107              :       const gsl::not_null<Scalar<DataType>*> log_temperature,
     108              :       const Scalar<DataType>& electron_fraction,
     109              :       const Scalar<DataType>& rest_mass_density,
     110              :       const Scalar<DataType>& temperature) const {
     111              :     get(*converted_electron_fraction) = get(electron_fraction);
     112              :     get(*log_rest_mass_density) = get(rest_mass_density);
     113              :     get(*log_temperature) = get(temperature);
     114              : 
     115              :     // Enforce physicality of input
     116              :     // We reuse the same variables here, these are not log yet.
     117              :     enforce_physicality(*converted_electron_fraction, *log_rest_mass_density,
     118              :                         *log_temperature);
     119              : 
     120              :     // Table uses log T and log rho
     121              :     get(*log_rest_mass_density) = log(get(*log_rest_mass_density));
     122              :     get(*log_temperature) = log(get(*log_temperature));
     123              :   }
     124              : 
     125            0 :   std::unique_ptr<EquationOfState<IsRelativistic, 3>> get_clone()
     126              :       const override;
     127              : 
     128            0 :   void initialize(std::vector<double> electron_fraction,
     129              :                   std::vector<double> log_density,
     130              :                   std::vector<double> log_temperature,
     131              :                   std::vector<double> table_data, double energy_shift,
     132              :                   double enthalpy_minimum);
     133              : 
     134              : 
     135            0 :   void initialize(const h5::EosTable& spectre_eos);
     136              : 
     137            0 :   bool is_equal(const EquationOfState<IsRelativistic, 3>& rhs) const override;
     138              : 
     139              :   /// \brief Returns `true` if the EOS is barotropic
     140            1 :   bool is_barotropic() const override { return false; }
     141              : 
     142              :   /// \brief Returns `true` if the EOS is in beta-equilibrium
     143            1 :   bool is_equilibrium() const override { return false; }
     144              : 
     145            0 :   bool operator==(const Tabulated3D<IsRelativistic>& rhs) const;
     146              : 
     147            0 :   bool operator!=(const Tabulated3D<IsRelativistic>& rhs) const;
     148              : 
     149              :   template <class DataType>
     150            0 :   Scalar<DataType> equilibrium_electron_fraction_from_density_temperature_impl(
     151              :       const Scalar<DataType>& rest_mass_density,
     152              :       const Scalar<DataType>& temperature) const;
     153              : 
     154              :   /// @{
     155              :   /*!
     156              :    * Computes the electron fraction in beta-equilibrium \f$Y_e^{\rm eq}\f$ from
     157              :    * the rest mass density \f$\rho\f$ and the temperature \f$T\f$.
     158              :    */
     159            1 :   Scalar<double> equilibrium_electron_fraction_from_density_temperature(
     160              :       const Scalar<double>& rest_mass_density,
     161              :       const Scalar<double>& temperature) const override {
     162              :     return equilibrium_electron_fraction_from_density_temperature_impl<double>(
     163              :         rest_mass_density, temperature);
     164              :   }
     165              : 
     166            1 :   Scalar<DataVector> equilibrium_electron_fraction_from_density_temperature(
     167              :       const Scalar<DataVector>& rest_mass_density,
     168              :       const Scalar<DataVector>& temperature) const override {
     169              :     return equilibrium_electron_fraction_from_density_temperature_impl<
     170              :         DataVector>(rest_mass_density, temperature);
     171              :   }
     172              :   /// @}
     173              :   //
     174              : 
     175              :   template <typename DataType>
     176            0 :   void enforce_physicality(Scalar<DataType>& electron_fraction,
     177              :                            Scalar<DataType>& density,
     178              :                            Scalar<DataType>& temperature) const;
     179              : 
     180            0 :   WRAPPED_PUPable_decl_base_template(  // NOLINT
     181              :       SINGLE_ARG(EquationOfState<IsRelativistic, 3>), Tabulated3D);
     182              : 
     183              :   /// The lower bound of the electron fraction that is valid for this EOS
     184            1 :   double electron_fraction_lower_bound() const override {
     185              :     return table_electron_fraction_.front();
     186              :   }
     187              : 
     188              :   /// The upper bound of the electron fraction that is valid for this EOS
     189            1 :   double electron_fraction_upper_bound() const override {
     190              :     return table_electron_fraction_.back();
     191              :   }
     192              : 
     193              :   /// The lower bound of the rest mass density that is valid for this EOS
     194            1 :   double rest_mass_density_lower_bound() const override {
     195              :     return std::exp((table_log_density_.front()));
     196              :   }
     197              : 
     198              :   /// The upper bound of the rest mass density that is valid for this EOS
     199            1 :   double rest_mass_density_upper_bound() const override {
     200              :     return std::exp((table_log_density_.back()));
     201              :   }
     202              : 
     203              :   /// The lower bound of the temperature that is valid for this EOS
     204            1 :   double temperature_lower_bound() const override {
     205              :     return std::exp((table_log_temperature_.front()));
     206              :   }
     207              : 
     208              :   /// The upper bound of the temperature that is valid for this EOS
     209            1 :   double temperature_upper_bound() const override {
     210              :     return std::exp((table_log_temperature_.back()));
     211              :   }
     212              : 
     213              :   /// The lower bound of the specific internal energy that is valid for this EOS
     214              :   /// at the given rest mass density \f$\rho\f$ and electron fraction \f$Y_e\f$
     215            1 :   double specific_internal_energy_lower_bound(
     216              :       const double rest_mass_density,
     217              :       const double electron_fraction) const override;
     218              : 
     219              :   /// The upper bound of the specific internal energy that is valid for this EOS
     220              :   /// at the given rest mass density \f$\rho\f$
     221            1 :   double specific_internal_energy_upper_bound(
     222              :       const double rest_mass_density,
     223              :       const double electron_fraction) const override;
     224              : 
     225              :   /// The lower bound of the specific enthalpy that is valid for this EOS
     226            1 :   double specific_enthalpy_lower_bound() const override {
     227              :     return enthalpy_minimum_;
     228              :   }
     229              : 
     230              :   /// The baryon mass for this EoS
     231            1 :   double baryon_mass() const override {
     232              :     return hydro::units::geometric::neutron_mass;
     233              :   }
     234              : 
     235              :  private:
     236              :   EQUATION_OF_STATE_FORWARD_DECLARE_MEMBER_IMPLS(3)
     237              : 
     238            0 :   void initialize_interpolator();
     239              : 
     240              :   /// Energy shift used to account for negative specific internal energies,
     241              :   /// which are only stored logarithmically
     242            1 :   double energy_shift_ = 0.;
     243              : 
     244              :   /// Enthalpy minium  across the table
     245            1 :   double enthalpy_minimum_ = 1.;
     246              : 
     247              :   /// Main interpolator for the EoS.
     248              :   /// The ordering is  \f$(\log T. \log \rho, Y_e)\f$.
     249              :   /// Assumed to be sorted in ascending order.
     250            1 :   intrp::UniformMultiLinearSpanInterpolation<3, NumberOfVars> interpolator_{};
     251              :   /// Electron fraction
     252            1 :   std::vector<double> table_electron_fraction_{};
     253              :   /// Logarithmic rest-mass denisty
     254            1 :   std::vector<double> table_log_density_{};
     255              :   /// Logarithmic temperature
     256            1 :   std::vector<double> table_log_temperature_{};
     257              :   /// Tabulate data. Entries are stated in the enum
     258            1 :   std::vector<double> table_data_{};
     259              : 
     260              :   /// Tolerance on upper bound for root finding
     261            1 :   static constexpr double upper_bound_tolerance_ = 0.9999;
     262              : };
     263              : 
     264              : /// \cond
     265              : template <bool IsRelativistic>
     266              : PUP::able::PUP_ID EquationsOfState::Tabulated3D<IsRelativistic>::my_PUP_ID = 0;
     267              : /// \endcond
     268              : 
     269              : }  // namespace EquationsOfState
        

Generated by: LCOV version 2.0-1