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
|