Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <complex>
7 : #include <cstddef>
8 :
9 : #include "DataStructures/ComplexDataVector.hpp"
10 : #include "DataStructures/DataVector.hpp"
11 : #include "DataStructures/Matrix.hpp"
12 : #include "DataStructures/Tensor/TypeAliases.hpp"
13 : #include "DataStructures/Variables.hpp"
14 : #include "Utilities/Blas.hpp"
15 : #include "Utilities/ErrorHandling/Assert.hpp"
16 : #include "Utilities/Gsl.hpp"
17 :
18 : /// \cond
19 : template <size_t Dim>
20 : class Mesh;
21 : namespace PUP {
22 : class er;
23 : } // namespace PUP
24 :
25 : /// \endcond
26 :
27 : namespace intrp {
28 :
29 : /// \ingroup NumericalAlgorithmsGroup
30 : /// \brief Interpolates a `Variables` onto an arbitrary set of points.
31 : ///
32 : /// \details If the `source_mesh` uses Spectral::Basis::FiniteDifference,
33 : /// linear interpolation is done in each dimension; otherwise it uses the
34 : /// barycentric interpolation provided by Spectral::interpolation_matrix in each
35 : /// dimension.
36 : template <size_t Dim>
37 1 : class Irregular {
38 : public:
39 0 : Irregular(
40 : const Mesh<Dim>& source_mesh,
41 : const tnsr::I<DataVector, Dim, Frame::ElementLogical>& target_points,
42 : const std::optional<size_t>& fd_to_fd_interp_order = std::nullopt);
43 0 : Irregular(const Mesh<Dim>& source_mesh,
44 : const tnsr::I<double, Dim, Frame::ElementLogical>& target_point,
45 : const std::optional<size_t>& fd_to_fd_interp_order = std::nullopt);
46 0 : Irregular();
47 :
48 : /// Serialization for Charm++
49 : // NOLINTNEXTLINE(google-runtime-references)
50 1 : void pup(PUP::er& p);
51 :
52 : /// @{
53 : /// Performs the interpolation on a `Variables` with grid points corresponding
54 : /// to the `Mesh<Dim>` specified in the constructor.
55 : /// The result is a `Variables` whose internal `DataVector` goes over the
56 : /// list of target_points that were specified in the constructor.
57 : /// \note for the void function, `result` will be resized to the proper size.
58 : template <typename TagsList>
59 1 : void interpolate(gsl::not_null<Variables<TagsList>*> result,
60 : const Variables<TagsList>& vars) const;
61 : template <typename TagsList>
62 1 : Variables<TagsList> interpolate(const Variables<TagsList>& vars) const;
63 : /// @}
64 :
65 : /// @{
66 : /// \brief Interpolate a DataVector or ComplexDataVector onto the target
67 : /// points.
68 : ///
69 : /// \note When interpolating multiple tensors, the Variables interface is more
70 : /// efficient. However, this DataVector interface is useful for applications
71 : /// where only some components of a Tensor or Variables need to be
72 : /// interpolated.
73 1 : void interpolate(gsl::not_null<DataVector*> result,
74 : const DataVector& input) const;
75 1 : DataVector interpolate(const DataVector& input) const;
76 1 : void interpolate(gsl::not_null<ComplexDataVector*> result,
77 : const ComplexDataVector& input) const;
78 1 : ComplexDataVector interpolate(const ComplexDataVector& input) const;
79 : /// @}
80 :
81 : /// \brief Interpolate multiple variables on the grid to the target points.
82 : /// @{
83 1 : void interpolate(gsl::not_null<gsl::span<double>*> result,
84 : const gsl::span<const double>& input) const;
85 1 : void interpolate(gsl::not_null<gsl::span<std::complex<double>>*> result,
86 : const gsl::span<const std::complex<double>>& input) const;
87 1 : void interpolate(gsl::not_null<gsl::span<float>*> result,
88 : const gsl::span<const float>& input) const;
89 : /// @}
90 :
91 : private:
92 0 : friend bool operator==(const Irregular& lhs, const Irregular& rhs) {
93 : return lhs.interpolation_matrix_ == rhs.interpolation_matrix_;
94 : }
95 0 : Matrix interpolation_matrix_;
96 : };
97 :
98 : template <size_t Dim>
99 : template <typename TagsList>
100 0 : void Irregular<Dim>::interpolate(
101 : const gsl::not_null<Variables<TagsList>*> result,
102 : const Variables<TagsList>& vars) const {
103 : if (UNLIKELY(result->number_of_grid_points() !=
104 : interpolation_matrix_.rows())) {
105 : *result = Variables<TagsList>(interpolation_matrix_.rows(), 0.);
106 : }
107 : ASSERT(interpolation_matrix_.columns() == vars.number_of_grid_points(),
108 : "Number of grid points in source 'vars', "
109 : << vars.number_of_grid_points()
110 : << ",\n disagrees with the size of the source_mesh, "
111 : << interpolation_matrix_.columns()
112 : << ", that was passed into the constructor");
113 : auto result_span = gsl::make_span(result->data(), result->size());
114 : const auto vars_span = gsl::make_span(vars.data(), vars.size());
115 : interpolate(make_not_null(&result_span), vars_span);
116 : }
117 :
118 : template <size_t Dim>
119 : template <typename TagsList>
120 : Variables<TagsList> Irregular<Dim>::interpolate(
121 : const Variables<TagsList>& vars) const {
122 : Variables<TagsList> result{interpolation_matrix_.rows()};
123 : interpolate(make_not_null(&result), vars);
124 : return result;
125 : }
126 :
127 : template <size_t Dim>
128 0 : bool operator!=(const Irregular<Dim>& lhs, const Irregular<Dim>& rhs);
129 :
130 : } // namespace intrp
|