SpECTRE Documentation Coverage Report
Current view: top level - Evolution/Systems/Cce/AnalyticSolutions - WorldtubeData.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 7.3 % 41 3
Test Date: 2026-10-22 17:29:42
Legend: Lines:     hit not hit

            Line data    Source code
       1            0 : // Distributed under the MIT License.
       2              : // See LICENSE.txt for details.
       3              : 
       4              : #pragma once
       5              : 
       6              : #include <cstddef>
       7              : 
       8              : #include "DataStructures/DataBox/DataBox.hpp"
       9              : #include "DataStructures/DataVector.hpp"
      10              : #include "DataStructures/TaggedTuple.hpp"
      11              : #include "DataStructures/Tensor/Tensor.hpp"
      12              : #include "Evolution/Systems/Cce/Initialize/InitializeJ.hpp"
      13              : #include "Evolution/Systems/Cce/Initialize/InverseCubic.hpp"
      14              : #include "Evolution/Systems/Cce/Tags.hpp"
      15              : #include "Evolution/Systems/GeneralizedHarmonic/Tags.hpp"
      16              : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp"
      17              : #include "NumericalAlgorithms/SpinWeightedSphericalHarmonics/SwshCollocation.hpp"
      18              : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
      19              : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
      20              : #include "Utilities/Gsl.hpp"
      21              : #include "Utilities/Serialization/CharmPupable.hpp"
      22              : #include "Utilities/SetNumberOfGridPoints.hpp"
      23              : #include "Utilities/TMPL.hpp"
      24              : 
      25              : namespace Cce {
      26              : /// Analytic solutions for CCE worldtube data and corresponding waveform News
      27              : namespace Solutions {
      28              : 
      29              : /// \cond
      30              : class BouncingBlackHole;
      31              : class GaugeWave;
      32              : class LinearizedBondiSachs;
      33              : class RobinsonTrautman;
      34              : class RotatingSchwarzschild;
      35              : class TeukolskyWave;
      36              : /// \endcond
      37              : 
      38              : /*!
      39              :  * \brief Abstract base class for analytic worldtube data for verifying the CCE
      40              :  * system.
      41              :  *
      42              :  * \details All of the boundary data quantities are provided by the
      43              :  * `WorldtubeData::variables()` function.
      44              :  *
      45              :  * This class provides caching and conversion between different
      46              :  * representations of the metric data needed for the worldtube computation and
      47              :  * evolution. The set of pure virtual functions (required to be overriden in the
      48              :  * derived classes) is:
      49              :  * - `WorldtubeData::get_clone()`: should return a
      50              :  * `std::unique_ptr<WorldtubeData>` with cloned state
      51              :  * - `WorldtubeData::variables_impl()` (a `protected` function): should compute
      52              :  * and return by `not_null` pointer the spacetime metric quantity requested in
      53              :  * the final (metavariable) tag argument. The function overloads that are
      54              :  * required to be overriden in the derived class are
      55              :  * `gr::Tags::SpacetimeMetric<DataVector, 3>`,
      56              :  * `::Tags::dt<gr::Tags::SpacetimeMetric<DataVector, 3>>`,
      57              :  * `gh::Tags::Phi<DataVector, 3>`, and
      58              :  * `Cce::Tags::News`.
      59              :  * - `prepare_solution()`: Any initial precomputation needed to determine all of
      60              :  * the solutions efficiently. This function is called by the base class prior to
      61              :  * computing or retrieving from the internal cache the requested quantities.
      62              :  *
      63              :  * \warning This class is not intended to be threadsafe! Therefore, using
      64              :  * instances of this class placed into the const global cache results in
      65              :  * undefined behavior. The analytic data for CCE is not easily represented as a
      66              :  * full closed-form solution for the entire Bondi-Sachs-like metric over the
      67              :  * domain, so this class and its descendants perform numerical calculations such
      68              :  * as spin-weighted derivatives over the sphere. Instead, it makes best sense to
      69              :  * compute the global solution over the extraction sphere, and cache
      70              :  * intermediate steps to avoid repeating potentially expensive tensor
      71              :  * calculations.
      72              :  */
      73            1 : struct WorldtubeData : public PUP::able {
      74            0 :   using creatable_classes =
      75              :       tmpl::list<BouncingBlackHole, GaugeWave, LinearizedBondiSachs,
      76              :                  RobinsonTrautman, RotatingSchwarzschild, TeukolskyWave>;
      77              : 
      78              :   /// The set of available tags provided by the analytic solution
      79            1 :   using tags = tmpl::list<
      80              :       Tags::CauchyCartesianCoords, Tags::Dr<Tags::CauchyCartesianCoords>,
      81              :       gr::Tags::SpacetimeMetric<DataVector, 3>,
      82              :       ::Tags::dt<gr::Tags::SpacetimeMetric<DataVector, 3>>,
      83              :       gh::Tags::Pi<DataVector, 3>, gh::Tags::Phi<DataVector, 3>,
      84              :       gr::Tags::SpatialMetric<DataVector, 3>,
      85              :       ::Tags::dt<gr::Tags::SpatialMetric<DataVector, 3>>,
      86              :       Tags::Dr<gr::Tags::SpatialMetric<DataVector, 3>>,
      87              :       gr::Tags::Shift<DataVector, 3>,
      88              :       ::Tags::dt<gr::Tags::Shift<DataVector, 3>>,
      89              :       Tags::Dr<gr::Tags::Shift<DataVector, 3>>, gr::Tags::Lapse<DataVector>,
      90              :       ::Tags::dt<gr::Tags::Lapse<DataVector>>,
      91              :       Tags::Dr<gr::Tags::Lapse<DataVector>>, Tags::News>;
      92              : 
      93            0 :   WRAPPED_PUPable_abstract(WorldtubeData);  // NOLINT
      94              : 
      95              :   // clang doesn't manage to use = default correctly in this case
      96              :   // NOLINTNEXTLINE(modernize-use-equals-default)
      97            0 :   WorldtubeData() {}
      98              : 
      99            0 :   explicit WorldtubeData(const double extraction_radius)
     100              :       : extraction_radius_{extraction_radius} {}
     101              : 
     102            0 :   explicit WorldtubeData(CkMigrateMessage* msg) : PUP::able(msg) {}
     103              : 
     104            0 :   ~WorldtubeData() override = default;
     105              : 
     106            0 :   virtual std::unique_ptr<WorldtubeData> get_clone() const = 0;
     107              : 
     108              :   /*!
     109              :    * \brief Retrieve worldtube data represented by the analytic solution, at
     110              :    * boundary angular resolution `l_max` and time `time`
     111              :    *
     112              :    * \details The set of requested tags are specified by the final argument,
     113              :    * which must be a `tmpl::list` of tags to be retrieved. The set of available
     114              :    * tags is found in `WorldtubeData::tags`, and includes coordinate and
     115              :    * Jacobian quantities as well as metric quantities and derivatives thereof.
     116              :    */
     117              :   template <typename... Tags>
     118            1 :   tuples::TaggedTuple<Tags...> variables(
     119              :       // NOLINTNEXTLINE(readability-avoid-const-params-in-decls)
     120              :       const size_t output_l_max, const double time,
     121              :       tmpl::list<Tags...> /*meta*/) const {
     122              :     prepare_solution(output_l_max, time);
     123              :     return {cache_or_compute<Tags>(output_l_max, time)...};
     124              :   }
     125              : 
     126            0 :   void pup(PUP::er& p) override;
     127              : 
     128              :   virtual std::unique_ptr<Cce::InitializeJ::InitializeJ<false>>
     129            0 :   get_initialize_j(const double /*start_time*/) const {
     130              :     return std::make_unique<Cce::InitializeJ::InverseCubic<false>>();
     131              :   };
     132              : 
     133            0 :   virtual bool use_noninertial_news() const { return false; }
     134              : 
     135              :  protected:
     136              :   template <typename Tag>
     137            0 :   const auto& cache_or_compute(const size_t output_l_max,
     138              :                                const double time) const {
     139              :     auto& item_cache = get<IntermediateCacheTag<Tag>>(intermediate_cache_);
     140              :     if (item_cache.l_max == output_l_max and item_cache.time == time) {
     141              :       return item_cache.data;
     142              :     }
     143              :     auto& item = item_cache.data;
     144              :     set_number_of_grid_points(
     145              :         make_not_null(&item),
     146              :         Spectral::Swsh::number_of_swsh_collocation_points(output_l_max));
     147              :     variables_impl(make_not_null(&item), output_l_max, time,
     148              :                    tmpl::type_<Tag>{});
     149              :     item_cache.l_max = output_l_max;
     150              :     item_cache.time = time;
     151              :     return item;
     152              :   }
     153            0 :   virtual void prepare_solution(size_t output_l_max, double time) const = 0;
     154              : 
     155              :   // note that function template cannot be virtual, so we have to emulate
     156              :   // template specializations through function overloads
     157            0 :   virtual void variables_impl(
     158              :       gsl::not_null<tnsr::i<DataVector, 3>*> cartesian_coordinates,
     159              :       size_t output_l_max, double time,
     160              :       tmpl::type_<Tags::CauchyCartesianCoords> /*meta*/) const;
     161              : 
     162            0 :   virtual void variables_impl(
     163              :       gsl::not_null<tnsr::i<DataVector, 3>*> dr_cartesian_coordinates,
     164              :       size_t output_l_max, double time,
     165              :       tmpl::type_<Tags::Dr<Tags::CauchyCartesianCoords>> /*meta*/) const;
     166              : 
     167            0 :   virtual void variables_impl(
     168              :       gsl::not_null<tnsr::aa<DataVector, 3>*> spacetime_metric,
     169              :       size_t output_l_max, double time,
     170              :       tmpl::type_<gr::Tags::SpacetimeMetric<DataVector, 3>>
     171              :       /*meta*/) const = 0;
     172              : 
     173            0 :   virtual void variables_impl(
     174              :       gsl::not_null<tnsr::aa<DataVector, 3>*> dt_spacetime_metric,
     175              :       size_t output_l_max, double time,
     176              :       tmpl::type_<::Tags::dt<gr::Tags::SpacetimeMetric<DataVector, 3>>>
     177              :       /*meta*/) const = 0;
     178              : 
     179            0 :   virtual void variables_impl(gsl::not_null<tnsr::aa<DataVector, 3>*> pi,
     180              :                               size_t output_l_max, double time,
     181              :                               tmpl::type_<gh::Tags::Pi<DataVector, 3>>
     182              :                               /*meta*/) const;
     183              : 
     184            0 :   virtual void variables_impl(
     185              :       gsl::not_null<tnsr::iaa<DataVector, 3>*> d_spacetime_metric,
     186              :       size_t output_l_max, double time,
     187              :       tmpl::type_<gh::Tags::Phi<DataVector, 3>>
     188              :       /*meta*/) const = 0;
     189              : 
     190            0 :   virtual void variables_impl(
     191              :       gsl::not_null<tnsr::ii<DataVector, 3>*> spatial_metric,
     192              :       size_t output_l_max, double time,
     193              :       tmpl::type_<gr::Tags::SpatialMetric<DataVector, 3>>
     194              :       /*meta*/) const;
     195              : 
     196            0 :   virtual void variables_impl(
     197              :       gsl::not_null<tnsr::ii<DataVector, 3>*> dt_spatial_metric,
     198              :       size_t output_l_max, double time,
     199              :       tmpl::type_<::Tags::dt<gr::Tags::SpatialMetric<DataVector, 3>>>
     200              :       /*meta*/) const;
     201              : 
     202            0 :   virtual void variables_impl(
     203              :       gsl::not_null<tnsr::ii<DataVector, 3>*> dr_spatial_metric,
     204              :       size_t output_l_max, double time,
     205              :       tmpl::type_<Tags::Dr<gr::Tags::SpatialMetric<DataVector, 3>>>
     206              :       /*meta*/) const;
     207              : 
     208            0 :   virtual void variables_impl(gsl::not_null<tnsr::I<DataVector, 3>*> shift,
     209              :                               size_t output_l_max, double time,
     210              :                               tmpl::type_<gr::Tags::Shift<DataVector, 3>>
     211              :                               /*meta*/) const;
     212              : 
     213            0 :   virtual void variables_impl(
     214              :       gsl::not_null<tnsr::I<DataVector, 3>*> dt_shift, size_t output_l_max,
     215              :       double time, tmpl::type_<::Tags::dt<gr::Tags::Shift<DataVector, 3>>>
     216              :       /*meta*/) const;
     217              : 
     218            0 :   virtual void variables_impl(
     219              :       gsl::not_null<tnsr::I<DataVector, 3>*> dr_shift, size_t output_l_max,
     220              :       double time, tmpl::type_<Tags::Dr<gr::Tags::Shift<DataVector, 3>>>
     221              :       /*meta*/) const;
     222              : 
     223            0 :   virtual void variables_impl(gsl::not_null<Scalar<DataVector>*> lapse,
     224              :                               size_t output_l_max, double time,
     225              :                               tmpl::type_<gr::Tags::Lapse<DataVector>>
     226              :                               /*meta*/) const;
     227              : 
     228            0 :   virtual void variables_impl(
     229              :       gsl::not_null<Scalar<DataVector>*> dt_lapse, size_t output_l_max,
     230              :       double time, tmpl::type_<::Tags::dt<gr::Tags::Lapse<DataVector>>>
     231              :       /*meta*/) const;
     232              : 
     233            0 :   virtual void variables_impl(gsl::not_null<Scalar<DataVector>*> dr_lapse,
     234              :                               size_t output_l_max, double time,
     235              :                               tmpl::type_<Tags::Dr<gr::Tags::Lapse<DataVector>>>
     236              :                               /*meta*/) const;
     237              : 
     238            0 :   virtual void variables_impl(
     239              :       gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -2>>*> news,
     240              :       size_t output_l_max, double time,
     241              :       tmpl::type_<Tags::News> /*meta*/) const = 0;
     242              : 
     243              :   template <typename Tag>
     244            0 :   struct IntermediateCache {
     245            0 :     typename Tag::type data;
     246            0 :     size_t l_max = 0;
     247            0 :     double time = -std::numeric_limits<double>::infinity();
     248              :   };
     249              : 
     250              :   template <typename Tag>
     251            0 :   struct IntermediateCacheTag {
     252            0 :     using type = IntermediateCache<Tag>;
     253              :   };
     254              : 
     255            0 :   using IntermediateCacheTuple =
     256              :       tuples::tagged_tuple_from_typelist<tmpl::transform<
     257              :           tmpl::list<Tags::CauchyCartesianCoords,
     258              :                      Tags::Dr<Tags::CauchyCartesianCoords>,
     259              :                      gr::Tags::SpacetimeMetric<DataVector, 3>,
     260              :                      gh::Tags::Pi<DataVector, 3>, gh::Tags::Phi<DataVector, 3>,
     261              :                      gr::Tags::SpatialMetric<DataVector, 3>,
     262              :                      gr::Tags::Shift<DataVector, 3>,
     263              :                      gr::Tags::Lapse<DataVector>,
     264              :                      ::Tags::dt<gr::Tags::SpacetimeMetric<DataVector, 3>>,
     265              :                      ::Tags::dt<gr::Tags::SpatialMetric<DataVector, 3>>,
     266              :                      ::Tags::dt<gr::Tags::Shift<DataVector, 3>>,
     267              :                      ::Tags::dt<gr::Tags::Lapse<DataVector>>,
     268              :                      Tags::Dr<gr::Tags::SpatialMetric<DataVector, 3>>,
     269              :                      Tags::Dr<gr::Tags::Shift<DataVector, 3>>,
     270              :                      Tags::Dr<gr::Tags::Lapse<DataVector>>, Tags::News>,
     271              :           tmpl::bind<IntermediateCacheTag, tmpl::_1>>>;
     272              : 
     273              :   // NOLINTNEXTLINE(spectre-mutable)
     274            0 :   mutable IntermediateCacheTuple intermediate_cache_;
     275            0 :   double extraction_radius_ = std::numeric_limits<double>::quiet_NaN();
     276              : };
     277              : }  // namespace Solutions
     278              : }  // namespace Cce
        

Generated by: LCOV version 2.0-1