Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <algorithm>
7 : #include <array>
8 : #include <cstddef>
9 : #include <functional>
10 : #include <tuple>
11 : #include <type_traits>
12 : #include <utility>
13 :
14 : #include "DataStructures/DataBox/PrefixHelpers.hpp"
15 : #include "DataStructures/DataBox/Prefixes.hpp"
16 : #include "DataStructures/Matrix.hpp"
17 : #include "DataStructures/Variables.hpp"
18 : #include "Domain/Structure/Direction.hpp"
19 : #include "Domain/Structure/DirectionalId.hpp"
20 : #include "Domain/Structure/DirectionalIdMap.hpp"
21 : #include "Domain/Structure/ElementId.hpp"
22 : #include "Domain/Structure/SegmentId.hpp"
23 : #include "NumericalAlgorithms/DiscontinuousGalerkin/LiftFlux.hpp"
24 : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
25 : #include "NumericalAlgorithms/Spectral/Projection.hpp"
26 : #include "NumericalAlgorithms/Spectral/SegmentSize.hpp"
27 : #include "Utilities/Algorithm.hpp"
28 : #include "Utilities/ConstantExpressions.hpp"
29 : #include "Utilities/ErrorHandling/Assert.hpp"
30 : #include "Utilities/Gsl.hpp"
31 : #include "Utilities/MakeArray.hpp"
32 : #include "Utilities/TMPL.hpp"
33 : /// \cond
34 : template <size_t VolumeDim>
35 : class ElementId;
36 : template <size_t VolumeDim>
37 : class OrientationMap;
38 :
39 : /// \endcond
40 :
41 : namespace dg {
42 :
43 : template <size_t VolumeDim>
44 0 : using MortarId = DirectionalId<VolumeDim>;
45 : template <size_t MortarDim>
46 0 : using MortarSize = std::array<Spectral::SegmentSize, MortarDim>;
47 : template <size_t VolumeDim, typename ValueType>
48 0 : using MortarMap = DirectionalIdMap<VolumeDim, ValueType>;
49 :
50 : /// \ingroup DiscontinuousGalerkinGroup
51 : /// Find a mesh for a mortar capable of representing data from either
52 : /// of two faces.
53 : ///
54 : /// \warning Make sure the two face meshes are oriented the same, i.e.
55 : /// their dimensions align. This is facilitated by the `orientation`
56 : /// passed to `domain::create_initial_mesh`, for example.
57 : template <size_t Dim>
58 1 : Mesh<Dim> mortar_mesh(const Mesh<Dim>& face_mesh1, const Mesh<Dim>& face_mesh2);
59 :
60 : /// \ingroup DiscontinuousGalerkinGroup
61 : /// Determine the size of the mortar (i.e., the part of the face it
62 : /// covers) for communicating with a neighbor. This is the size
63 : /// relative to the size of \p self, and will not generally agree with
64 : /// that determined by \p neighbor.
65 : template <size_t Dim>
66 1 : MortarSize<Dim - 1> mortar_size(const ElementId<Dim>& self,
67 : const ElementId<Dim>& neighbor,
68 : size_t dimension,
69 : const OrientationMap<Dim>& orientation);
70 :
71 : /// \ingroup DiscontinuousGalerkinGroup
72 : /// Determine the size of the mortar in block coordinates. The
73 : /// segments are given in the block of \p self.
74 : template <size_t Dim>
75 1 : std::array<SegmentId, Dim - 1> mortar_segments(
76 : const ElementId<Dim>& self, const ElementId<Dim>& neighbor,
77 : size_t dimension, const OrientationMap<Dim>& orientation);
78 :
79 : /// @{
80 : /// \ingroup DiscontinuousGalerkinGroup
81 : /// Project variables from a face to a mortar.
82 : template <typename Tags, size_t Dim>
83 1 : void project_to_mortar(const gsl::not_null<Variables<Tags>*> result,
84 : const Variables<Tags>& vars, const Mesh<Dim>& face_mesh,
85 : const Mesh<Dim>& mortar_mesh,
86 : const MortarSize<Dim>& mortar_size) {
87 : Spectral::project(result, vars, face_mesh, mortar_mesh,
88 : make_array<Dim>(Spectral::SegmentSize::Full), mortar_size);
89 : }
90 :
91 : template <typename Tags, size_t Dim>
92 1 : Variables<Tags> project_to_mortar(const Variables<Tags>& vars,
93 : const Mesh<Dim>& face_mesh,
94 : const Mesh<Dim>& mortar_mesh,
95 : const MortarSize<Dim>& mortar_size) {
96 : Variables<Tags> result{mortar_mesh.number_of_grid_points()};
97 : project_to_mortar(make_not_null(&result), vars, face_mesh, mortar_mesh,
98 : mortar_size);
99 : return result;
100 : }
101 : /// @}
102 :
103 : /// @{
104 : /// \ingroup DiscontinuousGalerkinGroup
105 : /// Project variables from a mortar to a face.
106 : template <typename Tags, size_t Dim>
107 1 : void project_from_mortar(const gsl::not_null<Variables<Tags>*> result,
108 : const Variables<Tags>& vars,
109 : const Mesh<Dim>& face_mesh,
110 : const Mesh<Dim>& mortar_mesh,
111 : const MortarSize<Dim>& mortar_size) {
112 : ASSERT(Spectral::needs_projection(face_mesh, mortar_mesh, mortar_size),
113 : "project_from_mortar should not be called if the interface mesh and "
114 : "mortar mesh are identical. Please elide the copy instead.");
115 : Spectral::project(result, vars, mortar_mesh, face_mesh, mortar_size,
116 : make_array<Dim>(Spectral::SegmentSize::Full));
117 : }
118 :
119 : template <typename Tags, size_t Dim>
120 1 : Variables<Tags> project_from_mortar(const Variables<Tags>& vars,
121 : const Mesh<Dim>& face_mesh,
122 : const Mesh<Dim>& mortar_mesh,
123 : const MortarSize<Dim>& mortar_size) {
124 : ASSERT(Spectral::needs_projection(face_mesh, mortar_mesh, mortar_size),
125 : "project_from_mortar should not be called if the interface mesh and "
126 : "mortar mesh are identical. Please elide the copy instead.");
127 : Variables<Tags> result{face_mesh.number_of_grid_points()};
128 : project_from_mortar(make_not_null(&result), vars, face_mesh, mortar_mesh,
129 : mortar_size);
130 : return result;
131 : }
132 : /// @}
133 : } // namespace dg
|