SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/Spectral/BasisFunctions - Chebyshev.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 87.5 % 8 7
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              : /// \cond
       9              : class DataVector;
      10              : class Matrix;
      11              : namespace Spectral {
      12              : enum class Quadrature : uint8_t;
      13              : }  // namespace Spectral
      14              : /// \endcond
      15              : 
      16              : namespace Spectral {
      17              : 
      18              : /*!
      19              :  * \ingroup SpectralGroup
      20              :  *
      21              :  * \brief A collection of helper functions for Chebyshev polynomials
      22              :  *
      23              :  * \details The Chebyshev polynomials are given by:
      24              :  * \f[
      25              :  * T_n (x) = \cos(n \theta), \text{      } \theta = \arccos(x)
      26              :  * \f]
      27              :  *
      28              :  * The Chebyshev expansion of a function \f$f \in [-1,1] \f$ is given by:
      29              :  * \f[
      30              :  * f(x) = \sum_{n=0}^{\infty} f_n T_n(x)
      31              :  * \f]
      32              :  * where
      33              :  * \f[
      34              :  * f_n = \frac{1}{c_n} \int_{-1}^1 f(x) T_n(x) w(x) dx
      35              :  * \f]
      36              :  * where the weight function is \f$w(x) = (1-x^2)^{-1/2}\f$ and the basis
      37              :  * function normalization value is given by:
      38              :  * \f{align*}{
      39              :  *   c_n
      40              :  *   &=\begin{cases}
      41              :  *     \hfil \pi \hfil & \text{if } n = 0 \\
      42              :  *     \hfil \frac{\pi}{2} \hfil & \text{otherwise}
      43              :  *   \end{cases}
      44              :  * \f}
      45              :  *
      46              :  * If a function is discretized at \f$N+1\f$ collocation points, the modal
      47              :  * representation will have \f$N+1\f$ spectral coefficients consisting of
      48              :  * \f[
      49              :  * f_n \qquad \text{for } n = 0, \ldots, N
      50              :  * \f]
      51              :  *
      52              :  * For more details about using Chebyshev polynomials see e.g. \cite Boyd2001
      53              :  * and \cite Fornberg1996.
      54              :  */
      55            1 : class Chebyshev {
      56              :  public:
      57              :   /*!
      58              :    * \brief Value of the basis function \f$\Phi_k(x) = T_k(x)\f$
      59              :    */
      60              :   template <typename T>
      61            1 :   static T basis_function_value(size_t k, const T& x);
      62              : 
      63              :   /*!
      64              :    * \brief The normalization square \f$c_k\f$ of the basis function
      65              :    * \f$\Phi_k(x)\f$, i.e. the definite integral of its square.
      66              :    */
      67            1 :   static double basis_function_normalization_square(size_t k);
      68              : 
      69              :   /*!
      70              :    * \brief Collocation points \f$\{x_i\}\f$
      71              :    *
      72              :    * \details The collocation points on the interval \f$[-1, 1]\f$ are given by
      73              :    * \f{align*}{
      74              :    *   x_i
      75              :    *   &=\begin{cases}
      76              :    *     \hfil - \cos \frac{(2i+1)\pi}{2N+2} \hfil &
      77              :    *       \text{for Quadrature::Gauss} \\
      78              :    *     \hfil - \cos \frac{i \pi}{N} \hfil &
      79              :    *       \text{for Quadrature::GaussLobatto}
      80              :    *   \end{cases}
      81              :    * \f}
      82              :    */
      83              :   template <Quadrature quadrature>
      84            1 :   static DataVector collocation_points(size_t num_points);
      85              : 
      86              :   /*!
      87              :    * \brief Integration weights \f$\{w_i\}\f$
      88              :    *
      89              :    * \details The integration weights are used to approximate the weighted
      90              :    * integral \f$Q[f]=\int f(x)w(x)\mathrm{d}x\approx \sum_k f_k w_k\f$.
      91              :    * For Quadrature::Gauss, the weights are given by:
      92              :    * \f[
      93              :    * w_i = \frac{\pi}{N+1}
      94              :    * \f]
      95              :    *
      96              :    * For Quadrature::GaussLobatto, the weights are given by:
      97              :    * \f{align*}{
      98              :    *   w_i
      99              :    *   &=\begin{cases}
     100              :    *     \hfil \frac{\pi}{2N}  \hfil & \text{for } j = 0, N\\
     101              :    *     \hfil \frac{\pi}{N}   \hfil & \text{for } j = 1, \ldots, N-1
     102              :    *   \end{cases}
     103              :    * \f}
     104              :    *
     105              :    * \note These weights are used to compute the modes from the nodal
     106              :    * values.  They are not used to evaluate definite or indefinite
     107              :    * integrals directly from the nodal values.
     108              :    */
     109              :   template <Quadrature quadrature>
     110            1 :   static DataVector integration_weights(size_t num_points);
     111              : 
     112              :   /*!
     113              :    * \brief Matrix used to compute the modes of the indefinite
     114              :    * integral from the modes of the integrand such that the constant
     115              :    * of integration is determined by requiring the integral to be zero
     116              :    * at \f$x=-1\f$.
     117              :    *
     118              :    * \details Chebyshev polynomials satisfy the identity:
     119              :    * \f[
     120              :    * \int^x dy T_n (y) = \left\{ \frac{T_{n+1}(x)}{2(n+1)} +
     121              :    *   \frac{T_{n-1}(x)}{2(n-1)} \right\}, \qquad n \geq 2
     122              :    * \f]
     123              :    *
     124              :    * Thus the modes \f$\tilde{f}_j\f$ of the integral are given as:
     125              :    * \f{align*}{
     126              :    *   \tilde{f}_i
     127              :    *   &=\begin{cases}
     128              :    *     \hfil \frac{f_{i-1}-f_{i+1}}{2i}, \hfil & \text{for } i > 1\\
     129              :    *     \hfil f_0 - \frac{f_2}{2} \hfil & \text{for } i = 1
     130              :    *   \end{cases}
     131              :    * \f}
     132              :    * where \f$f_j\f$ are the modes of the integrand.
     133              :    *\f$\tilde{f}_0\f$ is a constant of integration, which we choose such that
     134              :    * the integral is 0 at the left boundary of the domain (\f$x=-1\f$). The
     135              :    * condition for this is:
     136              :    *
     137              :    * \f[
     138              :    *   \tilde{f}_0=\sum_{i=1}^{N}(-1)^{i+1}\tilde{f}_i
     139              :    * \f]
     140              :    */
     141            1 :   static Matrix indefinite_integral_matrix(size_t num_points);
     142              : 
     143              :   /*!
     144              :    * \brief Row-vector used to compute the definite integral from the modes of
     145              :    * the integrand
     146              :    *
     147              :    * \details Given the modes \f$\tilde{f}_j\f$ of the integral (see
     148              :    * indefinite_integral_matrix), the definite integral is given by evaluating
     149              :    * the series at \f$x=1\f$ and \f$x=-1\f$ and taking the difference.  Given
     150              :    * that \f$T_n(1) = 1\f$ and \f$T_n(-1) = (-1)^n\f$, this means multiplying
     151              :    * the indefinite_integral_matrix by the row-vector \f$\{0, 2, 0, 2, \ldots
     152              :    * \}\f$ which yields:
     153              :    * \f{align*}{
     154              :    *   \tilde{q}_i
     155              :    *   &=\begin{cases}
     156              :    *     \hfil -\frac{2}{n^2-1}, \hfil & \text{for } i \text{ even}\\
     157              :    *     \hfil 0 \hfil & \text{for } i \text{ odd}
     158              :    *   \end{cases}
     159              :    * \f}
     160              :    */
     161            1 :   static Matrix definite_integral_matrix(size_t num_points);
     162              : };
     163              : }  // namespace Spectral
        

Generated by: LCOV version 2.0-1