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