WorldtubeBufferUpdater.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 #include <memory>
8 #include <string>
9 #include <utility>
10 
11 #include "DataStructures/ComplexModalVector.hpp"
12 #include "DataStructures/DataBox/PrefixHelpers.hpp"
14 #include "DataStructures/DataBox/Tag.hpp"
15 #include "DataStructures/DataBox/TagName.hpp"
16 #include "DataStructures/DataVector.hpp"
18 #include "ErrorHandling/Assert.hpp"
19 #include "Evolution/Systems/Cce/Tags.hpp"
20 #include "IO/H5/Dat.hpp"
21 #include "IO/H5/File.hpp"
22 #include "IO/H5/Version.hpp"
23 #include "NumericalAlgorithms/Spectral/SwshTags.hpp"
25 #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
26 #include "Utilities/Gsl.hpp"
27 #include "Utilities/TMPL.hpp"
28 #include "Utilities/TaggedTuple.hpp"
29 
30 namespace Cce {
31 namespace Tags {
32 namespace detail {
33 // tags for use in the buffers for the modal input worldtube data management
34 // classes
35 using SpatialMetric =
39 
40 // radial derivative prefix tag to be used with the modal input worldtube data
41 template <typename Tag>
42 struct Dr : db::SimpleTag, db::PrefixTag {
43  using type = typename Tag::type;
44  using tag = Tag;
45 };
46 
47 // tag for the string for accessing the quantity associated with `Tag` in
48 // worldtube h5 file
49 template <typename Tag>
50 struct InputDataSet : db::SimpleTag, db::PrefixTag {
51  using type = std::string;
52  using tag = Tag;
53 };
54 } // namespace detail
55 } // namespace Tags
56 
57 namespace detail {
58 // generates the component dataset name in the worldtube file based on the
59 // tensor indices requested. For instance, if called with arguments ("/g", 0,1),
60 // it returns the dataset name "/gxy".
61 template <typename... T>
62 std::string dataset_name_for_component(std::string base_name,
63  const T... indices) noexcept { // NOLINT
64  const auto add_index = [&base_name](size_t index) noexcept {
65  ASSERT(index < 3, "The character-arithmetic index must be less than 3.");
66  base_name += static_cast<char>('x' + index);
67  };
68  EXPAND_PACK_LEFT_TO_RIGHT(add_index(indices));
69  // void cast so that compilers can tell it's used.
70  (void)add_index;
71  return base_name;
72 }
73 
74 // creates a pair of indices such that the difference is `2 *
75 // interpolator_length + pad`, centered around `time`, and bounded by
76 // `lower_bound` and `upper_bound`. If it cannot be centered, it gives a span
77 // that is appropriately sized and bounded by the supplied bounds. If the bounds
78 // are too constraining for the necessary size, it gives a span that is the
79 // correct size starting at `lower bound`, but not constrained by `upper_bound`
80 std::pair<size_t, size_t> create_span_for_time_value(
81  double time, size_t pad, size_t interpolator_length, size_t lower_bound,
82  size_t upper_bound, const DataVector& time_buffer) noexcept;
83 } // namespace detail
84 
85 /// the full set of tensors to be extracted from the worldtube h5 file
86 using cce_metric_input_tags = tmpl::list<
87  Tags::detail::SpatialMetric, Tags::detail::Dr<Tags::detail::SpatialMetric>,
88  ::Tags::dt<Tags::detail::SpatialMetric>, Tags::detail::Shift,
89  Tags::detail::Dr<Tags::detail::Shift>, ::Tags::dt<Tags::detail::Shift>,
90  Tags::detail::Lapse, Tags::detail::Dr<Tags::detail::Lapse>,
92 
93 /// the full set of tensors to be extracted from the reduced form of the
94 /// worldtube h5 file
96  tmpl::list<Spectral::Swsh::Tags::SwshTransform<Tags::BondiBeta>,
105 
106 /// \cond
109 /// \endcond
110 
111 /*!
112  * \brief Abstract base class for utilities that are able to perform the buffer
113  * updating procedure needed by the `WorldtubeDataManager`.
114  *
115  * \details The methods that are required to be overridden in the derived
116  * classes are:
117  * - `WorldtubeBufferUpdater::update_buffers_for_time()`:
118  * updates the buffers passed by pointer and the `time_span_start` and
119  * `time_span_end` to be appropriate for the requested `time`,
120  * `interpolator_length`, and `buffer_depth`.
121  * - `WorldtubeBufferUpdater::get_clone()`
122  * clone function to obtain a `std::unique_ptr` of the base
123  * `WorldtubeBufferUpdater`, needed to pass around the factory-created
124  * object.
125  * - `WorldtubeBufferUpdater::time_is_outside_range()`
126  * the override should return `true` if the `time` could be used in a
127  * `update_buffers_for_time` call given the data available to the derived
128  * class, and `false` otherwise
129  * - `WorldtubeBufferUpdater::get_l_max()`
130  * The override should return the `l_max` it uses in the
131  * Goldberg modal data placed in the buffers.
132  * - `WorldtubeBufferUpdater::get_extraction_radius()`
133  * The override should return the coordinate radius associated with the modal
134  * worldtube data that it supplies in the buffer update function. This is
135  * currently assumed to be a single double, but may be generalized in future
136  * to be time-dependent.
137  * - `WorldtubeBufferUpdater::get_time_buffer`
138  * The override should return the vector of times that it can produce modal
139  * data at. For instance, if associated with a file input, this will be the
140  * times at each of the rows of the time-series data.
141  */
142 template <typename BufferTags>
143 class WorldtubeBufferUpdater : public PUP::able {
144  public:
145  using creatable_classes =
146  tmpl::list<MetricWorldtubeH5BufferUpdater, BondiWorldtubeH5BufferUpdater>;
147 
148  WRAPPED_PUPable_abstract(WorldtubeBufferUpdater); // NOLINT
149 
150  virtual double update_buffers_for_time(
151  gsl::not_null<Variables<BufferTags>*> buffers,
152  gsl::not_null<size_t*> time_span_start,
153  gsl::not_null<size_t*> time_span_end, double time,
154  size_t computation_l_max, size_t interpolator_length,
155  size_t buffer_depth) const noexcept = 0;
156 
157  virtual std::unique_ptr<WorldtubeBufferUpdater> get_clone()
158  const noexcept = 0;
159 
160  virtual bool time_is_outside_range(double time) const noexcept = 0;
161 
162  virtual size_t get_l_max() const noexcept = 0;
163 
164  virtual double get_extraction_radius() const noexcept = 0;
165 
166  virtual bool has_version_history() const noexcept = 0;
167 
168  virtual DataVector& get_time_buffer() noexcept = 0;
169 };
170 
171 /// A `WorldtubeBufferUpdater` specialized to the CCE input worldtube H5 file
172 /// produced by SpEC.
174  : public WorldtubeBufferUpdater<cce_metric_input_tags> {
175  public:
176  // charm needs the empty constructor
177  MetricWorldtubeH5BufferUpdater() = default;
178 
179  /// The constructor takes the filename of the SpEC h5 file that will be used
180  /// for boundary data. Note that this assumes that the input data has
181  /// correctly-normalized radial derivatives, and that the extraction radius is
182  /// encoded as an integer in the filename.
184  const std::string& cce_data_filename) noexcept;
185 
186  WRAPPED_PUPable_decl_template(MetricWorldtubeH5BufferUpdater); // NOLINT
187 
189  CkMigrateMessage* /*unused*/) noexcept {}
190 
191  /// update the `buffers`, `time_span_start`, and `time_span_end` with
192  /// time-varies-fastest, Goldberg modal data and the start and end index in
193  /// the member `time_buffer_` covered by the newly updated `buffers`. The
194  /// function returns the next time at which a full update will occur. If
195  /// called again at times earlier than the next full update time, it will
196  /// leave the `buffers` unchanged and again return the next needed time.
198  gsl::not_null<Variables<cce_metric_input_tags>*> buffers,
199  gsl::not_null<size_t*> time_span_start,
200  gsl::not_null<size_t*> time_span_end, double time,
201  size_t computation_l_max, size_t interpolator_length,
202  size_t buffer_depth) const noexcept override;
203 
205  const noexcept override;
206 
207  /// The time can only be supported in the buffer update if it is between the
208  /// first and last time of the input file.
209  bool time_is_outside_range(double time) const noexcept override;
210 
211  /// retrieves the l_max of the input file
212  size_t get_l_max() const noexcept override { return l_max_; }
213 
214  /// retrieves the extraction radius encoded in the filename
215  double get_extraction_radius() const noexcept override {
216  return extraction_radius_;
217  }
218 
219  /// The time buffer is supplied by non-const reference to allow views to
220  /// easily point into the buffer.
221  ///
222  /// \warning Altering this buffer outside of the constructor of this class
223  /// results in undefined behavior! This should be supplied by const reference
224  /// once there is a convenient method of producing a const view of a vector
225  /// type.
226  DataVector& get_time_buffer() noexcept override { return time_buffer_; }
227 
228  bool has_version_history() const noexcept override {
229  return has_version_history_;
230  }
231 
232  /// Serialization for Charm++.
233  void pup(PUP::er& p) noexcept override;
234 
235  private:
236  void update_buffer(gsl::not_null<ComplexModalVector*> buffer_to_update,
237  const h5::Dat& read_data, size_t computation_l_max,
238  size_t time_span_start,
239  size_t time_span_end) const noexcept;
240 
241  bool has_version_history_ = true;
242  double extraction_radius_ = 1.0;
243  size_t l_max_ = 0;
244 
246  std::string filename_;
247 
248  tuples::tagged_tuple_from_typelist<
250  dataset_names_;
251 
252  // stores all the times in the input file
253  DataVector time_buffer_;
254 };
255 
256 /// A `WorldtubeBufferUpdater` specialized to the CCE input worldtube H5 file
257 /// produced by the reduced SpEC format.
259  : public WorldtubeBufferUpdater<cce_bondi_input_tags> {
260  public:
261  // charm needs the empty constructor
262  BondiWorldtubeH5BufferUpdater() = default;
263 
264  /// The constructor takes the filename of the SpEC h5 file that will be used
265  /// for boundary data. Note that this assumes that the input data has
266  /// correctly-normalized radial derivatives, and that the extraction radius is
267  /// encoded as an integer in the filename.
269  const std::string& cce_data_filename) noexcept;
270 
271  WRAPPED_PUPable_decl_template(BondiWorldtubeH5BufferUpdater); // NOLINT
272 
274  CkMigrateMessage* /*unused*/) noexcept {}
275 
276  /// update the `buffers`, `time_span_start`, and `time_span_end` with
277  /// time-varies-fastest, Goldberg modal data and the start and end index in
278  /// the member `time_buffer_` covered by the newly updated `buffers`.
280  gsl::not_null<Variables<cce_bondi_input_tags>*> buffers,
281  gsl::not_null<size_t*> time_span_start,
282  gsl::not_null<size_t*> time_span_end, double time,
283  size_t computation_l_max, size_t interpolator_length,
284  size_t buffer_depth) const noexcept override;
285 
287  const noexcept override {
288  return std::make_unique<BondiWorldtubeH5BufferUpdater>(filename_);
289  }
290 
291  /// The time can only be supported in the buffer update if it is between the
292  /// first and last time of the input file.
293  bool time_is_outside_range(const double time) const noexcept override {
294  return time < time_buffer_[0] or
295  time > time_buffer_[time_buffer_.size() - 1];
296  }
297 
298  /// retrieves the l_max of the input file
299  size_t get_l_max() const noexcept override { return l_max_; }
300 
301  /// retrieves the extraction radius encoded in the filename
302  double get_extraction_radius() const noexcept override {
303  return extraction_radius_;
304  }
305 
306  /// The time buffer is supplied by non-const reference to allow views to
307  /// easily point into the buffer.
308  ///
309  /// \warning Altering this buffer outside of the constructor of this class
310  /// results in undefined behavior! This should be supplied by const reference
311  /// once there is a convenient method of producing a const view of a vector
312  /// type.
313  DataVector& get_time_buffer() noexcept override { return time_buffer_; }
314 
315  bool has_version_history() const noexcept override {
316  return true;
317  }
318 
319  /// Serialization for Charm++.
320  void pup(PUP::er& p) noexcept override;
321 
322  private:
323  void update_buffer(gsl::not_null<ComplexModalVector*> buffer_to_update,
324  const h5::Dat& read_data, size_t computation_l_max,
325  size_t time_span_start, size_t time_span_end,
326  bool is_real) const noexcept;
327 
328  double extraction_radius_ = 1.0;
329  size_t l_max_ = 0;
330 
332  std::string filename_;
333 
334  tuples::tagged_tuple_from_typelist<
336  dataset_names_;
337 
338  // stores all the times in the input file
339  DataVector time_buffer_;
340 };
341 } // namespace Cce
h5::read_data
T read_data(const hid_t group_id, const std::string &dataset_name) noexcept
Read an array of rank 0-3 into an object.
Definition: Helpers.cpp:458
Cce::MetricWorldtubeH5BufferUpdater
A WorldtubeBufferUpdater specialized to the CCE input worldtube H5 file produced by SpEC.
Definition: WorldtubeBufferUpdater.hpp:173
std::string
CharmPupable.hpp
EXPAND_PACK_LEFT_TO_RIGHT
#define EXPAND_PACK_LEFT_TO_RIGHT(...)
Expand a parameter pack evaluating the terms from left to right.
Definition: TMPL.hpp:563
utility
Cce::BondiWorldtubeH5BufferUpdater::get_time_buffer
DataVector & get_time_buffer() noexcept override
The time buffer is supplied by non-const reference to allow views to easily point into the buffer.
Definition: WorldtubeBufferUpdater.hpp:313
gr::Tags::SpatialMetric
Definition: Tags.hpp:26
db::PrefixTag
Mark a struct as a prefix tag by inheriting from this.
Definition: Tag.hpp:103
std::pair
h5::Dat
Represents a multicolumn dat file inside an HDF5 file.
Definition: Dat.hpp:42
Cce::BondiWorldtubeH5BufferUpdater::get_extraction_radius
double get_extraction_radius() const noexcept override
retrieves the extraction radius encoded in the filename
Definition: WorldtubeBufferUpdater.hpp:302
Cce::MetricWorldtubeH5BufferUpdater::time_is_outside_range
bool time_is_outside_range(double time) const noexcept override
The time can only be supported in the buffer update if it is between the first and last time of the i...
Definition: WorldtubeBufferUpdater.cpp:210
db::SimpleTag
Mark a struct as a simple tag by inheriting from this.
Definition: Tag.hpp:36
Cce::BondiWorldtubeH5BufferUpdater
A WorldtubeBufferUpdater specialized to the CCE input worldtube H5 file produced by the reduced SpEC ...
Definition: WorldtubeBufferUpdater.hpp:258
File.hpp
h5::H5File< h5::AccessType::ReadOnly >
Version.hpp
Spectral::Swsh::Tags::SwshTransform
Prefix tag representing the spin-weighted spherical harmonic transform of a spin-weighted scalar.
Definition: SwshTags.hpp:183
cstddef
Assert.hpp
Cce::MetricWorldtubeH5BufferUpdater::get_l_max
size_t get_l_max() const noexcept override
retrieves the l_max of the input file
Definition: WorldtubeBufferUpdater.hpp:212
Cce::MetricWorldtubeH5BufferUpdater::get_time_buffer
DataVector & get_time_buffer() noexcept override
The time buffer is supplied by non-const reference to allow views to easily point into the buffer.
Definition: WorldtubeBufferUpdater.hpp:226
DataVector
Stores a collection of function values.
Definition: DataVector.hpp:42
Cce::BondiWorldtubeH5BufferUpdater::update_buffers_for_time
double update_buffers_for_time(gsl::not_null< Variables< cce_bondi_input_tags > * > buffers, gsl::not_null< size_t * > time_span_start, gsl::not_null< size_t * > time_span_end, double time, size_t computation_l_max, size_t interpolator_length, size_t buffer_depth) const noexcept override
update the buffers, time_span_start, and time_span_end with time-varies-fastest, Goldberg modal data ...
Definition: WorldtubeBufferUpdater.cpp:319
Cce::MetricWorldtubeH5BufferUpdater::get_extraction_radius
double get_extraction_radius() const noexcept override
retrieves the extraction radius encoded in the filename
Definition: WorldtubeBufferUpdater.hpp:215
memory
Cce::MetricWorldtubeH5BufferUpdater::update_buffers_for_time
double update_buffers_for_time(gsl::not_null< Variables< cce_metric_input_tags > * > buffers, gsl::not_null< size_t * > time_span_start, gsl::not_null< size_t * > time_span_end, double time, size_t computation_l_max, size_t interpolator_length, size_t buffer_depth) const noexcept override
update the buffers, time_span_start, and time_span_end with time-varies-fastest, Goldberg modal data ...
Definition: WorldtubeBufferUpdater.cpp:131
gr::Tags::Shift
Definition: Tags.hpp:48
Cce::cce_metric_input_tags
tmpl::list< Tags::detail::SpatialMetric, Tags::detail::Dr< Tags::detail::SpatialMetric >, ::Tags::dt< Tags::detail::SpatialMetric >, Tags::detail::Shift, Tags::detail::Dr< Tags::detail::Shift >, ::Tags::dt< Tags::detail::Shift >, Tags::detail::Lapse, Tags::detail::Dr< Tags::detail::Lapse >, ::Tags::dt< Tags::detail::Lapse > > cce_metric_input_tags
the full set of tensors to be extracted from the worldtube h5 file
Definition: WorldtubeBufferUpdater.hpp:91
ASSERT
#define ASSERT(a, m)
Assert that an expression should be true.
Definition: Assert.hpp:51
Tags::dt
Prefix indicating a time derivative.
Definition: Prefixes.hpp:29
Cce
The set of utilities for performing Cauchy characteristic evolution and Cauchy characteristic matchin...
Definition: BoundaryComputeAndSendToEvolution.hpp:28
Gsl.hpp
Dat.hpp
Cce::MetricWorldtubeH5BufferUpdater::pup
void pup(PUP::er &p) noexcept override
Serialization for Charm++.
Definition: WorldtubeBufferUpdater.cpp:215
db::wrap_tags_in
tmpl::transform< TagList, tmpl::bind< Wrapper, tmpl::_1, tmpl::pin< Args >... > > wrap_tags_in
Create a new tmpl::list of tags by wrapping each tag in TagList in Wrapper<_, Args....
Definition: PrefixHelpers.hpp:30
Matrix.hpp
Cce::BondiWorldtubeH5BufferUpdater::get_l_max
size_t get_l_max() const noexcept override
retrieves the l_max of the input file
Definition: WorldtubeBufferUpdater.hpp:299
Cce::WorldtubeBufferUpdater
Abstract base class for utilities that are able to perform the buffer updating procedure needed by th...
Definition: WorldtubeBufferUpdater.hpp:143
Cce::BondiWorldtubeH5BufferUpdater::pup
void pup(PUP::er &p) noexcept override
Serialization for Charm++.
Definition: WorldtubeBufferUpdater.cpp:433
std::unique_ptr
Prefixes.hpp
gr::Tags::Lapse
Definition: Tags.hpp:52
TMPL.hpp
Cce::cce_bondi_input_tags
tmpl::list< Spectral::Swsh::Tags::SwshTransform< Tags::BondiBeta >, Spectral::Swsh::Tags::SwshTransform< Tags::BondiU >, Spectral::Swsh::Tags::SwshTransform< Tags::BondiQ >, Spectral::Swsh::Tags::SwshTransform< Tags::BondiW >, Spectral::Swsh::Tags::SwshTransform< Tags::BondiJ >, Spectral::Swsh::Tags::SwshTransform< Tags::Dr< Tags::BondiJ > >, Spectral::Swsh::Tags::SwshTransform< Tags::Du< Tags::BondiJ > >, Spectral::Swsh::Tags::SwshTransform< Tags::BondiR >, Spectral::Swsh::Tags::SwshTransform< Tags::Du< Tags::BondiR > >> cce_bondi_input_tags
the full set of tensors to be extracted from the reduced form of the worldtube h5 file
Definition: WorldtubeBufferUpdater.hpp:104
Cce::BondiWorldtubeH5BufferUpdater::time_is_outside_range
bool time_is_outside_range(const double time) const noexcept override
The time can only be supported in the buffer update if it is between the first and last time of the i...
Definition: WorldtubeBufferUpdater.hpp:293
gsl::not_null
Require a pointer to not be a nullptr
Definition: Gsl.hpp:183
string