SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/Spectral - Filtering.hpp Hit Total Coverage
Commit: c3e43f8d41800b0ecefb9d1393f1de1d5a280c8f Lines: 4 5 80.0 %
Date: 2026-07-24 22:09:25
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 "NumericalAlgorithms/Spectral/Parity.hpp"
       9             : 
      10             : /// \cond
      11             : class Matrix;
      12             : template <size_t>
      13             : class Mesh;
      14             : /// \endcond
      15             : 
      16             : namespace Spectral {
      17             : /*!
      18             :  * \ingroup SpectralGroup
      19             :  * \brief Matrices for filtering spectral coefficients.
      20             :  */
      21           1 : namespace filtering {
      22             : /*!
      23             :  * \brief Returns a `Matrix` by which to multiply the nodal coefficients to
      24             :  * apply a stable exponential filter.
      25             :  *
      26             :  * The exponential filter rescales the modal coefficients according to:
      27             :  *
      28             :  * \f{align*}{
      29             :  *  c_i\to c_i \exp\left[-\alpha \left(\frac{i}{N}\right)^{2m}\right]
      30             :  * \f}
      31             :  *
      32             :  * where \f$c_i\f$ are the zero-indexed modal coefficients, \f$N\f$ is the basis
      33             :  * degree (number of grid points per element per dimension minus one),
      34             :  * \f$\alpha\f$ determines how much the coefficients are rescaled, and \f$m\f$
      35             :  * determines how aggressive/broad the filter is (lower values means filtering
      36             :  * more coefficients). Setting \f$\alpha=36\f$ results in setting the highest
      37             :  * coefficient to machine precision, effectively zeroing it out.
      38             :  *
      39             :  * For filtering the Fourier basis, both \f$\cos\f$ and \f$\sin\f$
      40             :  * contributions to a given \f$m\f$-mode are equally weighted.
      41             :  *
      42             :  * The Parity argument is only used for ZernikeB1 bases, where the modal space
      43             :  * is parity dependent.
      44             :  *
      45             :  * \note The filter matrix is not cached by the function because it depends on a
      46             :  * double, an integer, and the mesh, which could make caching very memory
      47             :  * intensive. The caller of this function is responsible for determining whether
      48             :  * or not the matrix should be cached.
      49             :  */
      50           1 : Matrix exponential_filter(const Mesh<1>& mesh, double alpha,
      51             :                           unsigned half_power,
      52             :                           Parity parity = Parity::Uninitialized);
      53             : 
      54             : /*!
      55             :  * \brief Zeros the lowest `number_of_modes_to_zero` modal coefficients. Note
      56             :  * that the matrix must be applied to a nodal representation.
      57             :  *
      58             :  * Given a function \f$u\f$
      59             :  *
      60             :  * \f{align}{
      61             :  *   u(x)=\sum_{i=0}^N c_i P_i(x),
      62             :  * \f}
      63             :  *
      64             :  * where \f$c_i\f$ are the modal coefficients and \f$P_i(x)\f$ is the basis
      65             :  * (e.g. Legendre polynomials), the filter matrix will take the *nodal*
      66             :  * representation of \f$u\f$ and zero out the lowest `number_of_modes_to_zero`
      67             :  * modal coefficients. That is, after the filter is applied \f$u\to\bar{u}\f$ is
      68             :  *
      69             :  * \f{align}{
      70             :  *   \bar{u}(x)=\sum_{i=k}^N c_i P_i(x),
      71             :  * \f}
      72             :  *
      73             :  * where \f$k\f$ is the number of modes set to zero. The output \f$\bar{u}\f$ is
      74             :  * also in the *nodal* representation.
      75             :  *
      76             :  * The Parity argument is only used for ZernikeB1 bases, where the modal space
      77             :  * is parity dependent.
      78             :  */
      79           1 : const Matrix& zero_lowest_modes(
      80             :     const Mesh<1>& mesh, size_t number_of_modes_to_zero,
      81             :     Spectral::Parity parity = Spectral::Parity::Uninitialized);
      82             : 
      83             : /*!
      84             :  * \brief Zeros the highest `number_of_modes_to_zero` modal coefficients. Note
      85             :  * that the matrix must be applied to a nodal representation.
      86             :  *
      87             :  * Given a function \f$u\f$
      88             :  *
      89             :  * \f{align}{
      90             :  *   u(x)=\sum_{i=0}^N c_i P_i(x),
      91             :  * \f}
      92             :  *
      93             :  * where \f$c_i\f$ are the modal coefficients and \f$P_i(x)\f$ is the basis
      94             :  * (e.g. Legendre polynomials), the filter matrix will take the *nodal*
      95             :  * representation of \f$u\f$ and zero out the highest `number_of_modes_to_zero`
      96             :  * modal coefficients. That is, after the filter is applied \f$u\to\bar{u}\f$ is
      97             :  *
      98             :  * \f{align}{
      99             :  *   \bar{u}(x)=\sum_{i=0}^{N-k} c_i P_i(x),
     100             :  * \f}
     101             :  *
     102             :  * where \f$k\f$ is the number of modes set to zero. The output \f$\bar{u}\f$ is
     103             :  * also in the *nodal* representation. The constant (\f$i=0\f$) mode is never
     104             :  * removed for any basis.
     105             :  *
     106             :  * For the Fourier basis the "modes" are the \f$m\f$-modes: the highest
     107             :  * `number_of_modes_to_zero` \f$m\f$-modes are zeroed, with both the \f$\cos\f$
     108             :  * and \f$\sin\f$ contributions to a given \f$m\f$-mode treated identically.
     109             :  *
     110             :  * \note Only the Legendre, Chebyshev, and Fourier bases are supported. Unlike
     111             :  * `zero_lowest_modes`, there is no parity argument and the ZernikeB1 basis is
     112             :  * not supported.
     113             :  */
     114           1 : const Matrix& zero_highest_modes(const Mesh<1>& mesh,
     115             :                                  size_t number_of_modes_to_zero);
     116             : }  // namespace filtering
     117             : }  // namespace Spectral

Generated by: LCOV version 1.14