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

Generated by: LCOV version 1.14