SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/DiscontinuousGalerkin - ApplyMassMatrix.hpp Hit Total Coverage
Commit: 361cb8d8406bb752684a5f31c27320ec444a50e3 Lines: 5 6 83.3 %
Date: 2025-11-09 02:02:04
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             : 
       8             : #include "DataStructures/Variables.hpp"
       9             : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
      10             : #include "Utilities/ErrorHandling/Assert.hpp"
      11             : #include "Utilities/Gsl.hpp"
      12             : 
      13           1 : namespace dg {
      14             : 
      15             : namespace detail {
      16             : template <typename ValueType, size_t Dim>
      17             : void apply_mass_matrix_impl(gsl::not_null<ValueType*> data,
      18             :                             const Mesh<Dim>& mesh);
      19             : template <typename ValueType, size_t Dim>
      20             : void apply_inverse_mass_matrix_impl(gsl::not_null<ValueType*> data,
      21             :                                     const Mesh<Dim>& mesh);
      22             : }  // namespace detail
      23             : 
      24             : /*!
      25             :  * \brief Apply the DG mass matrix to the data, in the diagonal mass-matrix
      26             :  * approximation ("mass-lumping")
      27             :  *
      28             :  * The DG mass matrix is:
      29             :  *
      30             :  * \f{equation}
      31             :  * M_{pq} = \int_{\Omega_k} \psi_p(\xi) \psi_q(\xi) \mathrm{d}V
      32             :  * \f}
      33             :  *
      34             :  * where \f$\psi_p(\xi)\f$ are the basis functions on the element
      35             :  * \f$\Omega_k\f$. In the diagonal mass-matrix approximation ("mass-lumping") we
      36             :  * evaluate the integral directly on the collocation points, i.e. with a Gauss
      37             :  * or Gauss-Lobatto quadrature determined by the element mesh. Then it reduces
      38             :  * to:
      39             :  *
      40             :  * \f{equation}
      41             :  * M_{pq} \approx \delta_{pq} \prod_{i=1}^d w_{p_i}
      42             :  * \f}
      43             :  *
      44             :  * where \f$d\f$ is the spatial dimension and \f$w_{p_i}\f$ are the quadrature
      45             :  * weights in dimension \f$i\f$. To apply the mass matrix in coordinates
      46             :  * different than logical, or to account for a curved background metric, the
      47             :  * data can be pre-multiplied with the Jacobian determinant and/or a metric
      48             :  * determinant.
      49             :  *
      50             :  * \note The mass-lumping is exact on Legendre-Gauss meshes, but omits a
      51             :  * correction term on Legendre-Gauss-Lobatto meshes.
      52             :  */
      53             : /// @{
      54             : template <typename DataType, size_t Dim>
      55           1 : void apply_mass_matrix(const gsl::not_null<DataType*> data,
      56             :                        const Mesh<Dim>& mesh) {
      57             :   ASSERT(data->size() == mesh.number_of_grid_points(),
      58             :          "The data has size " << data->size() << ", but expected size "
      59             :                               << mesh.number_of_grid_points()
      60             :                               << " on the given mesh.");
      61             :   detail::apply_mass_matrix_impl(make_not_null(data->data()), mesh);
      62             : }
      63             : 
      64             : template <size_t Dim, typename TagsList>
      65           1 : void apply_mass_matrix(const gsl::not_null<Variables<TagsList>*> data,
      66             :                        const Mesh<Dim>& mesh) {
      67             :   const size_t num_points = data->number_of_grid_points();
      68             :   ASSERT(num_points == mesh.number_of_grid_points(),
      69             :          "The Variables data has "
      70             :              << num_points << " grid points, but expected "
      71             :              << mesh.number_of_grid_points() << " on the given mesh.");
      72             :   constexpr size_t num_comps =
      73             :       Variables<TagsList>::number_of_independent_components;
      74             :   for (size_t i = 0; i < num_comps; ++i) {
      75             :     detail::apply_mass_matrix_impl(make_not_null(data->data() + i * num_points),
      76             :                                    mesh);
      77             :   }
      78             : }
      79             : /// @}
      80             : 
      81             : /*!
      82             :  * \brief Apply the inverse DG mass matrix to the data
      83             :  *
      84             :  * \see dg::apply_mass_matrix
      85             :  */
      86             : /// @{
      87             : template <typename DataType, size_t Dim>
      88           1 : void apply_inverse_mass_matrix(const gsl::not_null<DataType*> data,
      89             :                                const Mesh<Dim>& mesh) {
      90             :   ASSERT(data->size() == mesh.number_of_grid_points(),
      91             :          "The data has size " << data->size() << ", but expected size "
      92             :                               << mesh.number_of_grid_points()
      93             :                               << " on the given mesh.");
      94             :   detail::apply_inverse_mass_matrix_impl(make_not_null(data->data()), mesh);
      95             : }
      96             : 
      97             : template <size_t Dim, typename TagsList>
      98           1 : void apply_inverse_mass_matrix(const gsl::not_null<Variables<TagsList>*> data,
      99             :                                const Mesh<Dim>& mesh) {
     100             :   const size_t num_points = data->number_of_grid_points();
     101             :   ASSERT(num_points == mesh.number_of_grid_points(),
     102             :          "The Variables data has "
     103             :              << num_points << " grid points, but expected "
     104             :              << mesh.number_of_grid_points() << " on the given mesh.");
     105             :   constexpr size_t num_comps =
     106             :       Variables<TagsList>::number_of_independent_components;
     107             :   for (size_t i = 0; i < num_comps; ++i) {
     108             :     detail::apply_inverse_mass_matrix_impl(
     109             :         make_not_null(data->data() + i * num_points), mesh);
     110             :   }
     111             : }
     112             : /// @}
     113             : 
     114             : }  // namespace dg

Generated by: LCOV version 1.14