Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 : #include <vector>
8 :
9 : #include "Domain/Structure/DirectionalId.hpp"
10 : #include "Domain/Structure/ElementId.hpp"
11 : #include "NumericalAlgorithms/Interpolation/IrregularInterpolant.hpp"
12 : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
13 :
14 : /// \cond
15 : template <size_t Dim>
16 : class Domain;
17 : class DataVector;
18 : namespace gsl {
19 : template <typename T>
20 : class not_null;
21 : } // namespace gsl
22 : /// \endcond
23 :
24 : namespace dg {
25 : /// \brief Interpolator to be used for interpolating boundary data from (to) a
26 : /// Neighbor onto a mortar between nonconforming Blocks.
27 : ///
28 : /// \details This interpolator is designed to be used when multiple
29 : /// nonconforming elements are neighbors with a single element (e.g deformed
30 : /// cubes of a cubed sphere next to a single S2 spherical shell). Each of the
31 : /// multiple elements (the hosts) should create this class to both interpolate
32 : /// neighbor boundary data to the mortar of the host as well as interpolate the
33 : /// host boundary data onto the subset of points of the mortar of the neighbor.
34 : ///
35 : /// \note For nonconforming neighbors, the block logical coordinates of
36 : /// neighboring elements are not related by a discrete rotation (i.e. an
37 : /// OrientationMap). Therefore boundary data cannot be copied or projected to a
38 : /// neighbor, but must be interpolated. As nonconforming neighbors cannot exist
39 : /// in one dimension, this class is not instantiated for Dim = 1.
40 : template <size_t Dim>
41 1 : class MortarInterpolator {
42 : public:
43 : /// The Element with host_id is one of the multiple nonconforming Elements
44 : /// abutting the single Element with neighbor_id. The host_mortar_mesh and
45 : /// neighbor_mortar_mesh are simply the appropriate face Mesh of the host and
46 : /// neighbor.
47 1 : MortarInterpolator(const ElementId<Dim>& host_id,
48 : const DirectionalId<Dim>& neighbor_id,
49 : const Domain<Dim>& domain,
50 : const Mesh<Dim - 1>& host_mortar_mesh,
51 : const Mesh<Dim - 1>& neighbor_mortar_mesh);
52 :
53 0 : MortarInterpolator() = default;
54 :
55 : /// @{
56 : /// \brief Interpolates the boundary data of the neighbor to the host mortar
57 : ///
58 : /// \details neighbor_data is a type-erased Variables so will have a size
59 : /// equal to the product of the number of components and the number of grid
60 : /// points of the neighbor_mortar_mesh. The returned DataVector will have a
61 : /// size equal to the number of components and the number of grid points of
62 : /// the host_mortar_mesh.
63 1 : void interpolate_to_host(gsl::not_null<DataVector*> result,
64 : const DataVector& neighbor_data) const;
65 1 : DataVector interpolate_to_host(const DataVector& neighbor_data) const;
66 : /// @}
67 :
68 : /// @{
69 : /// \brief Interpolates the boundary data of the host to a subset of the
70 : /// points of the neighbor mortar
71 : ///
72 : /// \details host_data is a type-erased Variables so will have a size
73 : /// equal to the product of the number of components and the number of grid
74 : /// points of the host_mortar_mesh. The returned DataVector will have a
75 : /// size equal to the number of components and the number of grid points of
76 : /// the neighbor_mortar_mesh that the host is able to interpolate to.
77 1 : void interpolate_to_neighbor(gsl::not_null<DataVector*> result,
78 : const DataVector& host_data) const;
79 1 : DataVector interpolate_to_neighbor(const DataVector& host_data) const;
80 : /// @}
81 :
82 : /// \brief The offsets of the data returned by interpolate_to_neighbor into
83 : /// the full data on the neighbor_mortar_mesh.
84 : ///
85 : /// \details The DataVectors of type-erased Variables store data such that
86 : /// the grid point index varies fastest (as opposed to the component index).
87 : /// The size of the returned vector is equal to the number of grid points of
88 : /// the neighbor_mortar_mesh that the host is able to interpolate to, and the
89 : /// values of the returned vector map the grid point index of the partial
90 : /// DataVector returned by interpolate_to_neighbor to the grid point index of
91 : /// the full DataVector on the neighbor_mortar_mesh
92 1 : const std::vector<size_t>& interpolated_neighbor_data_offsets() const {
93 : return interpolated_neighbor_data_offsets_;
94 : }
95 :
96 : /// \brief The neighbor mortar mesh that is used to compute the target points
97 : /// and offsets when interpolating to the neighbor
98 1 : const Mesh<Dim - 1>& neighbor_mortar_mesh() const {
99 : return neighbor_mortar_mesh_;
100 : }
101 :
102 : /// \brief Updates the interpolator if either of the mortar Mesh change
103 1 : void reset_if_necessary(const Domain<Dim>& domain,
104 : const Mesh<Dim - 1>& host_mortar_mesh,
105 : const Mesh<Dim - 1>& neighbor_mortar_mesh);
106 :
107 : // NOLINTNEXTLINE(google-runtime-references)
108 0 : void pup(PUP::er& p);
109 :
110 : private:
111 : template <size_t LocalDim>
112 0 : friend bool operator==(const MortarInterpolator<LocalDim>& lhs,
113 : const MortarInterpolator<LocalDim>& rhs);
114 :
115 0 : ElementId<Dim> host_id_{};
116 0 : DirectionalId<Dim> neighbor_id_{};
117 0 : Mesh<Dim - 1> host_mortar_mesh_{};
118 0 : Mesh<Dim - 1> neighbor_mortar_mesh_{};
119 0 : intrp::Irregular<Dim - 1> neighbor_to_host_interpolant_{};
120 0 : intrp::Irregular<Dim - 1> host_to_neighbor_interpolant_{};
121 0 : std::vector<size_t> interpolated_neighbor_data_offsets_{};
122 : };
123 :
124 : template <>
125 0 : class MortarInterpolator<1> {
126 : public: // NOLINTNEXTLINE(google-runtime-references)
127 0 : void pup(PUP::er& /*unused*/) {}
128 : };
129 :
130 : template <size_t Dim>
131 0 : bool operator==(const MortarInterpolator<Dim>& lhs,
132 : const MortarInterpolator<Dim>& rhs);
133 :
134 : template <>
135 0 : inline bool operator==(const MortarInterpolator<1>& /*unused*/,
136 : const MortarInterpolator<1>& /*unused*/) {
137 : return true;
138 : }
139 : } // namespace dg
|