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