MortarData.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 #include <optional>
8 #include <ostream>
9 #include <pup.h>
10 #include <utility>
11 #include <vector>
12 
15 #include "Parallel/PupStlCpp17.hpp"
16 #include "Time/TimeStepId.hpp"
18 #include "Utilities/Gsl.hpp"
19 
20 /// \cond
21 class DataVector;
22 /// \endcond
23 
24 namespace evolution::dg {
25 /*!
26  * \brief Data on the mortar used to compute the boundary correction for the
27  * DG scheme.
28  *
29  * The class holds the local data that has been projected to the mortar as well
30  * as the neighbor data that has been projected to the mortar. The local and
31  * neighbor data is later used to compute the same unique boundary correction on
32  * the mortar for both elements. That is, the final boundary correction
33  * computation is done twice: once on each element touching the mortar. However,
34  * the computation is done in such a way that the results agree.
35  *
36  * In addition to the (type-erased) fields on both sides of the mortar, the face
37  * (not mortar!) mesh of the neighbor is stored. The mesh will be necessary
38  * when hybridizing DG with finite difference or finite volume schemes
39  * (DG-subcell).
40  *
41  * If the element and its neighbor have unaligned logical coordinate systems
42  * then the data is stored in the local logical coordinate's orientation
43  * (\f$\xi\f$ varies fastest). This means the action sending the data is
44  * responsible for reorienting the data on the mortar so it matches the
45  * neighbor's orientation.
46  *
47  * \tparam Dim the volume dimension of the mesh
48  */
49 template <size_t Dim>
50 class MortarData {
51  public:
52  /*!
53  * \brief Insert data onto the mortar.
54  *
55  * Exactly one local and neighbor insert call must be made between calls to
56  * `extract()`.
57  *
58  * The insert functions require that:
59  * - the data is inserted only once
60  * - the `TimeStepId` of the local and neighbor data are the same (this is
61  * only checked if the local/neighbor data was already inserted)
62  *
63  * \note it is not required that the number of grid points between the local
64  * and neighbor data be the same since one may be using FD/FV instead of DG
65  * and this switch is done locally in space and time in such a way that
66  * neighboring elements have no a priori knowledge about what well be
67  * received.
68  */
69  /// @{
70  void insert_local_mortar_data(TimeStepId time_step_id,
71  Mesh<Dim - 1> local_interface_mesh,
72  std::vector<double> local_mortar_vars) noexcept;
74  TimeStepId time_step_id, Mesh<Dim - 1> neighbor_interface_mesh,
75  std::vector<double> neighbor_mortar_vars) noexcept;
76  /// @}
77 
78  /*!
79  * \brief Insert the magnitude of the local face normal, the determinant
80  * of the volume inverse Jacobian, and the determinant of the face Jacobian.
81  * Used for local time stepping with Gauss points.
82  *
83  * The magnitude of the face normal is given by:
84  *
85  * \f{align*}{
86  * \sqrt{
87  * \frac{\partial\xi}{\partial x^i} \gamma^{ij}
88  * \frac{\partial\xi}{\partial x^j}}
89  * \f}
90  *
91  * for a face in the \f$\xi\f$-direction, with inverse spatial metric
92  * \f$\gamma^{ij}\f$.
93  */
95  const Scalar<DataVector>& local_volume_det_inv_jacobian,
96  const Scalar<DataVector>& local_face_det_jacobian,
97  const Scalar<DataVector>& local_face_normal_magnitude) noexcept;
98 
99  /*!
100  * \brief Insert the magnitude of the local face normal. Used for local time
101  * stepping with Gauss-Lobatto points.
102  *
103  * The magnitude of the face normal is given by:
104  *
105  * \f{align*}{
106  * \sqrt{
107  * \frac{\partial\xi}{\partial x^i} \gamma^{ij}
108  * \frac{\partial\xi}{\partial x^j}}
109  * \f}
110  *
111  * for a face in the \f$\xi\f$-direction, with inverse spatial metric
112  * \f$\gamma^{ij}\f$.
113  */
115  const Scalar<DataVector>& local_face_normal_magnitude) noexcept;
116 
117  /*!
118  * \brief Sets the `local_volume_det_inv_jacobian` by setting the DataVector
119  * to point into the `MortarData`'s internal storage.
120  *
121  * \warning The result should never be changed.
122  */
124  gsl::not_null<Scalar<DataVector>*> local_volume_det_inv_jacobian)
125  const noexcept;
126 
127  /*!
128  * \brief Sets the `local_face_det_jacobian` by setting the DataVector to
129  * point into the `MortarData`'s internal storage.
130  *
131  * \warning The result should never be changed.
132  */
134  local_face_det_jacobian) const noexcept;
135 
136  /*!
137  * \brief Sets the `local_face_normal_magnitude` by setting the DataVector to
138  * point into the `MortarData`'s internal storage.
139  *
140  * \warning The result should never be changed.
141  */
143  gsl::not_null<Scalar<DataVector>*> local_face_normal_magnitude)
144  const noexcept;
145 
146  /// Return the inserted data and reset the state to empty.
147  ///
148  /// The first element is the local data while the second element is the
149  /// neighbor data.
150  auto extract() noexcept
152  std::pair<Mesh<Dim - 1>, std::vector<double>>>;
153 
154  const TimeStepId& time_step_id() const noexcept { return time_step_id_; }
155 
156  auto local_mortar_data() const noexcept
157  -> const std::optional<std::pair<Mesh<Dim - 1>, std::vector<double>>>& {
158  return local_mortar_data_;
159  }
160 
161  auto neighbor_mortar_data() const noexcept
162  -> const std::optional<std::pair<Mesh<Dim - 1>, std::vector<double>>>& {
163  return neighbor_mortar_data_;
164  }
165 
166  // clang-tidy: google-runtime-references
167  void pup(PUP::er& p) noexcept; // NOLINT
168 
169  private:
170  template <size_t LocalDim>
171  // NOLINTNEXTLINE
172  friend bool operator==(const MortarData<LocalDim>& lhs,
173  const MortarData<LocalDim>& rhs) noexcept;
174 
175  TimeStepId time_step_id_{};
177  local_mortar_data_{};
179  neighbor_mortar_data_{};
180  std::vector<double> local_geometric_quantities_{};
181  bool using_volume_and_face_jacobians_{false};
182  bool using_only_face_normal_magnitude_{false};
183 };
184 
185 template <size_t Dim>
186 bool operator!=(const MortarData<Dim>& lhs,
187  const MortarData<Dim>& rhs) noexcept;
188 } // namespace evolution::dg
evolution::dg::MortarData::insert_local_mortar_data
void insert_local_mortar_data(TimeStepId time_step_id, Mesh< Dim - 1 > local_interface_mesh, std::vector< double > local_mortar_vars) noexcept
Insert data onto the mortar.
utility
std::pair
evolution::dg
Functionality for evolving hyperbolic partial differential equations using the discontinuous Galerkin...
Definition: ConservativeDuDt.hpp:22
evolution::dg::MortarData::get_local_volume_det_inv_jacobian
void get_local_volume_det_inv_jacobian(gsl::not_null< Scalar< DataVector > * > local_volume_det_inv_jacobian) const noexcept
Sets the local_volume_det_inv_jacobian by setting the DataVector to point into the MortarData's inter...
vector
evolution::dg::MortarData::get_local_face_det_jacobian
void get_local_face_det_jacobian(gsl::not_null< Scalar< DataVector > * > local_face_det_jacobian) const noexcept
Sets the local_face_det_jacobian by setting the DataVector to point into the MortarData's internal st...
evolution::dg::MortarData
Data on the mortar used to compute the boundary correction for the DG scheme.
Definition: MortarData.hpp:50
cstddef
Assert.hpp
evolution::dg::MortarData::insert_local_geometric_quantities
void insert_local_geometric_quantities(const Scalar< DataVector > &local_volume_det_inv_jacobian, const Scalar< DataVector > &local_face_det_jacobian, const Scalar< DataVector > &local_face_normal_magnitude) noexcept
Insert the magnitude of the local face normal, the determinant of the volume inverse Jacobian,...
evolution::dg::MortarData::insert_local_face_normal_magnitude
void insert_local_face_normal_magnitude(const Scalar< DataVector > &local_face_normal_magnitude) noexcept
Insert the magnitude of the local face normal. Used for local time stepping with Gauss-Lobatto points...
evolution::dg::MortarData::get_local_face_normal_magnitude
void get_local_face_normal_magnitude(gsl::not_null< Scalar< DataVector > * > local_face_normal_magnitude) const noexcept
Sets the local_face_normal_magnitude by setting the DataVector to point into the MortarData's interna...
DataVector
Stores a collection of function values.
Definition: DataVector.hpp:46
TimeStepId
Definition: TimeStepId.hpp:25
Mesh
Holds the number of grid points, basis, and quadrature in each direction of the computational grid.
Definition: Mesh.hpp:49
TimeStepId.hpp
Scalar
Tensor< T, Symmetry<>, index_list<> > Scalar
Definition: TypeAliases.hpp:21
Gsl.hpp
evolution::dg::MortarData::insert_neighbor_mortar_data
void insert_neighbor_mortar_data(TimeStepId time_step_id, Mesh< Dim - 1 > neighbor_interface_mesh, std::vector< double > neighbor_mortar_vars) noexcept
Insert data onto the mortar.
TypeAliases.hpp
optional
evolution::dg::MortarData::extract
auto extract() noexcept -> std::pair< std::pair< Mesh< Dim - 1 >, std::vector< double >>, std::pair< Mesh< Dim - 1 >, std::vector< double >>>
Return the inserted data and reset the state to empty.
ostream
Mesh.hpp
gsl::not_null
Require a pointer to not be a nullptr
Definition: ReadSpecPiecewisePolynomial.hpp:13