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 Parity : 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 the half-Fourier spectral basis
22 : *
23 : * \details The half-Fourier basis represents functions on the interval
24 : * \f$\phi \in [0, \pi)\f$ using \f$N\f$ equispaced interior collocation
25 : * points \f$\phi_j = (j + \tfrac{1}{2})\pi/N\f$ for \f$j = 0, \ldots, N-1\f$.
26 : *
27 : * Functions of even parity under \f$\phi \to -\phi\f$ (i.e. those satisfying
28 : * \f$f(-\phi)=f(\phi)\f$) are expanded in cosines:
29 : * \f[
30 : * f(\phi) = \sum_{n=0}^{N-1} a_n \cos(n\phi)
31 : * \f]
32 : *
33 : * Functions of odd parity under \f$\phi \to -\phi\f$ (i.e. those satisfying
34 : * \f$f(-\phi)=-f(\phi)\f$) are expanded in sines:
35 : * \f[
36 : * f(\phi) = \sum_{n=1}^{N} b_n \sin(n\phi)
37 : * \f]
38 : *
39 : * The derivative \f$\partial / \partial \phi\f$ maps even-parity functions to
40 : * odd-parity functions and vice versa.
41 : *
42 : * This basis is intended for use in the Cartoon method for axisymmetric
43 : * problems on a cylinder, where the azimuthal direction covers only half a
44 : * circle due to the reflection symmetry, and the parity boundary conditions
45 : * are internal to the spectral representation.
46 : *
47 : * \note The odd-parity space includes the Nyquist mode \f$\sin(N\phi)\f$,
48 : * whose derivative vanishes at every collocation point. Nonlinear terms can
49 : * alias into it, so evolutions should filter it out;
50 : * `Spectral::filtering::exponential_filter` does this.
51 : */
52 1 : class HalfFourier {
53 : public:
54 : /*!
55 : * \brief Collocation points \f$\{\phi_j\}\f$
56 : *
57 : * \details The collocation points on the interval \f$(0, \pi)\f$ are given
58 : * by
59 : * \f[
60 : * \phi_j = \frac{(j + \tfrac{1}{2})\pi}{N}
61 : * \f]
62 : */
63 1 : static DataVector collocation_points(size_t num_points);
64 :
65 : /*!
66 : * \brief Quadrature weights \f$\{w_j\}\f$
67 : *
68 : * \details The quadrature weights are uniform:
69 : * \f[
70 : * w_j = \frac{\pi}{N}
71 : * \f]
72 : */
73 1 : static DataVector quadrature_weights(size_t num_points);
74 :
75 : /*!
76 : * \brief Differentiation matrix \f$D^{\text{even}}_{ij}\f$ for even-parity
77 : * functions
78 : *
79 : * \details Maps an even-parity function (expanded in cosines) to its
80 : * derivative, which is an odd-parity function (expanded in sines).
81 : * Explicitly:
82 : * \f[
83 : * D^{\text{even}}_{ij} = \frac{2}{N} \sum_{n=1}^{N-1}
84 : * (-n) \sin(n\phi_i) \cos(n\phi_j)
85 : * \f]
86 : */
87 1 : static Matrix even_differentiation_matrix(size_t num_points);
88 :
89 : /*!
90 : * \brief Differentiation matrix \f$D^{\text{odd}}_{ij}\f$ for odd-parity
91 : * functions
92 : *
93 : * \details Maps an odd-parity function (expanded in sines) to its
94 : * derivative, which is an even-parity function (expanded in cosines).
95 : * Explicitly:
96 : * \f[
97 : * D^{\text{odd}}_{ij} = \frac{2}{N} \sum_{n=1}^{N-1}
98 : * n \cos(n\phi_i) \sin(n\phi_j)
99 : * \f]
100 : *
101 : * Note that \f$D^{\text{even}} = -(D^{\text{odd}})^T\f$. The sum stops at
102 : * \f$N-1\f$ rather than \f$N\f$ because \f$\cos(N\phi_i) = 0\f$.
103 : */
104 1 : static Matrix odd_differentiation_matrix(size_t num_points);
105 :
106 : /*!
107 : * \brief Interpolation matrix for even-parity functions to
108 : * \p target_points.
109 : *
110 : * \details Using the discrete cosine transform (DCT-II) representation, the
111 : * interpolation weights at a target point \f$x\f$ are:
112 : * \f[
113 : * I^{\text{even}}_j(x) = \frac{1}{N}\left[1 + 2\sum_{n=1}^{N-1}
114 : * \cos(nx)\cos(n\phi_j)\right]
115 : * \f]
116 : */
117 : template <typename T>
118 1 : static Matrix even_interpolation_matrix(size_t num_points,
119 : const T& target_points);
120 :
121 : /*!
122 : * \brief Interpolation matrix for odd-parity functions to
123 : * \p target_points.
124 : *
125 : * \details Using the discrete sine transform (DST-II) representation, the
126 : * interpolation weights at a target point \f$x\f$ are:
127 : * \f[
128 : * I^{\text{odd}}_j(x) = \frac{2}{N}\sum_{n=1}^{N-1}
129 : * \sin(nx)\sin(n\phi_j) + \frac{1}{N}\sin(Nx)\sin(N\phi_j)
130 : * \f]
131 : * where the Nyquist mode \f$n=N\f$ carries half the weight of the other
132 : * modes.
133 : */
134 : template <typename T>
135 1 : static Matrix odd_interpolation_matrix(size_t num_points,
136 : const T& target_points);
137 :
138 : /*!
139 : * \brief %Matrix used to interpolate to the \p target_points for a given
140 : * \p parity.
141 : *
142 : * \details Dispatches to `even_interpolation_matrix` when \p parity is
143 : * `Parity::Even` and to `odd_interpolation_matrix` when it is `Parity::Odd`.
144 : * This mirrors the interface of `Zernike<1>::interpolation_matrix`.
145 : */
146 : template <typename T>
147 1 : static Matrix interpolation_matrix(size_t num_points, const T& target_points,
148 : Parity parity);
149 : };
150 : } // namespace Spectral
|