SpECTRE Documentation Coverage Report
Current view: top level - Evolution/Systems/Cce - WorldtubeDataManager.hpp Hit Total Coverage
Commit: c3e43f8d41800b0ecefb9d1393f1de1d5a280c8f Lines: 15 65 23.1 %
Date: 2026-07-24 22:09:25
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 <algorithm>
       7             : #include <cstddef>
       8             : #include <memory>
       9             : #include <utility>
      10             : 
      11             : #include "DataStructures/ComplexModalVector.hpp"
      12             : #include "DataStructures/DataBox/Tag.hpp"
      13             : #include "Evolution/Systems/Cce/BoundaryData.hpp"
      14             : #include "Evolution/Systems/Cce/Tags.hpp"
      15             : #include "Evolution/Systems/Cce/WorldtubeBufferUpdater.hpp"
      16             : #include "NumericalAlgorithms/Interpolation/SpanInterpolator.hpp"
      17             : #include "Parallel/NodeLock.hpp"
      18             : #include "Utilities/Gsl.hpp"
      19             : #include "Utilities/Serialization/CharmPupable.hpp"
      20             : #include "Utilities/TMPL.hpp"
      21             : 
      22             : namespace Cce {
      23             : 
      24             : namespace detail {
      25             : 
      26             : template <typename InputTags>
      27             : void set_non_pupped_members(
      28             :     gsl::not_null<size_t*> time_span_start,
      29             :     gsl::not_null<size_t*> time_span_end,
      30             :     gsl::not_null<Variables<InputTags>*> coefficients_buffers,
      31             :     gsl::not_null<Variables<InputTags>*> interpolated_coefficients,
      32             :     size_t buffer_depth, size_t interpolator_length, size_t l_max);
      33             : 
      34             : template <typename InputTags>
      35             : void initialize_buffers(
      36             :     gsl::not_null<size_t*> buffer_depth,
      37             :     gsl::not_null<Variables<InputTags>*> coefficients_buffers,
      38             :     size_t buffer_size, size_t interpolator_length, size_t l_max);
      39             : 
      40             : template <typename InputTags, typename OutputTags>
      41             : void populate_hypersurface_boundary_data(
      42             :     gsl::not_null<Variables<OutputTags>*> boundary_data_variables,
      43             :     gsl::not_null<Variables<InputTags>*> interpolated_coefficients,
      44             :     gsl::not_null<Variables<InputTags>*> coefficients_buffers,
      45             :     gsl::not_null<size_t*> time_span_start,
      46             :     gsl::not_null<size_t*> time_span_end,
      47             :     gsl::not_null<Parallel::NodeLock*> hdf5_lock, double time,
      48             :     const std::unique_ptr<intrp::SpanInterpolator>& interpolator,
      49             :     const std::unique_ptr<WorldtubeBufferUpdater<InputTags>>& buffer_updater,
      50             :     size_t l_max, size_t buffer_depth);
      51             : }  // namespace detail
      52             : 
      53             : /// \cond
      54             : class MetricWorldtubeDataManager;
      55             : class BondiWorldtubeDataManager;
      56             : class KleinGordonWorldtubeDataManager;
      57             : /// \endcond
      58             : 
      59             : /*!
      60             :  *  \brief Abstract base class for managers of CCE worldtube data that is
      61             :  * provided in large time-series chunks, especially the type provided by input
      62             :  * h5 files. `BoundaryTags` is a `tmpl::list` of tags on the worldtube boundary.
      63             :  *
      64             :  *  \details The methods that are required to be overridden in the derived
      65             :  * classes are:
      66             :  *
      67             :  * - `WorldtubeDataManager::populate_hypersurface_boundary_data()`:
      68             :  *   updates the Variables passed by pointer to contain correct boundary data
      69             :  *   for the time value passed in. This function should update all of the tags
      70             :  *   in `Tags::characteristic_worldtube_boundary_tags<Tags::BoundaryValue>`.
      71             :  * - `WorldtubeDataManager::get_clone()`: clone function to obtain a
      72             :  *   `std::unique_ptr` of the base `WorldtubeDataManager`, needed to pass around
      73             :  *   the factory-created object.
      74             :  * - `WorldtubeDataManager::get_l_max()`: The override should return the
      75             :  *   `l_max` that it computes for the collocation data calculated during
      76             :  *   `WorldtubeDataManager::populate_hypersurface_boundary_data()`.
      77             :  * - `WorldtubeBufferUpdater::get_time_span()`: The override should return the
      78             :  *   `std::pair` of indices that represent the start and end point of the
      79             :  *   underlying data source. This is primarily used for monitoring the frequency
      80             :  *   and size of the buffer updates.
      81             :  */
      82             : template <typename BoundaryTags>
      83           1 : class WorldtubeDataManager : public PUP::able {
      84             :  public:
      85           0 :   using creatable_classes =
      86             :       tmpl::list<MetricWorldtubeDataManager, BondiWorldtubeDataManager,
      87             :                  KleinGordonWorldtubeDataManager>;
      88             : 
      89           0 :   WRAPPED_PUPable_abstract(WorldtubeDataManager);  // NOLINT
      90             : 
      91           0 :   virtual bool populate_hypersurface_boundary_data(
      92             :       gsl::not_null<Variables<BoundaryTags>*> boundary_data_variables,
      93             :       double time, gsl::not_null<Parallel::NodeLock*> hdf5_lock) const = 0;
      94             : 
      95           0 :   virtual std::unique_ptr<WorldtubeDataManager> get_clone() const = 0;
      96             : 
      97           0 :   virtual size_t get_l_max() const = 0;
      98             : 
      99           0 :   virtual std::pair<size_t, size_t> get_time_span() const = 0;
     100             : };
     101             : 
     102             : /*!
     103             :  * \brief Manages the cached buffer data associated with a CCE worldtube and
     104             :  * interpolates to requested time points to provide worldtube boundary data to
     105             :  * the main evolution routines.
     106             :  *
     107             :  * \details The maintained buffer will be maintained at a length that is set by
     108             :  * the `Interpolator` and the `buffer_depth` also passed to the constructor. A
     109             :  * longer depth will ensure that the buffer updater is called less frequently,
     110             :  * which is useful for slow updaters (e.g. those that perform file access).
     111             :  * The main functionality is provided by the
     112             :  * `WorldtubeDataManager::populate_hypersurface_boundary_data()` member
     113             :  * function that handles buffer updating and boundary computation.
     114             :  */
     115           1 : class MetricWorldtubeDataManager
     116             :     : public WorldtubeDataManager<
     117             :           Tags::characteristic_worldtube_boundary_tags<Tags::BoundaryValue>> {
     118           0 :   using input_tags = cce_metric_input_tags<ComplexModalVector>;
     119             : 
     120             :  public:
     121             :   // charm needs an empty constructor.
     122           0 :   MetricWorldtubeDataManager() = default;
     123             : 
     124           0 :   MetricWorldtubeDataManager(
     125             :       std::unique_ptr<WorldtubeBufferUpdater<input_tags>> buffer_updater,
     126             :       size_t l_max, size_t buffer_depth,
     127             :       std::unique_ptr<intrp::SpanInterpolator> interpolator,
     128             :       bool fix_spec_normalization);
     129             : 
     130           0 :   WRAPPED_PUPable_decl_template(MetricWorldtubeDataManager);  // NOLINT
     131             : 
     132           0 :   explicit MetricWorldtubeDataManager(CkMigrateMessage* /*unused*/) {}
     133             : 
     134             :   /*!
     135             :    * \brief Update the `boundary_data_box` entries for all tags in
     136             :    * `Tags::characteristic_worldtube_boundary_tags` to the boundary data at
     137             :    * `time`.
     138             :    *
     139             :    * \details First, if the stored buffer requires updating, it will be updated
     140             :    * via the `buffer_updater_` supplied in the constructor. Then, each of the
     141             :    * spatial metric, shift, lapse, and each of their radial and time derivatives
     142             :    * are interpolated across buffer points to the requested time value (via the
     143             :    * `Interpolator` provided in the constructor). Finally, that data is supplied
     144             :    * to the `create_bondi_boundary_data()`, which updates the
     145             :    * `boundary_data_box` with the Bondi spin-weighted scalars determined from
     146             :    * the interpolated Cartesian data.
     147             :    *
     148             :    * Returns `true` if the time can be supplied from the `buffer_updater_`, and
     149             :    * `false` otherwise. No tags are updated if `false` is returned.
     150             :    */
     151           1 :   bool populate_hypersurface_boundary_data(
     152             :       gsl::not_null<Variables<
     153             :           Tags::characteristic_worldtube_boundary_tags<Tags::BoundaryValue>>*>
     154             :           boundary_data_variables,
     155             :       double time, gsl::not_null<Parallel::NodeLock*> hdf5_lock) const override;
     156             : 
     157           0 :   std::unique_ptr<WorldtubeDataManager> get_clone() const override;
     158             : 
     159             :   /// retrieves the l_max that will be supplied to the \ref DataBoxGroup in
     160             :   /// `populate_hypersurface_boundary_data()`
     161           1 :   size_t get_l_max() const override { return l_max_; }
     162             : 
     163             :   /// retrieves the current time span associated with the `buffer_updater_` for
     164             :   /// diagnostics
     165           1 :   std::pair<size_t, size_t> get_time_span() const override;
     166             : 
     167             :   /// Serialization for Charm++.
     168           1 :   void pup(PUP::er& p) override;  // NOLINT
     169             : 
     170             :  private:
     171           0 :   std::unique_ptr<WorldtubeBufferUpdater<input_tags>> buffer_updater_;
     172             :   // NOLINTNEXTLINE(spectre-mutable)
     173           0 :   mutable size_t time_span_start_ = 0;
     174             :   // NOLINTNEXTLINE(spectre-mutable)
     175           0 :   mutable size_t time_span_end_ = 0;
     176           0 :   size_t l_max_ = 0;
     177           0 :   bool fix_spec_normalization_ = false;
     178             : 
     179             :   // These buffers are just kept around to avoid allocations; they're
     180             :   // updated every time a time is requested
     181             :   // NOLINTNEXTLINE(spectre-mutable)
     182           0 :   mutable Variables<input_tags> interpolated_coefficients_;
     183             : 
     184             :   // note: buffers store data in a 'time-varies-fastest' manner
     185             :   // NOLINTNEXTLINE(spectre-mutable)
     186           0 :   mutable Variables<input_tags> coefficients_buffers_;
     187             : 
     188           0 :   size_t buffer_depth_ = 0;
     189             : 
     190           0 :   std::unique_ptr<intrp::SpanInterpolator> interpolator_;
     191             : };
     192             : 
     193             : /*!
     194             :  * \brief Manages the bondi cached buffer dataset associated with a CCE
     195             :  * worldtube and interpolates to requested time points to provide worldtube
     196             :  * boundary data to the main evolution routines.
     197             :  *
     198             :  * \details The maintained buffer will be kept at a length that is set by
     199             :  * the `Interpolator` and the `buffer_depth` also passed to the constructor. A
     200             :  * longer depth will ensure that the buffer updater is called less frequently,
     201             :  * which is useful for slow updaters (e.g. those that perform file access).
     202             :  * The main functionality is provided by the
     203             :  * `WorldtubeDataManager::populate_hypersurface_boundary_data()` member
     204             :  * function that handles buffer updating and boundary computation. This version
     205             :  * of the data manager handles the 9 scalars of
     206             :  * `worldtube_boundary_tags_for_writing<Spectral::Swsh::Tags::SwshTransform>`,
     207             :  * rather than direct metric components handled by `WorldtubeDataManager`. The
     208             :  * set of 9 scalars is a far leaner (factor of ~4) data storage format.
     209             :  */
     210           1 : class BondiWorldtubeDataManager
     211             :     : public WorldtubeDataManager<
     212             :           Tags::characteristic_worldtube_boundary_tags<Tags::BoundaryValue>> {
     213             :  public:
     214             :   // charm needs an empty constructor.
     215           0 :   BondiWorldtubeDataManager() = default;
     216             : 
     217           0 :   BondiWorldtubeDataManager(
     218             :       std::unique_ptr<
     219             :           WorldtubeBufferUpdater<Tags::worldtube_boundary_tags_for_writing<
     220             :               Spectral::Swsh::Tags::SwshTransform>>>
     221             :           buffer_updater,
     222             :       size_t l_max, size_t buffer_depth,
     223             :       std::unique_ptr<intrp::SpanInterpolator> interpolator);
     224             : 
     225           0 :   WRAPPED_PUPable_decl_template(BondiWorldtubeDataManager);  // NOLINT
     226             : 
     227           0 :   explicit BondiWorldtubeDataManager(CkMigrateMessage* /*unused*/) {}
     228             : 
     229             :   /*!
     230             :    * \brief Update the `boundary_data_box` entries for all tags in
     231             :    * `Tags::characteristic_worldtube_boundary_tags` to the boundary data at
     232             :    * `time`.
     233             :    *
     234             :    * \details First, if the stored buffer requires updating, it will be updated
     235             :    * via the `buffer_updater_` supplied in the constructor. Then, each of the
     236             :    * 9 spin-weighted scalars in
     237             :    * `worldtube_boundary_tags_for_writing<Spectral::Swsh::Tags::SwshTransform>`
     238             :    * are interpolated across buffer points to the requested time value (via the
     239             :    * `Interpolator` provided in the constructor). Finally, the remaining two
     240             :    * scalars not directly supplied in the input file are calculated in-line and
     241             :    * put in the \ref DataBoxGroup.
     242             :    *
     243             :    * Returns `true` if the time can be supplied from the `buffer_updater_`, and
     244             :    * `false` otherwise. No tags are updated if `false` is returned.
     245             :    */
     246           1 :   bool populate_hypersurface_boundary_data(
     247             :       gsl::not_null<Variables<
     248             :           Tags::characteristic_worldtube_boundary_tags<Tags::BoundaryValue>>*>
     249             :           boundary_data_variables,
     250             :       double time, gsl::not_null<Parallel::NodeLock*> hdf5_lock) const override;
     251             : 
     252           0 :   std::unique_ptr<WorldtubeDataManager> get_clone() const override;
     253             : 
     254             :   /// retrieves the l_max that will be supplied to the \ref DataBoxGroup in
     255             :   /// `populate_hypersurface_boundary_data()`
     256           1 :   size_t get_l_max() const override { return l_max_; }
     257             : 
     258             :   /// retrieves the current time span associated with the `buffer_updater_` for
     259             :   /// diagnostics
     260           1 :   std::pair<size_t, size_t> get_time_span() const override;
     261             : 
     262             :   /// Serialization for Charm++.
     263           1 :   void pup(PUP::er& p) override;  // NOLINT
     264             : 
     265             :  private:
     266             :   // Compute the boundary value of `Du<Dr<BondiJ>>` at the requested time by
     267             :   // numerically time-differentiating the buffered `Dr<BondiJ>` with
     268             :   // `interpolator_`, holding the angular coordinate fixed (i.e. following the
     269             :   // worldtube). This is the time derivative at constant numerical coordinate
     270             :   // y = -1, i.e. d_ubreve d_r J|_Gamma = d/du (d_r J|_Gamma), and is *not* a
     271             :   // derivative at constant Bondi r.
     272           0 :   void populate_boundary_du_dr_j(
     273             :       gsl::not_null<Variables<
     274             :           Tags::characteristic_worldtube_boundary_tags<Tags::BoundaryValue>>*>
     275             :           boundary_data_variables,
     276             :       double time) const;
     277             : 
     278             :   std::unique_ptr<
     279             :       WorldtubeBufferUpdater<Tags::worldtube_boundary_tags_for_writing<
     280             :           Spectral::Swsh::Tags::SwshTransform>>>
     281           0 :       buffer_updater_;
     282             :   // NOLINTNEXTLINE(spectre-mutable)
     283           0 :   mutable size_t time_span_start_ = 0;
     284             :   // NOLINTNEXTLINE(spectre-mutable)
     285           0 :   mutable size_t time_span_end_ = 0;
     286           0 :   size_t l_max_ = 0;
     287             : 
     288             :   // These buffers are just kept around to avoid allocations; they're
     289             :   // updated every time a time is requested
     290             :   // NOLINTNEXTLINE(spectre-mutable)
     291             :   mutable Variables<Tags::worldtube_boundary_tags_for_writing<
     292             :       Spectral::Swsh::Tags::SwshTransform>>
     293           0 :       interpolated_coefficients_;
     294             : 
     295             :   // note: buffers store data in an 'time-varies-fastest' manner
     296             :   // NOLINTNEXTLINE(spectre-mutable)
     297             :   mutable Variables<Tags::worldtube_boundary_tags_for_writing<
     298             :       Spectral::Swsh::Tags::SwshTransform>>
     299           0 :       coefficients_buffers_;
     300             : 
     301           0 :   size_t buffer_depth_ = 0;
     302             : 
     303           0 :   std::unique_ptr<intrp::SpanInterpolator> interpolator_;
     304             : };
     305             : 
     306           0 : class KleinGordonWorldtubeDataManager
     307             :     : public WorldtubeDataManager<Tags::klein_gordon_worldtube_boundary_tags> {
     308             :  public:
     309             :   // charm needs an empty constructor.
     310           0 :   KleinGordonWorldtubeDataManager() = default;
     311             : 
     312           0 :   KleinGordonWorldtubeDataManager(
     313             :       std::unique_ptr<WorldtubeBufferUpdater<klein_gordon_input_tags>>
     314             :           buffer_updater,
     315             :       size_t l_max, size_t buffer_depth,
     316             :       std::unique_ptr<intrp::SpanInterpolator> interpolator);
     317             : 
     318           0 :   WRAPPED_PUPable_decl_template(KleinGordonWorldtubeDataManager);  // NOLINT
     319             : 
     320           0 :   explicit KleinGordonWorldtubeDataManager(CkMigrateMessage* /*unused*/) {}
     321             : 
     322             :   /*!
     323             :    * \brief Update the `boundary_data_box` entries for all tags in
     324             :    * `Tags::klein_gordon_worldtube_boundary_tags` to the boundary data at
     325             :    * `time`.
     326             :    *
     327             :    * \details First, if the stored buffer requires updating, it will be updated
     328             :    * via the `buffer_updater_` supplied in the constructor. Then, each of the
     329             :    * 2 spin-weighted scalars in `Tags::klein_gordon_worldtube_boundary_tags`
     330             :    * are interpolated across buffer points to the requested time value (via the
     331             :    * `Interpolator` provided in the constructor).
     332             :    *
     333             :    * Returns `true` if the time can be supplied from the `buffer_updater_`, and
     334             :    * `false` otherwise. No tags are updated if `false` is returned.
     335             :    */
     336           1 :   bool populate_hypersurface_boundary_data(
     337             :       gsl::not_null<Variables<Tags::klein_gordon_worldtube_boundary_tags>*>
     338             :           boundary_data_variables,
     339             :       double time, gsl::not_null<Parallel::NodeLock*> hdf5_lock) const override;
     340             : 
     341           0 :   std::unique_ptr<WorldtubeDataManager> get_clone() const override;
     342             : 
     343             :   /// retrieves the l_max that will be supplied to the \ref DataBoxGroup in
     344             :   /// `populate_hypersurface_boundary_data()`
     345           1 :   size_t get_l_max() const override { return l_max_; }
     346             : 
     347             :   /// retrieves the current time span associated with the `buffer_updater_` for
     348             :   /// diagnostics
     349           1 :   std::pair<size_t, size_t> get_time_span() const override;
     350             : 
     351             :   /// Serialization for Charm++.
     352           1 :   void pup(PUP::er& p) override;  // NOLINT
     353             : 
     354             :  private:
     355             :   std::unique_ptr<WorldtubeBufferUpdater<klein_gordon_input_tags>>
     356           0 :       buffer_updater_;
     357             :   // NOLINTNEXTLINE(spectre-mutable)
     358           0 :   mutable size_t time_span_start_ = 0;
     359             :   // NOLINTNEXTLINE(spectre-mutable)
     360           0 :   mutable size_t time_span_end_ = 0;
     361           0 :   size_t l_max_ = 0;
     362             : 
     363             :   // These buffers are just kept around to avoid allocations; they're
     364             :   // updated every time a time is requested
     365             :   // NOLINTNEXTLINE(spectre-mutable)
     366           0 :   mutable Variables<klein_gordon_input_tags> interpolated_coefficients_;
     367             : 
     368             :   // note: buffers store data in an 'time-varies-fastest' manner
     369             :   // NOLINTNEXTLINE(spectre-mutable)
     370           0 :   mutable Variables<klein_gordon_input_tags> coefficients_buffers_;
     371             : 
     372           0 :   size_t buffer_depth_ = 0;
     373             : 
     374           0 :   std::unique_ptr<intrp::SpanInterpolator> interpolator_;
     375             : };
     376             : }  // namespace Cce

Generated by: LCOV version 1.14