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 <iosfwd> 8 : #include <optional> 9 : #include <pup.h> 10 : #include <string> 11 : #include <utility> 12 : 13 : #include "DataStructures/DataVector.hpp" 14 : #include "DataStructures/Tensor/Tensor.hpp" 15 : #include "NumericalAlgorithms/Spectral/Mesh.hpp" 16 : #include "Utilities/Gsl.hpp" 17 : #include "Utilities/Serialization/PupStlCpp17.hpp" 18 : 19 : namespace evolution::dg { 20 : /*! 21 : * \brief Data on the mortar used to compute the boundary correction for the 22 : * DG scheme. 23 : * 24 : * The class holds the data that has been projected to one side of the mortar. 25 : * It is meant to be used in a container (either MortarDataHolder or 26 : * TimeSteppers::BoundaryHistory) that holds MortarData on each side of the 27 : * mortar. The data is later used to compute the same unique boundary correction 28 : * on the mortar for both elements. That is, the final boundary correction 29 : * computation is done twice: once on each element touching the mortar. However, 30 : * the computation is done in such a way that the results agree. 31 : * 32 : * For local time stepping, the magnitude of the face normal is stored. 33 : * 34 : * The magnitude of the face normal is given by: 35 : * 36 : * \f{align*}{ 37 : * \sqrt{ 38 : * \frac{\partial\xi}{\partial x^i} \gamma^{ij} 39 : * \frac{\partial\xi}{\partial x^j}} 40 : * \f} 41 : * 42 : * for a face in the \f$\xi\f$-direction, with inverse spatial metric 43 : * \f$\gamma^{ij}\f$. 44 : * 45 : * In addition, for local time stepping with Gauss points, the determinants of 46 : * the volume inverse Jacobian and the face Jacobian are stored. 47 : * 48 : * In addition to the (type-erased) fields on the mortar, the appropriate meshes 49 : * are stored. When setting the mortar data and mortar mesh, the face mesh 50 : * should also be set as it is used when hybridizing DG with finite difference 51 : * or finite volume schemes (DG-subcell). 52 : * 53 : * If the element and its neighbor have unaligned logical coordinate 54 : * systems then the data and meshes are stored in the local logical 55 : * coordinate's orientation (\f$\xi\f$ varies fastest). This means the 56 : * action sending the data is responsible for reorienting the data on 57 : * the mortar so it matches the neighbor's orientation. 58 : * 59 : * \tparam Dim the volume dimension 60 : */ 61 : template <size_t Dim> 62 1 : struct MortarData { 63 0 : std::optional<DataVector> mortar_data{std::nullopt}; 64 0 : std::optional<Scalar<DataVector>> face_normal_magnitude{std::nullopt}; 65 0 : std::optional<Scalar<DataVector>> face_det_jacobian{std::nullopt}; 66 0 : std::optional<Scalar<DataVector>> volume_det_inv_jacobian{std::nullopt}; 67 0 : std::optional<Mesh<Dim - 1>> mortar_mesh{std::nullopt}; 68 0 : std::optional<Mesh<Dim - 1>> face_mesh{std::nullopt}; 69 0 : std::optional<Mesh<Dim>> volume_mesh{std::nullopt}; 70 : 71 : // NOLINTNEXTLINE(google-runtime-references) 72 0 : void pup(PUP::er& p); 73 : }; 74 : 75 : /// \brief Projects the geometric data (but not the data on the mortar 76 : /// grid) when p-refined 77 : /// 78 : /// \details only updates the stored mesh if the corresponding data exists 79 : /// 80 : /// \note The DG-subcell code stores the face mesh in the MortarData even when 81 : /// the geometric data are not used. Currently projection of MortarData is only 82 : /// needed for local time-stepping which is not yet supported for DG-subcell. 83 : /// 84 : /// \returns If the data was modified 85 : template <size_t Dim> 86 1 : bool p_project_geometric_data( 87 : gsl::not_null<::evolution::dg::MortarData<Dim>*> mortar_data, 88 : const Mesh<Dim - 1>& new_face_mesh, const Mesh<Dim>& new_volume_mesh); 89 : 90 : /// \brief Projects the mortar data (but not the geometric data) when p-refined 91 : /// 92 : /// \details Used to re-project mortar data when the mortar mesh changes 93 : /// reactively after the neighbor face mesh is received. In this case, the 94 : /// geometric data does not need to be updated as it already used the correct 95 : /// face/volume mesh. 96 : /// 97 : /// \returns If the data was modified 98 : template <size_t Dim> 99 1 : bool p_project_mortar_data( 100 : gsl::not_null<::evolution::dg::MortarData<Dim>*> mortar_data, 101 : const Mesh<Dim - 1>& new_mortar_mesh); 102 : 103 : template <size_t Dim> 104 0 : bool operator==(const MortarData<Dim>& lhs, const MortarData<Dim>& rhs); 105 : 106 : template <size_t Dim> 107 0 : bool operator!=(const MortarData<Dim>& lhs, const MortarData<Dim>& rhs); 108 : 109 : template <size_t Dim> 110 0 : std::ostream& operator<<(std::ostream& os, const MortarData<Dim>& mortar_data); 111 : } // namespace evolution::dg