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 : /// \cond 9 : class Matrix; 10 : template <size_t> 11 : class Mesh; 12 : /// \endcond 13 : 14 : namespace Spectral { 15 : /*! 16 : * \ingroup SpectralGroup 17 : * \brief Matrices for filtering spectral coefficients. 18 : */ 19 1 : namespace filtering { 20 : /*! 21 : * \brief Returns a `Matrix` by which to multiply the nodal coefficients to 22 : * apply a stable exponential filter. 23 : * 24 : * The exponential filter rescales the modal coefficients according to: 25 : * 26 : * \f{align*}{ 27 : * c_i\to c_i \exp\left[-\alpha \left(\frac{i}{N}\right)^{2m}\right] 28 : * \f} 29 : * 30 : * where \f$c_i\f$ are the zero-indexed modal coefficients, \f$N\f$ is the basis 31 : * degree (number of grid points per element per dimension minus one), 32 : * \f$\alpha\f$ determines how much the coefficients are rescaled, and \f$m\f$ 33 : * determines how aggressive/broad the filter is (lower values means filtering 34 : * more coefficients). Setting \f$\alpha=36\f$ results in setting the highest 35 : * coefficient to machine precision, effectively zeroing it out. 36 : * 37 : * \note The filter matrix is not cached by the function because it depends on a 38 : * double, an integer, and the mesh, which could make caching very memory 39 : * intensive. The caller of this function is responsible for determining whether 40 : * or not the matrix should be cached. 41 : */ 42 1 : Matrix exponential_filter(const Mesh<1>& mesh, double alpha, 43 : unsigned half_power); 44 : 45 : /*! 46 : * \brief Zeros the lowest `number_of_modes_to_zero` modal coefficients. Note 47 : * that the matrix must be applied to a nodal representation. 48 : * 49 : * Given a function \f$u\f$ 50 : * 51 : * \f{align}{ 52 : * u(x)=\sum_{i=0}^N c_i P_i(x), 53 : * \f} 54 : * 55 : * where \f$c_i\f$ are the modal coefficients and \f$P_i(x)\f$ is the basis 56 : * (e.g. Legendre polynomials), the filter matrix will take the *nodal* 57 : * representation of \f$u\f$ and zero out the lowest `number_of_modes_to_zero` 58 : * modal coefficients. That is, after the filter is applied \f$u\to\bar{u}\f$ is 59 : * 60 : * \f{align}{ 61 : * \bar{u}(x)=\sum_{i=k}^N c_i P_i(x), 62 : * \f} 63 : * 64 : * where \f$k\f$ is the number of modes set to zero. The output \f$\bar{u}\f$ is 65 : * also in the *nodal* representation. 66 : */ 67 1 : const Matrix& zero_lowest_modes(const Mesh<1>& mesh, 68 : size_t number_of_modes_to_zero); 69 : } // namespace filtering 70 : } // namespace Spectral