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 0 : Irregular(); 43 : 44 : /// Serialization for Charm++ 45 : // NOLINTNEXTLINE(google-runtime-references) 46 1 : void pup(PUP::er& p); 47 : 48 : /// @{ 49 : /// Performs the interpolation on a `Variables` with grid points corresponding 50 : /// to the `Mesh<Dim>` specified in the constructor. 51 : /// The result is a `Variables` whose internal `DataVector` goes over the 52 : /// list of target_points that were specified in the constructor. 53 : /// \note for the void function, `result` will be resized to the proper size. 54 : template <typename TagsList> 55 1 : void interpolate(gsl::not_null<Variables<TagsList>*> result, 56 : const Variables<TagsList>& vars) const; 57 : template <typename TagsList> 58 1 : Variables<TagsList> interpolate(const Variables<TagsList>& vars) const; 59 : /// @} 60 : 61 : /// @{ 62 : /// \brief Interpolate a DataVector or ComplexDataVector onto the target 63 : /// points. 64 : /// 65 : /// \note When interpolating multiple tensors, the Variables interface is more 66 : /// efficient. However, this DataVector interface is useful for applications 67 : /// where only some components of a Tensor or Variables need to be 68 : /// interpolated. 69 1 : void interpolate(gsl::not_null<DataVector*> result, 70 : const DataVector& input) const; 71 1 : DataVector interpolate(const DataVector& input) const; 72 1 : void interpolate(gsl::not_null<ComplexDataVector*> result, 73 : const ComplexDataVector& input) const; 74 1 : ComplexDataVector interpolate(const ComplexDataVector& input) const; 75 : /// @} 76 : 77 : /// \brief Interpolate multiple variables on the grid to the target points. 78 : /// @{ 79 1 : void interpolate(gsl::not_null<gsl::span<double>*> result, 80 : const gsl::span<const double>& input) const; 81 1 : void interpolate(gsl::not_null<gsl::span<std::complex<double>>*> result, 82 : const gsl::span<const std::complex<double>>& input) const; 83 : /// @} 84 : 85 : private: 86 0 : friend bool operator==(const Irregular& lhs, const Irregular& rhs) { 87 : return lhs.interpolation_matrix_ == rhs.interpolation_matrix_; 88 : } 89 0 : Matrix interpolation_matrix_; 90 : }; 91 : 92 : template <size_t Dim> 93 : template <typename TagsList> 94 0 : void Irregular<Dim>::interpolate( 95 : const gsl::not_null<Variables<TagsList>*> result, 96 : const Variables<TagsList>& vars) const { 97 : if (UNLIKELY(result->number_of_grid_points() != 98 : interpolation_matrix_.rows())) { 99 : *result = Variables<TagsList>(interpolation_matrix_.rows(), 0.); 100 : } 101 : ASSERT(interpolation_matrix_.columns() == vars.number_of_grid_points(), 102 : "Number of grid points in source 'vars', " 103 : << vars.number_of_grid_points() 104 : << ",\n disagrees with the size of the source_mesh, " 105 : << interpolation_matrix_.columns() 106 : << ", that was passed into the constructor"); 107 : auto result_span = gsl::make_span(result->data(), result->size()); 108 : const auto vars_span = gsl::make_span(vars.data(), vars.size()); 109 : interpolate(make_not_null(&result_span), vars_span); 110 : } 111 : 112 : template <size_t Dim> 113 : template <typename TagsList> 114 : Variables<TagsList> Irregular<Dim>::interpolate( 115 : const Variables<TagsList>& vars) const { 116 : Variables<TagsList> result{interpolation_matrix_.rows()}; 117 : interpolate(make_not_null(&result), vars); 118 : return result; 119 : } 120 : 121 : template <size_t Dim> 122 0 : bool operator!=(const Irregular<Dim>& lhs, const Irregular<Dim>& rhs); 123 : 124 : } // namespace intrp