SpECTRE Documentation Coverage Report
Current view: top level - PointwiseFunctions/AnalyticSolutions/RelativisticEuler - TovStar.hpp Hit Total Coverage
Commit: 1c32b58340e006addc79befb2cdaa7547247e09c Lines: 6 33 18.2 %
Date: 2024-04-19 07:30:15
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 <limits>
       8             : 
       9             : #include "DataStructures/CachedTempBuffer.hpp"
      10             : #include "DataStructures/DataBox/Tag.hpp"
      11             : #include "DataStructures/DataVector.hpp"
      12             : #include "DataStructures/Tensor/EagerMath/Magnitude.hpp"
      13             : #include "DataStructures/Tensor/Tensor.hpp"
      14             : #include "Options/String.hpp"
      15             : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
      16             : #include "PointwiseFunctions/AnalyticSolutions/RelativisticEuler/Solutions.hpp"
      17             : #include "PointwiseFunctions/AnalyticSolutions/RelativisticEuler/Tov.hpp"
      18             : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"  // IWYU pragma: keep
      19             : #include "PointwiseFunctions/Hydro/EquationsOfState/Factory.hpp"  // IWYU pragma: keep
      20             : #include "PointwiseFunctions/Hydro/Tags.hpp"
      21             : #include "PointwiseFunctions/InitialDataUtilities/InitialData.hpp"
      22             : #include "Utilities/Gsl.hpp"
      23             : #include "Utilities/MakeWithValue.hpp"
      24             : #include "Utilities/Serialization/CharmPupable.hpp"
      25             : #include "Utilities/TMPL.hpp"
      26             : #include "Utilities/TaggedTuple.hpp"
      27             : 
      28             : /// \cond
      29             : namespace PUP {
      30             : class er;  // IWYU pragma: keep
      31             : }  // namespace PUP
      32             : /// \endcond
      33             : 
      34             : namespace RelativisticEuler::Solutions {
      35             : namespace tov_detail {
      36             : 
      37             : enum class StarRegion { Center, Interior, Exterior };
      38             : 
      39             : namespace Tags {
      40             : template <typename DataType>
      41             : struct MassOverRadius : db::SimpleTag {
      42             :   using type = Scalar<DataType>;
      43             : };
      44             : template <typename DataType>
      45             : struct LogSpecificEnthalpy : db::SimpleTag {
      46             :   using type = Scalar<DataType>;
      47             : };
      48             : template <typename DataType>
      49             : struct ConformalFactor : db::SimpleTag {
      50             :   using type = Scalar<DataType>;
      51             : };
      52             : template <typename DataType>
      53             : struct DrConformalFactor : db::SimpleTag {
      54             :   using type = Scalar<DataType>;
      55             : };
      56             : template <typename DataType>
      57             : struct ArealRadius : db::SimpleTag {
      58             :   using type = Scalar<DataType>;
      59             : };
      60             : template <typename DataType>
      61             : struct DrArealRadius : db::SimpleTag {
      62             :   using type = Scalar<DataType>;
      63             : };
      64             : template <typename DataType>
      65             : struct DrPressure : db::SimpleTag {
      66             :   using type = Scalar<DataType>;
      67             : };
      68             : template <typename DataType>
      69             : struct MetricTimePotential : db::SimpleTag {
      70             :   using type = Scalar<DataType>;
      71             : };
      72             : template <typename DataType>
      73             : struct DrMetricTimePotential : db::SimpleTag {
      74             :   using type = Scalar<DataType>;
      75             : };
      76             : template <typename DataType>
      77             : struct MetricRadialPotential : db::SimpleTag {
      78             :   using type = Scalar<DataType>;
      79             : };
      80             : template <typename DataType>
      81             : struct DrMetricRadialPotential : db::SimpleTag {
      82             :   using type = Scalar<DataType>;
      83             : };
      84             : template <typename DataType>
      85             : struct MetricAngularPotential : db::SimpleTag {
      86             :   using type = Scalar<DataType>;
      87             : };
      88             : template <typename DataType>
      89             : struct DrMetricAngularPotential : db::SimpleTag {
      90             :   using type = Scalar<DataType>;
      91             : };
      92             : }  // namespace Tags
      93             : 
      94             : template <typename DataType>
      95             : using TovVariablesCache = cached_temp_buffer_from_typelist<tmpl::list<
      96             :     Tags::MassOverRadius<DataType>, Tags::LogSpecificEnthalpy<DataType>,
      97             :     Tags::ConformalFactor<DataType>, Tags::DrConformalFactor<DataType>,
      98             :     Tags::ArealRadius<DataType>, Tags::DrArealRadius<DataType>,
      99             :     hydro::Tags::SpecificEnthalpy<DataType>,
     100             :     hydro::Tags::RestMassDensity<DataType>,
     101             :     hydro::Tags::ElectronFraction<DataType>, hydro::Tags::Pressure<DataType>,
     102             :     Tags::DrPressure<DataType>,
     103             :     ::Tags::deriv<hydro::Tags::Pressure<DataType>, tmpl::size_t<3>,
     104             :                   Frame::Inertial>,
     105             :     hydro::Tags::SpecificInternalEnergy<DataType>,
     106             :     hydro::Tags::Temperature<DataType>, Tags::MetricTimePotential<DataType>,
     107             :     Tags::DrMetricTimePotential<DataType>,
     108             :     Tags::MetricRadialPotential<DataType>,
     109             :     Tags::DrMetricRadialPotential<DataType>,
     110             :     Tags::MetricAngularPotential<DataType>,
     111             :     Tags::DrMetricAngularPotential<DataType>,
     112             :     hydro::Tags::LorentzFactor<DataType>,
     113             :     hydro::Tags::SpatialVelocity<DataType, 3>,
     114             :     hydro::Tags::MagneticField<DataType, 3>,
     115             :     hydro::Tags::DivergenceCleaningField<DataType>, gr::Tags::Lapse<DataType>,
     116             :     ::Tags::dt<gr::Tags::Lapse<DataType>>,
     117             :     ::Tags::deriv<gr::Tags::Lapse<DataType>, tmpl::size_t<3>, Frame::Inertial>,
     118             :     gr::Tags::Shift<DataType, 3>, ::Tags::dt<gr::Tags::Shift<DataType, 3>>,
     119             :     ::Tags::deriv<gr::Tags::Shift<DataType, 3>, tmpl::size_t<3>,
     120             :                   Frame::Inertial>,
     121             :     gr::Tags::SpatialMetric<DataType, 3>,
     122             :     ::Tags::dt<gr::Tags::SpatialMetric<DataType, 3>>,
     123             :     ::Tags::deriv<gr::Tags::SpatialMetric<DataType, 3>, tmpl::size_t<3>,
     124             :                   Frame::Inertial>,
     125             :     gr::Tags::SqrtDetSpatialMetric<DataType>,
     126             :     gr::Tags::ExtrinsicCurvature<DataType, 3>,
     127             :     gr::Tags::InverseSpatialMetric<DataType, 3>>>;
     128             : 
     129             : template <typename DataType, StarRegion Region>
     130             : struct TovVariables {
     131             :   static constexpr size_t Dim = 3;
     132             :   using Cache = TovVariablesCache<DataType>;
     133             : 
     134             :   TovVariables(const TovVariables&) = default;
     135             :   TovVariables& operator=(const TovVariables&) = default;
     136             :   TovVariables(TovVariables&&) = default;
     137             :   TovVariables& operator=(TovVariables&&) = default;
     138             :   virtual ~TovVariables() = default;
     139             :   TovVariables(
     140             :       const tnsr::I<DataType, 3>& local_coords, const DataType& local_radius,
     141             :       const RelativisticEuler::Solutions::TovSolution& local_radial_solution,
     142             :       const EquationsOfState::EquationOfState<true, 1>& local_eos)
     143             :       : coords(local_coords),
     144             :         radius(local_radius),
     145             :         radial_solution(local_radial_solution),
     146             :         eos(local_eos) {}
     147             : 
     148             :   const tnsr::I<DataType, 3>& coords;
     149             :   const DataType& radius;
     150             :   const RelativisticEuler::Solutions::TovSolution& radial_solution;
     151             :   const EquationsOfState::EquationOfState<true, 1>& eos;
     152             : 
     153             :   void operator()(gsl::not_null<Scalar<DataType>*> mass_over_radius,
     154             :                   gsl::not_null<Cache*> cache,
     155             :                   Tags::MassOverRadius<DataType> /*meta*/) const;
     156             :   void operator()(gsl::not_null<Scalar<DataType>*> log_specific_enthalpy,
     157             :                   gsl::not_null<Cache*> cache,
     158             :                   Tags::LogSpecificEnthalpy<DataType> /*meta*/) const;
     159             :   void operator()(gsl::not_null<Scalar<DataType>*> conformal_factor,
     160             :                   gsl::not_null<Cache*> cache,
     161             :                   Tags::ConformalFactor<DataType> /*meta*/) const;
     162             :   void operator()(gsl::not_null<Scalar<DataType>*> dr_conformal_factor,
     163             :                   gsl::not_null<Cache*> cache,
     164             :                   Tags::DrConformalFactor<DataType> /*meta*/) const;
     165             :   void operator()(gsl::not_null<Scalar<DataType>*> areal_radius,
     166             :                   gsl::not_null<Cache*> cache,
     167             :                   Tags::ArealRadius<DataType> /*meta*/) const;
     168             :   void operator()(gsl::not_null<Scalar<DataType>*> dr_areal_radius,
     169             :                   gsl::not_null<Cache*> cache,
     170             :                   Tags::DrArealRadius<DataType> /*meta*/) const;
     171             :   void operator()(gsl::not_null<Scalar<DataType>*> specific_enthalpy,
     172             :                   gsl::not_null<Cache*> cache,
     173             :                   hydro::Tags::SpecificEnthalpy<DataType> /*meta*/) const;
     174             :   void operator()(gsl::not_null<Scalar<DataType>*> temperature,
     175             :                   gsl::not_null<Cache*> cache,
     176             :                   hydro::Tags::Temperature<DataType> /*meta*/) const;
     177             :   void operator()(gsl::not_null<Scalar<DataType>*> rest_mass_density,
     178             :                   gsl::not_null<Cache*> cache,
     179             :                   hydro::Tags::RestMassDensity<DataType> /*meta*/) const;
     180             :   void operator()(gsl::not_null<Scalar<DataType>*> electron_fraction,
     181             :                   gsl::not_null<Cache*> cache,
     182             :                   hydro::Tags::ElectronFraction<DataType> /*meta*/) const;
     183             :   void operator()(gsl::not_null<Scalar<DataType>*> pressure,
     184             :                   gsl::not_null<Cache*> cache,
     185             :                   hydro::Tags::Pressure<DataType> /*meta*/) const;
     186             :   void operator()(gsl::not_null<Scalar<DataType>*> dr_pressure,
     187             :                   gsl::not_null<Cache*> cache,
     188             :                   Tags::DrPressure<DataType> /*meta*/) const;
     189             :   void operator()(
     190             :       gsl::not_null<tnsr::i<DataType, 3>*> deriv_pressure,
     191             :       gsl::not_null<Cache*> cache,
     192             :       ::Tags::deriv<hydro::Tags::Pressure<DataType>, tmpl::size_t<3>,
     193             :                     Frame::Inertial> /*meta*/) const;
     194             :   void operator()(gsl::not_null<Scalar<DataType>*> specific_internal_energy,
     195             :                   gsl::not_null<Cache*> cache,
     196             :                   hydro::Tags::SpecificInternalEnergy<DataType> /*meta*/) const;
     197             :   void operator()(gsl::not_null<Scalar<DataType>*> metric_time_potential,
     198             :                   gsl::not_null<Cache*> cache,
     199             :                   Tags::MetricTimePotential<DataType> /*meta*/) const;
     200             :   void operator()(gsl::not_null<Scalar<DataType>*> dr_metric_time_potential,
     201             :                   gsl::not_null<Cache*> cache,
     202             :                   Tags::DrMetricTimePotential<DataType> /*meta*/) const;
     203             :   void operator()(gsl::not_null<Scalar<DataType>*> metric_radial_potential,
     204             :                   gsl::not_null<Cache*> cache,
     205             :                   Tags::MetricRadialPotential<DataType> /*meta*/) const;
     206             :   void operator()(gsl::not_null<Scalar<DataType>*> dr_metric_radial_potential,
     207             :                   gsl::not_null<Cache*> cache,
     208             :                   Tags::DrMetricRadialPotential<DataType> /*meta*/) const;
     209             :   void operator()(gsl::not_null<Scalar<DataType>*> metric_angular_potential,
     210             :                   gsl::not_null<Cache*> cache,
     211             :                   Tags::MetricAngularPotential<DataType> /*meta*/) const;
     212             :   void operator()(gsl::not_null<Scalar<DataType>*> dr_metric_angular_potential,
     213             :                   gsl::not_null<Cache*> cache,
     214             :                   Tags::DrMetricAngularPotential<DataType> /*meta*/) const;
     215             :   void operator()(gsl::not_null<Scalar<DataType>*> lorentz_factor,
     216             :                   gsl::not_null<Cache*> cache,
     217             :                   hydro::Tags::LorentzFactor<DataType> /*meta*/) const;
     218             :   void operator()(gsl::not_null<tnsr::I<DataType, 3>*> spatial_velocity,
     219             :                   gsl::not_null<Cache*> cache,
     220             :                   hydro::Tags::SpatialVelocity<DataType, 3> /*meta*/) const;
     221             :   virtual void operator()(
     222             :       gsl::not_null<tnsr::I<DataType, 3>*> magnetic_field,
     223             :       gsl::not_null<Cache*> cache,
     224             :       hydro::Tags::MagneticField<DataType, 3> /*meta*/) const;
     225             :   void operator()(
     226             :       gsl::not_null<Scalar<DataType>*> div_cleaning_field,
     227             :       gsl::not_null<Cache*> cache,
     228             :       hydro::Tags::DivergenceCleaningField<DataType> /*meta*/) const;
     229             :   void operator()(gsl::not_null<Scalar<DataType>*> lapse,
     230             :                   gsl::not_null<Cache*> cache,
     231             :                   gr::Tags::Lapse<DataType> /*meta*/) const;
     232             :   void operator()(gsl::not_null<Scalar<DataType>*> dt_lapse,
     233             :                   gsl::not_null<Cache*> cache,
     234             :                   ::Tags::dt<gr::Tags::Lapse<DataType>> /*meta*/) const;
     235             :   void operator()(gsl::not_null<tnsr::i<DataType, 3>*> deriv_lapse,
     236             :                   gsl::not_null<Cache*> cache,
     237             :                   ::Tags::deriv<gr::Tags::Lapse<DataType>, tmpl::size_t<3>,
     238             :                                 Frame::Inertial> /*meta*/) const;
     239             :   void operator()(gsl::not_null<tnsr::I<DataType, 3>*> shift,
     240             :                   gsl::not_null<Cache*> cache,
     241             :                   gr::Tags::Shift<DataType, 3> /*meta*/) const;
     242             :   void operator()(gsl::not_null<tnsr::I<DataType, 3>*> dt_shift,
     243             :                   gsl::not_null<Cache*> cache,
     244             :                   ::Tags::dt<gr::Tags::Shift<DataType, 3>> /*meta*/) const;
     245             :   void operator()(gsl::not_null<tnsr::iJ<DataType, 3>*> deriv_shift,
     246             :                   gsl::not_null<Cache*> cache,
     247             :                   ::Tags::deriv<gr::Tags::Shift<DataType, 3>, tmpl::size_t<3>,
     248             :                                 Frame::Inertial> /*meta*/) const;
     249             :   void operator()(gsl::not_null<tnsr::ii<DataType, 3>*> spatial_metric,
     250             :                   gsl::not_null<Cache*> cache,
     251             :                   gr::Tags::SpatialMetric<DataType, 3> /*meta*/) const;
     252             :   void operator()(
     253             :       gsl::not_null<tnsr::ii<DataType, 3>*> dt_spatial_metric,
     254             :       gsl::not_null<Cache*> cache,
     255             :       ::Tags::dt<gr::Tags::SpatialMetric<DataType, 3>> /*meta*/) const;
     256             :   void operator()(
     257             :       gsl::not_null<tnsr::ijj<DataType, 3>*> deriv_spatial_metric,
     258             :       gsl::not_null<Cache*> cache,
     259             :       ::Tags::deriv<gr::Tags::SpatialMetric<DataType, 3>, tmpl::size_t<3>,
     260             :                     Frame::Inertial> /*meta*/) const;
     261             :   void operator()(gsl::not_null<Scalar<DataType>*> sqrt_det_spatial_metric,
     262             :                   gsl::not_null<Cache*> cache,
     263             :                   gr::Tags::SqrtDetSpatialMetric<DataType> /*meta*/) const;
     264             :   void operator()(gsl::not_null<tnsr::ii<DataType, 3>*> extrinsic_curvature,
     265             :                   gsl::not_null<Cache*> cache,
     266             :                   gr::Tags::ExtrinsicCurvature<DataType, 3> /*meta*/) const;
     267             :   void operator()(gsl::not_null<tnsr::II<DataType, 3>*> inv_spatial_metric,
     268             :                   gsl::not_null<Cache*> cache,
     269             :                   gr::Tags::InverseSpatialMetric<DataType, 3> /*meta*/) const;
     270             : };
     271             : }  // namespace tov_detail
     272             : 
     273             : /*!
     274             :  * \brief A static spherically symmetric star
     275             :  *
     276             :  * An analytic solution for a static, spherically-symmetric star found by
     277             :  * solving the Tolman-Oppenheimer-Volkoff (TOV) equations.  The equation of
     278             :  * state is assumed to be that of a polytropic fluid.
     279             :  *
     280             :  * If the spherically symmetric metric is written as
     281             :  *
     282             :  * \f[
     283             :  * ds^2 = - e^{2 \Phi_t} dt^2 + e^{2 \Phi_r} dr^2 + e^{2 \Phi_\Omega} r^2
     284             :  * d\Omega^2
     285             :  * \f]
     286             :  *
     287             :  * where \f$r = \delta_{mn} x^m x^n\f$ is the radial coordinate and
     288             :  * \f$\Phi_t\f$, \f$\Phi_r\f$, and \f$\Phi_\Omega\f$ are the metric potentials,
     289             :  * then the lapse, shift, and spatial metric in Cartesian coordinates are
     290             :  *
     291             :  * \f{align*}
     292             :  * \alpha &= e^{\Phi_t} \\
     293             :  * \beta^i &= 0 \\
     294             :  * \gamma_{ij} &= \delta_{ij} e^{2 \Phi_\Omega} + \delta_{im} \delta_{jn}
     295             :  * \frac{x^m x^n}{r^2} \left( e^{2 \Phi_r} - e^{2 \Phi_\Omega} \right)
     296             :  * \f}
     297             :  *
     298             :  * We solve the TOV equations with the method implemented in
     299             :  * `RelativisticEuler::Solutions::TovSolution`. It provides the areal
     300             :  * mass-over-radius \f$m(r)/r\f$ and the log of the specific enthalpy
     301             :  * \f$\log{h}\f$. In areal (Schwarzschild) coordinates the spatial metric
     302             :  * potentials are
     303             :  *
     304             :  * \f{align}
     305             :  * e^{\Phi_r} &= \left(1 - \frac{2m}{r}\right)^{-1/2} \\
     306             :  * e^{\Phi_\Omega} &= 1
     307             :  * \f}
     308             :  *
     309             :  * In isotropic coordinates the spatial metric potentials are
     310             :  *
     311             :  * \begin{equation}
     312             :  * e^{2\Phi_r} = e^{2\Phi_\Omega} = \psi^4
     313             :  * \text{,}
     314             :  * \end{equation}
     315             :  *
     316             :  * where $\psi = \sqrt{r / \bar{r}}$ is the conformal factor, $r$ is the areal
     317             :  * (Schwarzschild) radius and $\bar{r}$ is the isotropic radius. See
     318             :  * `RelativisticEuler::Solutions::TovSolution` for details.
     319             :  *
     320             :  * \warning Isotropic coordinates should be used because the metric derivatives
     321             :  * are smooth. Otherwise the grid will over-compensate with finite difference
     322             :  * cells.
     323             :  */
     324             : 
     325           1 : class TovStar : public virtual evolution::initial_data::InitialData,
     326             :                 public MarkAsAnalyticSolution,
     327             :                 public AnalyticSolution<3> {
     328             :  public:
     329           0 :   using equation_of_state_type = EquationsOfState::EquationOfState<true, 1>;
     330             : 
     331             :   /// The central density of the star.
     332           1 :   struct CentralDensity {
     333           0 :     using type = double;
     334           0 :     static constexpr Options::String help = {
     335             :         "The central density of the star."};
     336           0 :     static type lower_bound() { return 0.; }
     337             :   };
     338             : 
     339             :   /// Areal (Schwarzschild) or isotropic coordinates
     340           1 :   struct Coordinates {
     341           0 :     using type = RelativisticEuler::Solutions::TovCoordinates;
     342           0 :     static constexpr Options::String help = {
     343             :         "Areal ('Schwarzschild') or 'Isotropic' coordinates."};
     344             :   };
     345             : 
     346           0 :   static constexpr size_t volume_dim = 3_st;
     347             : 
     348           0 :   using options =
     349             :       tmpl::list<CentralDensity,
     350             :                  hydro::OptionTags::InitialDataEquationOfState<true, 1>,
     351             :                  Coordinates>;
     352             : 
     353           0 :   static constexpr Options::String help = {
     354             :       "A static, spherically-symmetric star found by solving the \n"
     355             :       "Tolman-Oppenheimer-Volkoff (TOV) equations, with a given central \n"
     356             :       "density and equation of state."};
     357             : 
     358           0 :   TovStar() = default;
     359           0 :   TovStar(const TovStar& /*rhs*/);
     360           0 :   TovStar& operator=(const TovStar& /*rhs*/);
     361           0 :   TovStar(TovStar&& /*rhs*/) = default;
     362           0 :   TovStar& operator=(TovStar&& /*rhs*/) = default;
     363           0 :   ~TovStar() override = default;
     364           0 :   TovStar(double central_rest_mass_density,
     365             :           std::unique_ptr<EquationsOfState::EquationOfState<true, 1>>
     366             :               equation_of_state,
     367             :           const RelativisticEuler::Solutions::TovCoordinates coordinate_system =
     368             :               RelativisticEuler::Solutions::TovCoordinates::Schwarzschild);
     369             : 
     370           0 :   auto get_clone() const
     371             :       -> std::unique_ptr<evolution::initial_data::InitialData> override;
     372             : 
     373             :   /// \cond
     374             :   explicit TovStar(CkMigrateMessage* msg);
     375             :   using PUP::able::register_constructor;
     376             :   WRAPPED_PUPable_decl_template(TovStar);
     377             :   /// \endcond
     378             : 
     379             :   /// Retrieve a collection of variables at `(x, t)`
     380             :   template <typename DataType, typename... Tags>
     381           1 :   tuples::TaggedTuple<Tags...> variables(const tnsr::I<DataType, 3>& x,
     382             :                                          const double /*t*/,
     383             :                                          tmpl::list<Tags...> /*meta*/) const {
     384             :     return variables_impl<tov_detail::TovVariables>(x, tmpl::list<Tags...>{});
     385             :   }
     386             : 
     387             :   /// NOLINTNEXTLINE(google-runtime-references)
     388           1 :   void pup(PUP::er& /*p*/) override;
     389             : 
     390           0 :   const EquationsOfState::EquationOfState<true, 1>& equation_of_state() const {
     391             :     return *equation_of_state_;
     392             :   }
     393             : 
     394             :   /// The radial profile of the star
     395           1 :   const RelativisticEuler::Solutions::TovSolution& radial_solution() const {
     396             :     return radial_solution_;
     397             :   }
     398             : 
     399             :  protected:
     400             :   template <template <class, tov_detail::StarRegion> class VarsComputer,
     401             :             typename DataType, typename... Tags, typename... VarsComputerArgs>
     402           0 :   tuples::TaggedTuple<Tags...> variables_impl(
     403             :       const tnsr::I<DataType, 3>& x, tmpl::list<Tags...> /*meta*/,
     404             :       VarsComputerArgs&&... vars_computer_args) const {
     405             :     const double outer_radius = radial_solution_.outer_radius();
     406             :     const double center_radius_cutoff = 1.e-30 * outer_radius;
     407             :     const DataType radius = get(magnitude(x));
     408             :     // Dispatch interior and exterior regions of the star.
     409             :     // - Include the equality in the conditions below for the outer radius so
     410             :     //   the `DataVector` variants are preferred over the pointwise `double`
     411             :     //   variant when possible.
     412             :     // - Order the conditions so the cheaper exterior solution is preferred over
     413             :     //   the interior.
     414             :     // - A `DataVector` variant for the center of the star is not needed because
     415             :     //   it's only a single point.
     416             :     if (min(radius) >= outer_radius) {
     417             :       // All points are outside the star. This could be replaced by a
     418             :       // Schwarzschild solution.
     419             :       using ExteriorVarsComputer =
     420             :           VarsComputer<DataType, tov_detail::StarRegion::Exterior>;
     421             :       typename ExteriorVarsComputer::Cache cache{get_size(radius)};
     422             :       ExteriorVarsComputer computer{
     423             :           x, radius, radial_solution_, *equation_of_state_,
     424             :           std::forward<VarsComputerArgs>(vars_computer_args)...};
     425             :       return {cache.get_var(computer, Tags{})...};
     426             :     } else if (max(radius) <= outer_radius and
     427             :                min(radius) > center_radius_cutoff) {
     428             :       // All points are in the star interior, but not at the center
     429             :       using InteriorVarsComputer =
     430             :           VarsComputer<DataType, tov_detail::StarRegion::Interior>;
     431             :       typename InteriorVarsComputer::Cache cache{get_size(radius)};
     432             :       InteriorVarsComputer computer{
     433             :           x, radius, radial_solution_, *equation_of_state_,
     434             :           std::forward<VarsComputerArgs>(vars_computer_args)...};
     435             :       return {cache.get_var(computer, Tags{})...};
     436             :     } else {
     437             :       // Points can be at the center, in the interior, or outside the star, so
     438             :       // check each point individually
     439             :       const size_t num_points = get_size(radius);
     440             :       tuples::TaggedTuple<Tags...> vars{typename Tags::type{num_points}...};
     441             :       const auto get_var = [&vars](const size_t point_index, auto& local_cache,
     442             :                                    const auto& local_computer, auto tag_v) {
     443             :         using tag = std::decay_t<decltype(tag_v)>;
     444             :         if constexpr (std::is_same_v<DataType, DataVector>) {
     445             :           using tags_double = typename VarsComputer<
     446             :               double, tov_detail::StarRegion::Exterior>::Cache::tags_list;
     447             :           using tags_dv = typename VarsComputer<
     448             :               DataVector, tov_detail::StarRegion::Exterior>::Cache::tags_list;
     449             :           using tag_double =
     450             :               tmpl::at<tags_double, tmpl::index_of<tags_dv, tag>>;
     451             :           const auto& tensor =
     452             :               local_cache.get_var(local_computer, tag_double{});
     453             :           for (size_t component = 0; component < tensor.size(); ++component) {
     454             :             get<tag>(vars)[component][point_index] = tensor[component];
     455             :           }
     456             :         } else {
     457             :           (void)point_index;
     458             :           get<tag>(vars) = local_cache.get_var(local_computer, tag{});
     459             :         }
     460             :         return '0';
     461             :       };
     462             :       using CenterVarsComputer =
     463             :           VarsComputer<double, tov_detail::StarRegion::Center>;
     464             :       using InteriorVarsComputer =
     465             :           VarsComputer<double, tov_detail::StarRegion::Interior>;
     466             :       using ExteriorVarsComputer =
     467             :           VarsComputer<double, tov_detail::StarRegion::Exterior>;
     468             :       for (size_t i = 0; i < num_points; ++i) {
     469             :         const tnsr::I<double, 3> x_i{
     470             :             {{get_element(get<0>(x), i), get_element(get<1>(x), i),
     471             :               get_element(get<2>(x), i)}}};
     472             :         if (get_element(radius, i) > outer_radius) {
     473             :           typename ExteriorVarsComputer::Cache cache{1};
     474             :           ExteriorVarsComputer computer{
     475             :               x_i, get_element(radius, i), radial_solution_,
     476             :               *equation_of_state_,
     477             :               std::forward<VarsComputerArgs>(vars_computer_args)...};
     478             :           expand_pack(get_var(i, cache, computer, Tags{})...);
     479             :         } else if (get_element(radius, i) > center_radius_cutoff) {
     480             :           typename InteriorVarsComputer::Cache cache{1};
     481             :           InteriorVarsComputer computer{
     482             :               x_i, get_element(radius, i), radial_solution_,
     483             :               *equation_of_state_,
     484             :               std::forward<VarsComputerArgs>(vars_computer_args)...};
     485             :           expand_pack(get_var(i, cache, computer, Tags{})...);
     486             :         } else {
     487             :           typename CenterVarsComputer::Cache cache{1};
     488             :           CenterVarsComputer computer{
     489             :               x_i, get_element(radius, i), radial_solution_,
     490             :               *equation_of_state_,
     491             :               std::forward<VarsComputerArgs>(vars_computer_args)...};
     492             :           expand_pack(get_var(i, cache, computer, Tags{})...);
     493             :         }
     494             :       }
     495             :       return vars;
     496             :     }
     497             :   }
     498             : 
     499             :  public:
     500             :   template <typename DataType>
     501           0 :   using tags = tmpl::list_difference<
     502             :       typename tov_detail::TovVariablesCache<DataType>::tags_list,
     503             :       tmpl::list<
     504             :           // Remove internal tags, which may not be available in the full domain
     505             :           tov_detail::Tags::MassOverRadius<DataType>,
     506             :           tov_detail::Tags::LogSpecificEnthalpy<DataType>,
     507             :           tov_detail::Tags::ConformalFactor<DataType>,
     508             :           tov_detail::Tags::DrConformalFactor<DataType>,
     509             :           tov_detail::Tags::ArealRadius<DataType>,
     510             :           tov_detail::Tags::DrArealRadius<DataType>,
     511             :           tov_detail::Tags::DrPressure<DataType>,
     512             :           tov_detail::Tags::MetricTimePotential<DataType>,
     513             :           tov_detail::Tags::DrMetricTimePotential<DataType>,
     514             :           tov_detail::Tags::MetricRadialPotential<DataType>,
     515             :           tov_detail::Tags::DrMetricRadialPotential<DataType>,
     516             :           tov_detail::Tags::MetricAngularPotential<DataType>,
     517             :           tov_detail::Tags::DrMetricAngularPotential<DataType>>>;
     518             : 
     519             :  private:
     520           0 :   friend bool operator==(const TovStar& lhs, const TovStar& rhs);
     521             : 
     522           0 :   double central_rest_mass_density_ =
     523             :       std::numeric_limits<double>::signaling_NaN();
     524           0 :   std::unique_ptr<equation_of_state_type> equation_of_state_;
     525           0 :   RelativisticEuler::Solutions::TovCoordinates coordinate_system_{};
     526           0 :   RelativisticEuler::Solutions::TovSolution radial_solution_{};
     527             : };
     528             : 
     529           0 : bool operator!=(const TovStar& lhs, const TovStar& rhs);
     530             : }  // namespace RelativisticEuler::Solutions

Generated by: LCOV version 1.14