SpECTRE Documentation Coverage Report
Current view: top level - PointwiseFunctions/AnalyticSolutions/Xcts - Schwarzschild.hpp Hit Total Coverage
Commit: 35a1e98cd3e4fdea528eb8100f99c2f707894fda Lines: 2 17 11.8 %
Date: 2024-04-19 00:10:48
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 <limits>
       7             : #include <memory>
       8             : #include <ostream>
       9             : 
      10             : #include "DataStructures/CachedTempBuffer.hpp"
      11             : #include "DataStructures/DataBox/Prefixes.hpp"
      12             : #include "DataStructures/DataVector.hpp"
      13             : #include "DataStructures/Tensor/Tensor.hpp"
      14             : #include "Elliptic/Systems/Xcts/Tags.hpp"
      15             : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp"
      16             : #include "Options/String.hpp"
      17             : #include "PointwiseFunctions/AnalyticSolutions/Xcts/CommonVariables.hpp"
      18             : #include "PointwiseFunctions/AnalyticSolutions/Xcts/Flatness.hpp"
      19             : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
      20             : #include "PointwiseFunctions/GeneralRelativity/Tags/Conformal.hpp"
      21             : #include "PointwiseFunctions/InitialDataUtilities/AnalyticSolution.hpp"
      22             : #include "Utilities/ContainerHelpers.hpp"
      23             : #include "Utilities/Gsl.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;
      31             : }  // namespace PUP
      32             : /// \endcond
      33             : 
      34             : namespace Xcts::Solutions {
      35             : 
      36             : /// Various coordinate systems in which to express the Schwarzschild solution
      37           1 : enum class SchwarzschildCoordinates {
      38             :   /*!
      39             :    * \brief Isotropic Schwarzschild coordinates
      40             :    *
      41             :    * These arise from the canonical Schwarzschild coordinates by the radial
      42             :    * transformation
      43             :    *
      44             :    * \f{equation}
      45             :    * r = \bar{r}\left(1+\frac{M}{2\bar{r}}\right)^2
      46             :    * \f}
      47             :    *
      48             :    * (Eq. (1.61) in \cite BaumgarteShapiro) where \f$r\f$ is the canonical
      49             :    * Schwarzschild radius, also referred to as "areal" radius because it is
      50             :    * defined such that spheres with constant \f$r\f$ have the area \f$4\pi
      51             :    * r^2\f$, and \f$\bar{r}\f$ is the "isotropic" radius. In the isotropic
      52             :    * radius the Schwarzschild spatial metric is conformally flat:
      53             :    *
      54             :    * \f{equation}
      55             :    * \gamma_{ij}=\psi^4\eta_{ij} \quad \text{with conformal factor} \quad
      56             :    * \psi=1+\frac{M}{2\bar{r}}
      57             :    * \f}
      58             :    *
      59             :    * (Table 2.1 in \cite BaumgarteShapiro). The lapse in the conformal radius is
      60             :    *
      61             :    * \f{equation}
      62             :    * \alpha=\frac{1-M/(2\bar{r})}{1+M/(2\bar{r})}
      63             :    * \f}
      64             :    *
      65             :    * and the shift vanishes (\f$\beta^i=0\f$) as it does in areal Schwarzschild
      66             :    * coordinates. The solution also remains maximally sliced, i.e. \f$K=0\f$.
      67             :    *
      68             :    * The Schwarzschild horizon in these coordinates is at
      69             :    * \f$\bar{r}=\frac{M}{2}\f$ due to the radial transformation from \f$r=2M\f$.
      70             :    */
      71             :   Isotropic,
      72             :   /*!
      73             :    * \brief Painlevé-Gullstrand coordinates
      74             :    *
      75             :    * In these coordinates the spatial metric is flat and the lapse is trivial,
      76             :    * but contrary to (isotropic) Schwarzschild coordinates the shift is
      77             :    * nontrivial,
      78             :    *
      79             :    * \begin{align}
      80             :    *   \gamma_{ij} &= \eta_{ij} \\
      81             :    *   \alpha &= 1 \\
      82             :    *   \beta^i &= \sqrt{\frac{2M}{r}} \frac{x^i}{r} \\
      83             :    *   K &= \frac{3}{2}\sqrt{\frac{2M}{r^3}}
      84             :    * \end{align}
      85             :    *
      86             :    * (Table 2.1 in \cite BaumgarteShapiro).
      87             :    */
      88             :   PainleveGullstrand,
      89             :   /*!
      90             :    * \brief Isotropic Kerr-Schild coordinates
      91             :    *
      92             :    * Kerr-Schild coordinates with a radial transformation such that the spatial
      93             :    * metric is conformally flat.
      94             :    *
      95             :    * The Schwarzschild spacetime in canonical (areal) Kerr-Schild coordinates is
      96             :    *
      97             :    * \begin{align}
      98             :    *   \gamma_{ij} &= \eta_{ij} + \frac{2M}{r}\frac{x^i x^j}{r^2} \\
      99             :    *   \alpha &= \sqrt{1 + \frac{2M}{r}}^{-1} \\
     100             :    *   \beta^i &= \frac{2M\alpha^2}{r} \frac{x^i}{r} \\
     101             :    *   K &= \frac{2M\alpha^3}{r^2} \left(1 + \frac{3M}{r}\right)
     102             :    *   \text{.}
     103             :    * \end{align}
     104             :    *
     105             :    * (Table 2.1 in \cite BaumgarteShapiro). Since the Schwarzschild spacetime is
     106             :    * spherically symmetric we can transform to a radial coordinate $\bar{r}$ in
     107             :    * which it is conformally flat (see, e.g., Sec. 7.4.1 in \cite Pfeiffer2005zm
     108             :    * for details):
     109             :    *
     110             :    * \begin{equation}
     111             :    *   {}^{(3)}\mathrm{d}s^2
     112             :    *     = \left(1 + \frac{2M}{r}\right)\mathrm{d}r^2 + r^2 \mathrm{d}\Omega^2
     113             :    *     = \psi^4 \left(\mathrm{d}\bar{r}^2 +
     114             :    *       \bar{r}^2 \mathrm{d}\Omega^2\right)
     115             :    * \end{equation}
     116             :    *
     117             :    * Therefore, the conformal factor is $\psi^2 = r / \bar{r}$ and
     118             :    *
     119             :    * \begin{equation}
     120             :    *   \frac{\mathrm{d}\bar{r}}{\mathrm{d}r}
     121             :    *     = \frac{\bar{r}}{r} \sqrt{1 + \frac{2M}{r}}
     122             :    *     = \frac{\bar{r}}{r} \frac{1}{\alpha}
     123             :    *   \text{,}
     124             :    * \end{equation}
     125             :    *
     126             :    * which has the solution
     127             :    *
     128             :    * \begin{equation}
     129             :    *   \bar{r} = \frac{r}{4} \left(1 + \sqrt{1 + \frac{2M}{r}}\right)^2
     130             :    *     e^{2 - 2\sqrt{1 + 2M / r}}
     131             :    * \end{equation}
     132             :    *
     133             :    * when we impose $\bar{r} \rightarrow r$ as $r \rightarrow \infty$. We can
     134             :    * invert this transformation law with a numerical root find to obtain the
     135             :    * areal radius $r$ for any isotropic radius $\bar{r}$.
     136             :    *
     137             :    * In the isotropic radial coordinate $\bar{r}$ the solution is then:
     138             :    *
     139             :    * \begin{align}
     140             :    *   \gamma_{ij} &= \psi^4 \eta_{ij} \\
     141             :    *   \psi &= \sqrt{\frac{r}{\bar{r}}}
     142             :    *     = \frac{2e^{\sqrt{1 + 2M / r} - 1}}{1 + \sqrt{1 + 2M / r}} \\
     143             :    *   \alpha &= \sqrt{1 + \frac{2M}{r}}^{-1} \\
     144             :    *   \beta^i
     145             :    *     &= \frac{\mathrm{d}\bar{r}}{\mathrm{d}r} \beta^r \frac{x^i}{\bar{r}}
     146             :    *      = \frac{2M\alpha}{r^2} x^i \\
     147             :    *   K &= \frac{2M\alpha^3}{r^2} \left(1 + \frac{3M}{r}\right)
     148             :    * \end{align}
     149             :    *
     150             :    * Here, $x^i$ are the (isotropic) Cartesian coordinates from which we compute
     151             :    * the isotropic radius $\bar{r}$, $r$ is the areal radius we can obtain from
     152             :    * the isotropic radius by a root find, and $\beta^r$ is the magnitude of the
     153             :    * shift in areal coordinates, as given above.
     154             :    *
     155             :    * The horizon in these coordinates is at (Eq. (7.37) in
     156             :    * \cite Pfeiffer2005zm):
     157             :    *
     158             :    * \begin{equation}
     159             :    * \bar{r}_\mathrm{AH} / M \approx 1.2727410334221052
     160             :    * \end{equation}
     161             :    */
     162             :   KerrSchildIsotropic,
     163             : };
     164             : 
     165           0 : std::ostream& operator<<(std::ostream& os, SchwarzschildCoordinates coords);
     166             : 
     167             : }  // namespace Xcts::Solutions
     168             : 
     169             : template <>
     170           0 : struct Options::create_from_yaml<Xcts::Solutions::SchwarzschildCoordinates> {
     171             :   template <typename Metavariables>
     172           0 :   static Xcts::Solutions::SchwarzschildCoordinates create(
     173             :       const Options::Option& options) {
     174             :     return create<void>(options);
     175             :   }
     176             : };
     177             : 
     178             : template <>
     179           0 : Xcts::Solutions::SchwarzschildCoordinates
     180             : Options::create_from_yaml<Xcts::Solutions::SchwarzschildCoordinates>::create<
     181             :     void>(const Options::Option& options);
     182             : 
     183             : namespace Xcts::Solutions {
     184             : 
     185             : namespace detail {
     186             : 
     187             : struct SchwarzschildImpl {
     188             :   struct Mass {
     189             :     using type = double;
     190             :     static constexpr Options::String help = "Mass parameter M";
     191             :   };
     192             : 
     193             :   struct CoordinateSystem {
     194             :     static std::string name() { return "Coordinates"; }
     195             :     using type = SchwarzschildCoordinates;
     196             :     static constexpr Options::String help =
     197             :         "The coordinate system used to describe the solution";
     198             :   };
     199             : 
     200             :   using options = tmpl::list<Mass, CoordinateSystem>;
     201             :   static constexpr Options::String help{
     202             :       "Schwarzschild spacetime in general relativity"};
     203             : 
     204             :   SchwarzschildImpl() = default;
     205             :   SchwarzschildImpl(const SchwarzschildImpl&) = default;
     206             :   SchwarzschildImpl& operator=(const SchwarzschildImpl&) = default;
     207             :   SchwarzschildImpl(SchwarzschildImpl&&) = default;
     208             :   SchwarzschildImpl& operator=(SchwarzschildImpl&&) = default;
     209             :   ~SchwarzschildImpl() = default;
     210             : 
     211             :   explicit SchwarzschildImpl(double mass,
     212             :                              SchwarzschildCoordinates coordinate_system);
     213             : 
     214             :   /// The mass parameter \f$M\f$.
     215             :   double mass() const;
     216             : 
     217             :   SchwarzschildCoordinates coordinate_system() const;
     218             : 
     219             :   /// The radius of the Schwarzschild horizon in the given coordinates.
     220             :   double radius_at_horizon() const;
     221             : 
     222             :   // NOLINTNEXTLINE(google-runtime-references)
     223             :   void pup(PUP::er& p);
     224             : 
     225             :  protected:
     226             :   double mass_{std::numeric_limits<double>::signaling_NaN()};
     227             :   SchwarzschildCoordinates coordinate_system_{};
     228             : };
     229             : 
     230             : bool operator==(const SchwarzschildImpl& lhs, const SchwarzschildImpl& rhs);
     231             : 
     232             : bool operator!=(const SchwarzschildImpl& lhs, const SchwarzschildImpl& rhs);
     233             : 
     234             : namespace Tags {
     235             : template <typename DataType>
     236             : struct Radius : db::SimpleTag {
     237             :   using type = Scalar<DataType>;
     238             : };
     239             : template <typename DataType>
     240             : struct ArealRadius : db::SimpleTag {
     241             :   using type = Scalar<DataType>;
     242             : };
     243             : }  // namespace Tags
     244             : 
     245             : template <typename DataType>
     246             : using SchwarzschildVariablesCache =
     247             :     cached_temp_buffer_from_typelist<tmpl::push_front<
     248             :         common_tags<DataType>, detail::Tags::Radius<DataType>,
     249             :         detail::Tags::ArealRadius<DataType>,
     250             :         ::Tags::deriv<gr::Tags::Lapse<DataType>, tmpl::size_t<3>,
     251             :                       Frame::Inertial>,
     252             :         gr::Tags::Conformal<gr::Tags::EnergyDensity<DataType>, 0>,
     253             :         gr::Tags::Conformal<gr::Tags::StressTrace<DataType>, 0>,
     254             :         gr::Tags::Conformal<gr::Tags::MomentumDensity<DataType, 3>, 0>>>;
     255             : 
     256             : template <typename DataType>
     257             : struct SchwarzschildVariables
     258             :     : CommonVariables<DataType, SchwarzschildVariablesCache<DataType>> {
     259             :   static constexpr size_t Dim = 3;
     260             :   static constexpr int ConformalMatterScale = 0;
     261             :   using Cache = SchwarzschildVariablesCache<DataType>;
     262             :   using Base = CommonVariables<DataType, SchwarzschildVariablesCache<DataType>>;
     263             :   using Base::operator();
     264             : 
     265             :   SchwarzschildVariables(
     266             :       std::optional<std::reference_wrapper<const Mesh<Dim>>> local_mesh,
     267             :       std::optional<std::reference_wrapper<const InverseJacobian<
     268             :           DataType, Dim, Frame::ElementLogical, Frame::Inertial>>>
     269             :           local_inv_jacobian,
     270             :       const tnsr::I<DataType, 3>& local_x, const double local_mass,
     271             :       const SchwarzschildCoordinates local_coordinate_system)
     272             :       : Base(std::move(local_mesh), std::move(local_inv_jacobian)),
     273             :         x(local_x),
     274             :         mass(local_mass),
     275             :         coordinate_system(local_coordinate_system) {}
     276             : 
     277             :   const tnsr::I<DataType, 3>& x;
     278             :   double mass;
     279             :   SchwarzschildCoordinates coordinate_system;
     280             : 
     281             :   void operator()(gsl::not_null<Scalar<DataType>*> radius,
     282             :                   gsl::not_null<Cache*> cache,
     283             :                   detail::Tags::Radius<DataType> /*meta*/) const;
     284             :   void operator()(gsl::not_null<Scalar<DataType>*> areal_radius,
     285             :                   gsl::not_null<Cache*> cache,
     286             :                   detail::Tags::ArealRadius<DataType> /*meta*/) const;
     287             :   void operator()(
     288             :       gsl::not_null<tnsr::ii<DataType, 3>*> conformal_metric,
     289             :       gsl::not_null<Cache*> cache,
     290             :       Xcts::Tags::ConformalMetric<DataType, 3, Frame::Inertial> /*meta*/)
     291             :       const override;
     292             :   void operator()(
     293             :       gsl::not_null<tnsr::II<DataType, 3>*> inv_conformal_metric,
     294             :       gsl::not_null<Cache*> cache,
     295             :       Xcts::Tags::InverseConformalMetric<DataType, 3, Frame::Inertial> /*meta*/)
     296             :       const override;
     297             :   void operator()(
     298             :       gsl::not_null<tnsr::ijj<DataType, 3>*> deriv_conformal_metric,
     299             :       gsl::not_null<Cache*> cache,
     300             :       ::Tags::deriv<Xcts::Tags::ConformalMetric<DataType, 3, Frame::Inertial>,
     301             :                     tmpl::size_t<3>, Frame::Inertial> /*meta*/) const override;
     302             :   void operator()(
     303             :       gsl::not_null<Scalar<DataType>*> trace_extrinsic_curvature,
     304             :       gsl::not_null<Cache*> cache,
     305             :       gr::Tags::TraceExtrinsicCurvature<DataType> /*meta*/) const override;
     306             :   void operator()(
     307             :       gsl::not_null<tnsr::i<DataType, 3>*> trace_extrinsic_curvature_gradient,
     308             :       gsl::not_null<Cache*> cache,
     309             :       ::Tags::deriv<gr::Tags::TraceExtrinsicCurvature<DataType>,
     310             :                     tmpl::size_t<3>, Frame::Inertial> /*meta*/) const override;
     311             :   void operator()(
     312             :       gsl::not_null<Scalar<DataType>*> dt_trace_extrinsic_curvature,
     313             :       gsl::not_null<Cache*> cache,
     314             :       ::Tags::dt<gr::Tags::TraceExtrinsicCurvature<DataType>> /*meta*/)
     315             :       const override;
     316             :   void operator()(
     317             :       gsl::not_null<Scalar<DataType>*> conformal_factor_minus_one,
     318             :       gsl::not_null<Cache*> cache,
     319             :       Xcts::Tags::ConformalFactorMinusOne<DataType> /*meta*/) const override;
     320             :   void operator()(
     321             :       gsl::not_null<Scalar<DataType>*> conformal_factor,
     322             :       gsl::not_null<Cache*> cache,
     323             :       Xcts::Tags::ConformalFactor<DataType> /*meta*/) const override;
     324             :   void operator()(
     325             :       gsl::not_null<tnsr::i<DataType, 3>*> conformal_factor_gradient,
     326             :       gsl::not_null<Cache*> cache,
     327             :       ::Tags::deriv<Xcts::Tags::ConformalFactorMinusOne<DataType>,
     328             :                     tmpl::size_t<3>, Frame::Inertial> /*meta*/) const override;
     329             :   void operator()(gsl::not_null<Scalar<DataType>*> lapse,
     330             :                   gsl::not_null<Cache*> cache,
     331             :                   gr::Tags::Lapse<DataType> /*meta*/) const override;
     332             :   void operator()(gsl::not_null<tnsr::i<DataType, 3>*> deriv_lapse,
     333             :                   gsl::not_null<Cache*> cache,
     334             :                   ::Tags::deriv<gr::Tags::Lapse<DataType>, tmpl::size_t<3>,
     335             :                                 Frame::Inertial> /*meta*/) const;
     336             :   void operator()(
     337             :       gsl::not_null<Scalar<DataType>*> lapse_times_conformal_factor_minus_one,
     338             :       gsl::not_null<Cache*> cache,
     339             :       Xcts::Tags::LapseTimesConformalFactorMinusOne<DataType> /*meta*/)
     340             :       const override;
     341             :   void operator()(
     342             :       gsl::not_null<Scalar<DataType>*> lapse_times_conformal_factor,
     343             :       gsl::not_null<Cache*> cache,
     344             :       Xcts::Tags::LapseTimesConformalFactor<DataType> /*meta*/) const override;
     345             :   void operator()(
     346             :       gsl::not_null<tnsr::i<DataType, 3>*>
     347             :           lapse_times_conformal_factor_gradient,
     348             :       gsl::not_null<Cache*> cache,
     349             :       ::Tags::deriv<Xcts::Tags::LapseTimesConformalFactorMinusOne<DataType>,
     350             :                     tmpl::size_t<3>, Frame::Inertial> /*meta*/) const override;
     351             :   void operator()(
     352             :       gsl::not_null<tnsr::I<DataType, 3>*> shift_background,
     353             :       gsl::not_null<Cache*> cache,
     354             :       Xcts::Tags::ShiftBackground<DataType, 3, Frame::Inertial> /*meta*/)
     355             :       const override;
     356             :   void operator()(gsl::not_null<tnsr::II<DataType, 3, Frame::Inertial>*>
     357             :                       longitudinal_shift_background_minus_dt_conformal_metric,
     358             :                   gsl::not_null<Cache*> cache,
     359             :                   Xcts::Tags::LongitudinalShiftBackgroundMinusDtConformalMetric<
     360             :                       DataType, 3, Frame::Inertial> /*meta*/) const override;
     361             :   void operator()(
     362             :       gsl::not_null<tnsr::I<DataType, 3>*> shift_excess,
     363             :       gsl::not_null<Cache*> cache,
     364             :       Xcts::Tags::ShiftExcess<DataType, 3, Frame::Inertial> /*meta*/)
     365             :       const override;
     366             :   void operator()(
     367             :       gsl::not_null<tnsr::iJ<DataType, 3>*> deriv_shift_excess,
     368             :       gsl::not_null<Cache*> cache,
     369             :       ::Tags::deriv<Xcts::Tags::ShiftExcess<DataType, 3, Frame::Inertial>,
     370             :                     tmpl::size_t<3>, Frame::Inertial> /*meta*/) const override;
     371             :   void operator()(
     372             :       gsl::not_null<tnsr::ii<DataType, 3>*> extrinsic_curvature,
     373             :       gsl::not_null<Cache*> cache,
     374             :       gr::Tags::ExtrinsicCurvature<DataType, 3> /*meta*/) const override;
     375             :   void operator()(gsl::not_null<Scalar<DataType>*> energy_density,
     376             :                   gsl::not_null<Cache*> cache,
     377             :                   gr::Tags::Conformal<gr::Tags::EnergyDensity<DataType>,
     378             :                                       ConformalMatterScale> /*meta*/) const;
     379             :   void operator()(gsl::not_null<Scalar<DataType>*> stress_trace,
     380             :                   gsl::not_null<Cache*> cache,
     381             :                   gr::Tags::Conformal<gr::Tags::StressTrace<DataType>,
     382             :                                       ConformalMatterScale> /*meta*/) const;
     383             :   void operator()(gsl::not_null<tnsr::I<DataType, 3>*> momentum_density,
     384             :                   gsl::not_null<Cache*> cache,
     385             :                   gr::Tags::Conformal<gr::Tags::MomentumDensity<DataType, 3>,
     386             :                                       ConformalMatterScale> /*meta*/) const;
     387             : };
     388             : 
     389             : }  // namespace detail
     390             : 
     391             : /*!
     392             :  * \brief Schwarzschild spacetime in general relativity
     393             :  *
     394             :  * This class implements the Schwarzschild solution with mass parameter
     395             :  * \f$M\f$ in various coordinate systems. See the entries of the
     396             :  * `Xcts::Solutions::SchwarzschildCoordinates` enum for the available coordinate
     397             :  * systems and for the solution variables in the respective coordinates.
     398             :  */
     399           1 : class Schwarzschild : public elliptic::analytic_data::AnalyticSolution,
     400             :                       public detail::SchwarzschildImpl {
     401             :  public:
     402           0 :   Schwarzschild() = default;
     403           0 :   Schwarzschild(const Schwarzschild&) = default;
     404           0 :   Schwarzschild& operator=(const Schwarzschild&) = default;
     405           0 :   Schwarzschild(Schwarzschild&&) = default;
     406           0 :   Schwarzschild& operator=(Schwarzschild&&) = default;
     407           0 :   ~Schwarzschild() = default;
     408             : 
     409             :   using SchwarzschildImpl::SchwarzschildImpl;
     410             : 
     411             :   /// \cond
     412             :   explicit Schwarzschild(CkMigrateMessage* m)
     413             :       : elliptic::analytic_data::AnalyticSolution(m) {}
     414             :   using PUP::able::register_constructor;
     415             :   WRAPPED_PUPable_decl_template(Schwarzschild);
     416             :   std::unique_ptr<elliptic::analytic_data::AnalyticSolution> get_clone()
     417             :       const override {
     418             :     return std::make_unique<Schwarzschild>(*this);
     419             :   }
     420             :   /// \endcond
     421             : 
     422             :   template <typename DataType, typename... RequestedTags>
     423           0 :   tuples::TaggedTuple<RequestedTags...> variables(
     424             :       const tnsr::I<DataType, 3, Frame::Inertial>& x,
     425             :       tmpl::list<RequestedTags...> /*meta*/) const {
     426             :     return variables_impl<DataType>(x, std::nullopt, std::nullopt,
     427             :                                     tmpl::list<RequestedTags...>{});
     428             :   }
     429             : 
     430             :   template <typename... RequestedTags>
     431           0 :   tuples::TaggedTuple<RequestedTags...> variables(
     432             :       const tnsr::I<DataVector, 3, Frame::Inertial>& x, const Mesh<3>& mesh,
     433             :       const InverseJacobian<DataVector, 3, Frame::ElementLogical,
     434             :                             Frame::Inertial>& inv_jacobian,
     435             :       tmpl::list<RequestedTags...> /*meta*/) const {
     436             :     return variables_impl<DataVector>(x, mesh, inv_jacobian,
     437             :                                       tmpl::list<RequestedTags...>{});
     438             :   }
     439             : 
     440           0 :   void pup(PUP::er& p) override {
     441             :     elliptic::analytic_data::AnalyticSolution::pup(p);
     442             :     detail::SchwarzschildImpl::pup(p);
     443             :   }
     444             : 
     445             :  private:
     446             :   template <typename DataType, typename... RequestedTags>
     447           0 :   tuples::TaggedTuple<RequestedTags...> variables_impl(
     448             :       const tnsr::I<DataType, 3, Frame::Inertial>& x,
     449             :       std::optional<std::reference_wrapper<const Mesh<3>>> mesh,
     450             :       std::optional<std::reference_wrapper<const InverseJacobian<
     451             :           DataType, 3, Frame::ElementLogical, Frame::Inertial>>>
     452             :           inv_jacobian,
     453             :       tmpl::list<RequestedTags...> /*meta*/) const {
     454             :     using VarsComputer = detail::SchwarzschildVariables<DataType>;
     455             :     typename VarsComputer::Cache cache{get_size(*x.begin())};
     456             :     const VarsComputer computer{std::move(mesh), std::move(inv_jacobian), x,
     457             :                                 mass_, coordinate_system_};
     458             :     const auto get_var = [&cache, &computer, &x](auto tag_v) {
     459             :       using tag = std::decay_t<decltype(tag_v)>;
     460             :       if constexpr (tmpl::list_contains_v<hydro_tags<DataType>, tag>) {
     461             :         (void)cache;
     462             :         (void)computer;
     463             :         return get<tag>(Flatness{}.variables(x, tmpl::list<tag>{}));
     464             :       } else {
     465             :         (void)x;
     466             :         return cache.get_var(computer, tag{});
     467             :       }
     468             :     };
     469             :     return {get_var(RequestedTags{})...};
     470             :   }
     471             : };
     472             : 
     473             : }  // namespace Xcts::Solutions

Generated by: LCOV version 1.14