Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <array>
7 : #include <cstddef>
8 : #include <optional>
9 :
10 : #include "DataStructures/Matrix.hpp"
11 : #include "DataStructures/Tensor/IndexType.hpp"
12 : #include "DataStructures/Tensor/TypeAliases.hpp"
13 : #include "NumericalAlgorithms/SphericalHarmonics/Spherepack.hpp"
14 : #include "Utilities/Gsl.hpp"
15 :
16 : /// \cond
17 : class DataVector;
18 : template <size_t Dim>
19 : class Mesh;
20 : namespace PUP {
21 : class er;
22 : } // namespace PUP
23 : /// \endcond
24 :
25 : namespace intrp {
26 : /*!
27 : * \brief Interpolates by doing partial summation in each dimension using
28 : * one-dimensional interpolation
29 : *
30 : * \details The one-dimensional matrices used to do the interpolation depend
31 : * upon the Spectral::Basis used in each dimension:
32 : * - For a Chebyshev or Legendre basis, the matrices are given by
33 : * Spectral::fornberg_interpolation_matrix at the quadrature points of the
34 : * source_mesh. (These are equivalent to those returned by
35 : * Spectral::interpolation_matrix.)
36 : * - For a Fourier basis, the matrix is given by
37 : * Spectral::fourier_interpolation_matrix at the quadrature points of the
38 : * source_mesh
39 : *
40 : * For multidimensional bases such as SphericalHarmonic, ZernikeB2, or
41 : * ZernikeB3, the matrices used for interpolating cannot be applied per
42 : * dimension but must be handled specially.
43 : *
44 : */
45 : template <size_t Dim>
46 1 : class Cardinal {
47 : public:
48 0 : Cardinal(
49 : const Mesh<Dim>& source_mesh,
50 : const tnsr::I<DataVector, Dim, Frame::ElementLogical>& target_points);
51 0 : Cardinal(const Mesh<Dim>& source_mesh,
52 : const tnsr::I<double, Dim, Frame::ElementLogical>& target_point);
53 :
54 0 : Cardinal();
55 :
56 : /// Interpolates the function `f` provided on the `source_mesh` to the
57 : /// `target_points` with which the interpolator was constructed.
58 1 : DataVector interpolate(const DataVector& f) const;
59 :
60 : /// The one-dimensional interpolation matrices used to do the interpolation
61 1 : const std::array<Matrix, Dim>& interpolation_matrices() const;
62 :
63 : // NOLINTNEXTLINE(google-runtime-references)
64 0 : void pup(PUP::er& p);
65 :
66 : /// Logic for `set_zernike_b2_weights()`. Also used by IrregularInterpolant.
67 1 : static void compute_zernike_b2_weights(
68 : gsl::not_null<Matrix*> weights, const Mesh<Dim>& source_mesh,
69 : const std::array<Matrix, Dim>& interpolation_matrices,
70 : size_t n_target_points);
71 :
72 : /// Logic for `set_zernike_b3_weights()`. Also used by IrregularInterpolant.
73 1 : static void compute_zernike_b3_weights(
74 : gsl::not_null<Matrix*> weights, const Mesh<Dim>& source_mesh,
75 : const tnsr::I<DataVector, Dim, Frame::ElementLogical>& target_points,
76 : const ylm::Spherepack& b3_ylm, size_t n_target_points);
77 :
78 : private:
79 : /// Precomputes `zernike_b2_weights_`, which is all work independent of
80 : /// `f_source`, to avoid redundant computations. This is only needed when
81 : /// the source mesh has a B2 basis
82 1 : void set_zernike_b2_weights();
83 :
84 : /// General routine called by `interpolate()` for a mesh using B2 bases
85 1 : DataVector interpolate_zernike_b2(const DataVector& f_source) const;
86 :
87 : /// Precomputes `zernike_b3_weights_`, which is all work independent of
88 : /// `f_source`, to avoid redundant computations. This is only needed when
89 : /// the source mesh has a B3 basis
90 1 : void set_zernike_b3_weights();
91 :
92 : /// General routine called by `interpolate()` for a mesh using B3 bases
93 1 : DataVector interpolate_zernike_b3(const DataVector& f_source) const;
94 :
95 : template <size_t LocalDim>
96 : // NOLINTNEXTILNE(readability-redundant-declaration)
97 0 : friend bool operator==(const Cardinal<LocalDim>& lhs,
98 : const Cardinal<LocalDim>& rhs);
99 :
100 0 : size_t n_target_points_ = 0;
101 : // Only required by B3 weights
102 : std::optional<tnsr::I<DataVector, Dim, Frame::ElementLogical>>
103 0 : target_points_{};
104 0 : Mesh<Dim> source_mesh_{};
105 0 : std::array<Matrix, Dim> interpolation_matrices_{};
106 0 : bool using_spherical_harmonics_{false};
107 0 : bool using_zernike_b2_{false};
108 0 : Matrix zernike_b2_weights_{};
109 0 : bool using_zernike_b3_{false};
110 0 : Matrix zernike_b3_weights_{};
111 0 : std::optional<ylm::Spherepack> b3_ylm_{};
112 : };
113 :
114 : template <size_t Dim>
115 0 : bool operator==(const Cardinal<Dim>& lhs, const Cardinal<Dim>& rhs);
116 :
117 : template <size_t Dim>
118 0 : bool operator!=(const Cardinal<Dim>& lhs, const Cardinal<Dim>& rhs);
119 : } // namespace intrp
|