SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/Spectral/BasisFunctions - Fourier.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 90.0 % 10 9
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              : /// \endcond
      12              : 
      13              : namespace Spectral {
      14              : 
      15              : /*!
      16              :  * \ingroup SpectralGroup
      17              :  *
      18              :  * \brief A collection of helper functions for using a Fourier series
      19              :  *
      20              :  * \details The general real-valued Fourier series is given by:
      21              :  * \f[
      22              :  * f(x) = a_0 + \sum_{n=1}^{\infty} a_n \cos(nx) + b_n \sin(nx)
      23              :  * \f]
      24              :  * where
      25              :  * \f{align*}
      26              :  * a_0 &= \frac{1}{2\pi} \int_0^{2\pi} f(x) dx \\
      27              :  * a_n &= \frac{1}{\pi} \int_0^{2\pi} f(x) \cos(nx) dx \\
      28              :  * b_n &= \frac{1}{\pi} \int_0^{2\pi} f(x) \sin(nx) dx
      29              :  * \f}
      30              :  *
      31              :  * If a function is discretized at \f$N\f$ collocation points, the modal
      32              :  * representation will have \f$N\f$ spectral coefficients consisting of
      33              :  * \f{align*}
      34              :  * a_n & \qquad \text{for } n = 0, \ldots, \frac{N}{2} \\
      35              :  * b_n & \qquad \text{for } n = 1, \ldots, \frac{N-1}{2}
      36              :  * \f}
      37              :  * Thus to represent all terms through the harmonic \f$M\f$ requires \f$N = 2M
      38              :  * +1\f$ collocation points.
      39              :  *
      40              :  * For more details about using Fourier series see e.g. \cite Boyd2001 and
      41              :  * \cite Fornberg1996.
      42              :  */
      43            1 : class Fourier {
      44              :  public:
      45              :   /*!
      46              :    * \brief Value of the basis function \f$\Phi_k(x)\f$
      47              :    *
      48              :    * \details We define the basis functions as
      49              :    * \f{align*}{
      50              :    *   \Phi_k(x)
      51              :    *   &=\begin{cases}
      52              :    *     \hfil \cos(kx) \hfil & \text{if } k \geq 0 \\
      53              :    *     \hfil \sin(-kx) \hfil & \text{if } k < 0
      54              :    *   \end{cases}
      55              :    * \f}
      56              :    */
      57              :   template <typename T>
      58            1 :   static T basis_function_value(int k, const T& x);
      59              : 
      60              :   /*!
      61              :    * \brief The normalization square \f$c_k\f$ of the basis function
      62              :    * \f$\Phi_k(x)\f$, i.e. the definite integral of its square.
      63              :    *
      64              :    * \details
      65              :    * In particular,
      66              :    * \f{align*}{
      67              :    *   c_k
      68              :    *   &=\begin{cases}
      69              :    *     \hfil 2 \pi \hfil & \text{if } k = 0 \\
      70              :    *     \hfil \pi \hfil & \text{otherwise}
      71              :    *   \end{cases}
      72              :    * \f}
      73              :    */
      74            1 :   static double basis_function_normalization_square(int k);
      75              : 
      76              :   /*!
      77              :    * \brief Collocation points \f$\{x_i\}\f$
      78              :    *
      79              :    * \details The collocation points on the interval \f$0 \leq x < 2 \pi\f$ are
      80              :    * given by
      81              :    * \f[
      82              :    * x_i = \frac{2 \pi i}{N}
      83              :    * \f]
      84              :    */
      85            1 :   static DataVector collocation_points(size_t num_points);
      86              : 
      87              :   /*!
      88              :    * \brief Quadrature weights \f$\{w_i\}\f$
      89              :    *
      90              :    * \details The quadrature weights are given by
      91              :    * \f[
      92              :    * w_i = \frac{2 \pi}{N}
      93              :    * \f]
      94              :    */
      95            1 :   static DataVector quadrature_weights(size_t num_points);
      96              : 
      97              :   /*!
      98              :    * \brief Storage index (offset) \f$i\f$ into a ModalVector (representing the
      99              :    * coefficients) of the given mode \f$k\f$
     100              :    *
     101              :    * \details The modal coefficients are stored in a ModalVector as
     102              :    * \f$\{u_0, u_1, u_{-1}, u_2, u_{-2}, \ldots, u_M, u_{-M}\}\f$,
     103              :    * where \f$u_{-M}\f$ is omitted if the number of coefficients is even.
     104              :    * Therefore the storage index \f$i\f$ for the mode \f$u_k\f$ is:
     105              :    * \f{align*}{
     106              :    *   i
     107              :    *   &=\begin{cases}
     108              :    *     \hfil 0 \hfil & \text{if } k = 0 \\
     109              :    *     \hfil 2k-1 \hfil & \text{if } k > 0 \\
     110              :    *     \hfil -2k \hfil & \text{if } k < 0
     111              :    *   \end{cases}
     112              :    * \f}
     113              :    */
     114            1 :   static size_t modal_storage_index(int k);
     115              : 
     116              :   /*!
     117              :    * \brief Mode \f$k\f$ corresponding to given storage index (offset) \f$i\f$
     118              :    * into a ModalVector (representing the coefficients)
     119              :    *
     120              :    * \details The modal coefficients are stored in a ModalVector as
     121              :    * \f$\{u_0, u_1, u_{-1}, u_2, u_{-2}, \ldots, u_M, u_{-M}\}\f$,
     122              :    * where \f$u_{-M}\f$ is omitted if the number of coefficients is even.
     123              :    * Therefore the storage index \f$i\f$ for the mode \f$u_k\f$ is:
     124              :    * \f{align*}{
     125              :    *   k
     126              :    *   &=\begin{cases}
     127              :    *     \hfil 0 \hfil & \text{if } i = 0 \\
     128              :    *     \hfil 1 + \frac{i}{2} \hfil & \text{if } i \text{ is odd} \\
     129              :    *     \hfil -\frac{i}{2} \hfil & \text{if } i \text{ is even}
     130              :    *   \end{cases}
     131              :    * \f}
     132              :    */
     133            1 :   static int mode_at_storage_index(size_t storage_index);
     134              : 
     135              :   /*!
     136              :    * \brief Matrix \f$D_{i,j}\f$ used to obtain the first derivative
     137              :    *
     138              :    * \details The differentiation matrix is given by:
     139              :    * \f{align*}{
     140              :    *   D_{i,j}
     141              :    *   &=\begin{cases}
     142              :    *     \hfil 0 \hfil & \text{if } i = j \\
     143              :    *     \hfil \frac{1}{2} (-1)^{i-j} \csc \left[0.5 (x_i - x_j)\right] \hfil &
     144              :    *     \text{if } i \neq j,\; N \text{ is odd} \\
     145              :    *     \hfil \frac{1}{2} (-1)^{i-j} \cot \left[0.5 (x_i - x_j)\right] \hfil &
     146              :    *     \text{if } i \neq j,\; N \text{ is even}
     147              :    *   \end{cases}
     148              :    * \f}
     149              :    */
     150            1 :   static Matrix differentiation_matrix(size_t num_points);
     151              : 
     152              :   /*!
     153              :    * \brief %Matrix used to interpolate to the \p target_points.
     154              :    *
     155              :    * \details Each row of the matrix is given by the interpolation weights for
     156              :    * interpolating to a particular target point \f$x\f$.  At each target point,
     157              :    * \f$x\f$, the interpolation weights are given by:
     158              :    * \f{align*}{
     159              :    *   C_j(x)
     160              :    *   &=\begin{cases}
     161              :    *     \hfil \frac{1}{N} \sin \left[0.5 N(x - x_j)\right]
     162              :    *     \csc \left[0.5 (x - x_j)\right] \hfil & \text{if } N \text{ is odd} \\
     163              :    *     \hfil \frac{1}{N} \sin \left[0.5 N (x - x_j)\right]
     164              :    *     \cot \left[0.5 (x - x_j)\right] \hfil & \text{if } N \text{ is even}
     165              :    *   \end{cases}
     166              :    * \f}
     167              :    * where \f$x_j\f$ are the collocation_points.
     168              :    */
     169              :   template <typename T>
     170            1 :   static Matrix interpolation_matrix(size_t num_points, const T& target_points);
     171              : };
     172              : }  // namespace Spectral
        

Generated by: LCOV version 2.0-1