SpECTRE Documentation Coverage Report
Current view: top level - Evolution/DiscontinuousGalerkin - MortarData.hpp Hit Total Coverage
Commit: d0fc80462417e83e5cddfa1b9901bb4a9b6af4d6 Lines: 12 34 35.3 %
Date: 2024-03-29 00:33:31
Legend: Lines: hit not hit

          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/TypeAliases.hpp"
      15             : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
      16             : #include "Time/TimeStepId.hpp"
      17             : #include "Utilities/Gsl.hpp"
      18             : #include "Utilities/Serialization/PupStlCpp17.hpp"
      19             : 
      20             : namespace evolution::dg {
      21             : /*!
      22             :  * \brief Data on the mortar used to compute the boundary correction for the
      23             :  * DG scheme.
      24             :  *
      25             :  * The class holds the local data that has been projected to the mortar as well
      26             :  * as the neighbor data that has been projected to the mortar. The local and
      27             :  * neighbor data is later used to compute the same unique boundary correction on
      28             :  * 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             :  * In addition to the (type-erased) fields on both sides of the mortar, the face
      33             :  * (not mortar!) mesh of the neighbor is stored. The mesh will be necessary
      34             :  * when hybridizing DG with finite difference or finite volume schemes
      35             :  * (DG-subcell).
      36             :  *
      37             :  * If the element and its neighbor have unaligned logical coordinate systems
      38             :  * then the data is stored in the local logical coordinate's orientation
      39             :  * (\f$\xi\f$ varies fastest). This means the action sending the data is
      40             :  * responsible for reorienting the data on the mortar so it matches the
      41             :  * neighbor's orientation.
      42             :  *
      43             :  * \tparam Dim the volume dimension of the mesh
      44             :  */
      45             : template <size_t Dim>
      46           1 : class MortarData {
      47           0 :   using MortarType = std::optional<std::pair<Mesh<Dim - 1>, DataVector>>;
      48             : 
      49             :  public:
      50           0 :   MortarData(size_t number_of_buffers = 1);
      51             : 
      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           1 :   void insert_local_mortar_data(TimeStepId time_step_id,
      71             :                                 Mesh<Dim - 1> local_interface_mesh,
      72             :                                 DataVector local_mortar_vars);
      73           1 :   void insert_neighbor_mortar_data(TimeStepId time_step_id,
      74             :                                    Mesh<Dim - 1> neighbor_interface_mesh,
      75             :                                    DataVector neighbor_mortar_vars);
      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             :    */
      94           1 :   void insert_local_geometric_quantities(
      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);
      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             :    */
     114           1 :   void insert_local_face_normal_magnitude(
     115             :       const Scalar<DataVector>& local_face_normal_magnitude);
     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             :    */
     123           1 :   void get_local_volume_det_inv_jacobian(
     124             :       gsl::not_null<Scalar<DataVector>*> local_volume_det_inv_jacobian) const;
     125             : 
     126             :   /*!
     127             :    * \brief Sets the `local_face_det_jacobian` by setting the DataVector to
     128             :    * point into the `MortarData`'s internal storage.
     129             :    *
     130             :    * \warning The result should never be changed.
     131             :    */
     132           1 :   void get_local_face_det_jacobian(
     133             :       gsl::not_null<Scalar<DataVector>*> local_face_det_jacobian) const;
     134             : 
     135             :   /*!
     136             :    * \brief Sets the `local_face_normal_magnitude` by setting the DataVector to
     137             :    * point into the `MortarData`'s internal storage.
     138             :    *
     139             :    * \warning The result should never be changed.
     140             :    */
     141           1 :   void get_local_face_normal_magnitude(
     142             :       gsl::not_null<Scalar<DataVector>*> local_face_normal_magnitude) const;
     143             : 
     144             :   /// Return the inserted data and reset the state to empty.
     145             :   ///
     146             :   /// The first element is the local data while the second element is the
     147             :   /// neighbor data.
     148           1 :   auto extract() -> std::pair<std::pair<Mesh<Dim - 1>, DataVector>,
     149             :                               std::pair<Mesh<Dim - 1>, DataVector>>;
     150             : 
     151             :   /// Move to the next internal mortar buffer
     152           1 :   void next_buffer();
     153             : 
     154             :   /// Return the current internal mortar index
     155           1 :   size_t current_buffer_index() const;
     156             : 
     157             :   /// Return the total number of buffers that this MortarData was constructed
     158             :   /// with
     159           1 :   size_t total_number_of_buffers() const;
     160             : 
     161           0 :   const TimeStepId& time_step_id() const {
     162             :     return time_step_id_[mortar_index_];
     163             :   }
     164             : 
     165           0 :   TimeStepId& time_step_id() { return time_step_id_[mortar_index_]; }
     166             : 
     167           0 :   auto local_mortar_data() const
     168             :       -> const std::optional<std::pair<Mesh<Dim - 1>, DataVector>>& {
     169             :     return local_mortar_data_[mortar_index_];
     170             :   }
     171             : 
     172           0 :   auto neighbor_mortar_data() const
     173             :       -> const std::optional<std::pair<Mesh<Dim - 1>, DataVector>>& {
     174             :     return neighbor_mortar_data_[mortar_index_];
     175             :   }
     176             : 
     177           0 :   auto local_mortar_data()
     178             :       -> std::optional<std::pair<Mesh<Dim - 1>, DataVector>>& {
     179             :     return local_mortar_data_[mortar_index_];
     180             :   }
     181             : 
     182           0 :   auto neighbor_mortar_data()
     183             :       -> std::optional<std::pair<Mesh<Dim - 1>, DataVector>>& {
     184             :     return neighbor_mortar_data_[mortar_index_];
     185             :   }
     186             : 
     187             :   // NOLINTNEXTLINE(google-runtime-references)
     188           0 :   void pup(PUP::er& p);
     189             : 
     190           0 :   std::string pretty_print_current_buffer_no_data(size_t padding_size) const;
     191             : 
     192             :  private:
     193             :   template <size_t LocalDim>
     194             :   // NOLINTNEXTLINE
     195           0 :   friend bool operator==(const MortarData<LocalDim>& lhs,
     196             :                          const MortarData<LocalDim>& rhs);
     197             : 
     198           0 :   size_t number_of_buffers_{1};
     199           0 :   std::vector<TimeStepId> time_step_id_{};
     200           0 :   std::vector<MortarType> local_mortar_data_{};
     201           0 :   std::vector<MortarType> neighbor_mortar_data_{};
     202           0 :   size_t mortar_index_{0};
     203           0 :   DataVector local_geometric_quantities_{};
     204           0 :   bool using_volume_and_face_jacobians_{false};
     205           0 :   bool using_only_face_normal_magnitude_{false};
     206             : };
     207             : 
     208             : template <size_t Dim>
     209           0 : bool operator!=(const MortarData<Dim>& lhs, const MortarData<Dim>& rhs);
     210             : 
     211             : template <size_t Dim>
     212           0 : std::ostream& operator<<(std::ostream& os, const MortarData<Dim>& mortar_data);
     213             : }  // namespace evolution::dg

Generated by: LCOV version 1.14