SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/DiscontinuousGalerkin - ApplyMassMatrix.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 83.3 % 6 5
Test Date: 2026-10-22 17:29:42
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 2.0-1