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 "Utilities/Gsl.hpp" 9 : 10 : /// \cond 11 : class DataVector; 12 : template <size_t Dim> 13 : class Mesh; 14 : template <typename TagsList> 15 : class Variables; 16 : /// \endcond 17 : 18 : namespace Spectral::filtering { 19 : /*! 20 : * \brief Filters the radial components of tensors stored within a `Variables` 21 : * represented by ZernikeB3 basis functions on a filled ball. 22 : * 23 : * \details Functions on a filled ball with angular degree $\ell$ behave as 24 : * $r^\ell$ near the origin, so their radial profile lies in the even or 25 : * odd parity ZernikeB3 subspace depending on whether $\ell$ is even or odd. The 26 : * combined spectral space is therefore indexed by $(n_\mathrm{jac}, \ell, m)$, 27 : * where $n_\mathrm{jac}$ is the radial Jacobi index. The exponential filter 28 : * weight for mode $(n_\mathrm{jac}, \ell)$ is 29 : * 30 : * \f{align*}{ 31 : * w = \exp\!\left(-\alpha \left(\frac{n_i}{N_r-1}\right)^{2p}\right), 32 : * \f} 33 : * 34 : * where $n_i = \lfloor (\ell + 2 n_\mathrm{jac}) / 2 \rfloor$ and $N_r$ is the 35 : * number of radial grid points. 36 : * 37 : * The mesh must have basis 38 : * `(ZernikeB3, ZernikeB3, ZernikeB3)` with quadrature 39 : * `(GaussRadauUpper, Gauss, Equiangular)` and extents 40 : * `(n_r, l_max+1, 2*l_max+1)`. 41 : * 42 : * \see exponential_filter() 43 : */ 44 : template <typename VariablesTags> 45 1 : void zernike_b3_ball_radial_exponential_filter( 46 : gsl::not_null<Variables<VariablesTags>*> u, const Mesh<3>& mesh, 47 : double alpha, unsigned half_power); 48 : 49 : /*! 50 : * \brief Filters the radial components of tensors stored within a `Variables` 51 : * represented by ZernikeB3 basis functions on a filled ball. 52 : * 53 : * \details Overload taking a caller-managed working buffer. Avoids heap 54 : * allocations when the filter is applied repeatedly (e.g. every volume call 55 : * inside `Filters::Ball`). 56 : */ 57 : template <typename VariablesTags> 58 1 : void zernike_b3_ball_radial_exponential_filter( 59 : gsl::not_null<Variables<VariablesTags>*> u, gsl::not_null<DataVector*> buf, 60 : const Mesh<3>& mesh, double alpha, unsigned half_power); 61 : 62 : } // namespace Spectral::filtering