Line data Source code
1 1 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : /// \file
5 : /// Declares functions for interpolating data in volume files to target points.
6 : /// This file is intended to be included in external programs, so it
7 : /// intentionally has no dependencies on any other headers.
8 :
9 : #pragma once
10 :
11 : #include <array>
12 : #include <cstddef>
13 : #include <limits>
14 : #include <optional>
15 : #include <string>
16 : #include <variant>
17 : #include <vector>
18 :
19 : /// Functions that are intended to be used by external programs, e.g. to
20 : /// interpolate data in volume files to target points.
21 0 : namespace spectre::Exporter {
22 :
23 : /// Identifies an observation by its ID in the volume data file.
24 1 : struct ObservationId {
25 0 : ObservationId() = default;
26 0 : explicit ObservationId(size_t local_value) : value(local_value) {}
27 0 : size_t value;
28 : };
29 :
30 : /// Identifies an observation by its index in the ordered list of observations.
31 : /// Negative indices are counted from the end of the list.
32 1 : struct ObservationStep {
33 0 : ObservationStep() = default;
34 0 : explicit ObservationStep(int local_value) : value(local_value) {}
35 0 : int value;
36 : };
37 :
38 : /// Identifies an observation by its value (e.g. the time), selecting the
39 : /// observation whose value is closest to `value` within `epsilon`. This is the
40 : /// same selection as a bare `double`, but with a configurable tolerance.
41 1 : struct ObservationValue {
42 0 : ObservationValue() = default;
43 0 : explicit ObservationValue(double local_value, double local_epsilon = 1e-12)
44 : : value(local_value), epsilon(local_epsilon) {}
45 0 : double value = std::numeric_limits<double>::signaling_NaN();
46 0 : double epsilon = 1e-12;
47 : };
48 :
49 0 : using ObservationVariant =
50 : std::variant<ObservationId, ObservationStep, double, ObservationValue>;
51 :
52 : /*!
53 : * \brief Interpolate data in volume files to target points
54 : *
55 : * \tparam Dim Dimension of the domain
56 : * \param volume_files_or_glob The list of H5 files, or a glob pattern
57 : * \param subfile_name The name of the subfile in the H5 files containing the
58 : * volume data
59 : * \param observation Either the observation ID as a `size_t`, or the index of
60 : * the observation in the volume files to interpolate as an `int` (a value of 0
61 : * would be the first observation, and a value of -1 would be the last
62 : * observation).
63 : * \param tensor_components The tensor components to interpolate, e.g.
64 : * "Lapse", "Shift_x", "Shift_y", "Shift_z", "SpatialMetric_xx", etc.
65 : * Look into the H5 file to see what components are available.
66 : * \param target_points The points to interpolate to, in inertial coordinates.
67 : * \param extrapolate_into_excisions Enables extrapolation into excision regions
68 : * of the domain (default is `false`). This can be useful to fill the excision
69 : * region with (constraint-violating but smooth) data so it can be imported into
70 : * moving puncture codes. Specifically, we implement the strategy used in
71 : * \cite Etienne2008re adjusted for distorted excisions: we choose uniformly
72 : * spaced radial anchor points spaced as $\Delta r = 0.3 r_\mathrm{AH}$ in the
73 : * grid frame (where the excision is spherical), then map the anchor points to
74 : * the distorted frame (where we have the target point) and do a 7th order
75 : * polynomial extrapolation into the excision region.
76 : * \param error_on_missing_points If `true`, an error will be thrown if any of
77 : * the target points are outside the domain. If `false`, the result will be
78 : * filled with NaNs for points outside the domain (default is `false`).
79 : * \param num_threads The number of threads to use if OpenMP is linked in. If
80 : * not specified, OpenMP will determine the number of threads automatically.
81 : * It's also possible to set the number of threads using the environment
82 : * variable OMP_NUM_THREADS. It's an error to specify num_threads if OpenMP is
83 : * not linked in. Set num_threads to 1 to disable OpenMP.
84 : * \return std::vector<std::vector<double>> The interpolated data. The first
85 : * dimension corresponds to the selected tensor components, and the second
86 : * dimension corresponds to the target points.
87 : */
88 : template <size_t Dim>
89 1 : std::vector<std::vector<double>> interpolate_to_points(
90 : const std::variant<std::vector<std::string>, std::string>&
91 : volume_files_or_glob,
92 : const std::string& subfile_name, const ObservationVariant& observation,
93 : const std::vector<std::string>& tensor_components,
94 : const std::array<std::vector<double>, Dim>& target_points,
95 : bool extrapolate_into_excisions = false,
96 : bool error_on_missing_points = false,
97 : std::optional<size_t> num_threads = std::nullopt);
98 :
99 : } // namespace spectre::Exporter
|