SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/Spectral - Basis.hpp Hit Total Coverage
Commit: 107e15b340886ae54549b1baa4bfc92e676f667e Lines: 5 23 21.7 %
Date: 2026-09-17 16:38:56
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 <array>
       7             : #include <cstdint>
       8             : #include <iosfwd>
       9             : #include <string>
      10             : 
      11             : #include "Utilities/MakeArray.hpp"
      12             : 
      13             : /// \cond
      14             : namespace Options {
      15             : class Option;
      16             : template <typename T>
      17             : struct create_from_yaml;
      18             : }  // namespace Options
      19             : /// \endcond
      20             : 
      21             : namespace Spectral {
      22             : /// \brief The amount we left-shift the basis integers by.
      23             : ///
      24             : /// We do this to be able to represent the combined Basis and Quadrature as one
      25             : /// 8-bit integer.
      26           1 : constexpr uint8_t basis_shift = 4;
      27             : /*!
      28             :  * \brief Either the basis functions used by a spectral or discontinuous
      29             :  * Galerkin (DG) method, or the value `FiniteDifference` when a finite
      30             :  * difference method is used
      31             :  *
      32             :  * \details The particular choices of Basis and Quadrature determine where the
      33             :  * collocation points of a Mesh are located in an Element. For a spectral or DG
      34             :  * method, the Basis also represents the choice of basis functions used to
      35             :  * represent a function on an Element, which then provides a convenient choice
      36             :  * for the operators used for differentiation, interpolation, etc.  For a finite
      37             :  * difference method, one needs to choose the order of the scheme (and hence the
      38             :  * weights, differentiation matrix, integration weights, and interpolant)
      39             :  * locally in space and time to handle discontinuous solutions.
      40             :  *
      41             :  * \note Choose `Legendre` for a general-purpose spectral or DG mesh, unless
      42             :  * you have a particular reason for choosing `Chebyshev`.
      43             :  *
      44             :  * \note Choose `Fourier` for a dimension that is spatially periodic and in
      45             :  * which the expected solution is smooth.  A Mesh with this Basis cannot be
      46             :  * split by h-refinement in this dimension.
      47             :  *
      48             :  * \note Choose `HalfFourier` for a dimension that is spatially periodic and in
      49             :  * which the expected solution is smooth and each tensor component has a
      50             :  * definite parity, i.e. and be expanded purely in terms of either sines or
      51             :  * cosines. A Mesh with this Basis cannot be split by h-refinement in this
      52             :  * dimension.
      53             :  *
      54             :  * \note Choose two consecutive dimensions to have `SphericalHarmonic` to choose
      55             :  * a spherical harmonic basis.  By convention, the first dimension represents
      56             :  * the polar/zenith angle (or colatitude), while the second dimension represents
      57             :  * the azimuthal angle (or longitude).  A Mesh with this Basis cannot be split
      58             :  * by h-refinement in these dimensions.
      59             :  *
      60             :  * \note Choose two consecutive dimensions to have `ZernikeB2` to choose
      61             :  * a basis used on a disk or cross-section of a cylinder.  By convention, the
      62             :  * first dimension represents the radial direction, while the second dimension
      63             :  * represents the azimuthal angle. A Mesh with this Basis cannot be split by
      64             :  * h-refinement in these dimensions.
      65             :  *
      66             :  * \note Choose three consecutive dimensions to have `ZernikeB3` to choose
      67             :  * a basis used on a sphere.  By convention, the first dimension represents the
      68             :  * radial direction, the second dimension represents the polar/zenith angle (or
      69             :  * colatitude), while the third dimension represents the azimuthal angle (or
      70             :  * longitude). A Mesh with this Basis cannot be split by h-refinement in these
      71             :  * dimensions.
      72             :  *
      73             :  * \note Choose `Cartoon` for a dimension (or consecutive dimensions) that
      74             :  * represent axial (or spherical) symmetry.
      75             :  *
      76             :  * \remark We store these effectively as a 4-bit integer using the highest 4
      77             :  * bits of a uint8_t, which is why we do the left shift.  We cannot have more
      78             :  * than 16 bases to fit into the 4 bits, including the `Uninitialized` value.
      79             :  * The number of bits to shift is encoded in the variable
      80             :  * `Spectral::detail::basis_shift`.
      81             :  */
      82           0 : enum class Basis : uint8_t {
      83             :   Uninitialized = 0 << basis_shift,
      84             :   Chebyshev = 1 << basis_shift,
      85             :   Legendre = 2 << basis_shift,
      86             :   FiniteDifference = 3 << basis_shift,
      87             :   SphericalHarmonic = 4 << basis_shift,
      88             :   Fourier = 5 << basis_shift,
      89             :   ZernikeB1 = 6 << basis_shift,
      90             :   ZernikeB2 = 7 << basis_shift,
      91             :   ZernikeB3 = 8 << basis_shift,
      92             :   Cartoon = 9 << basis_shift,
      93             :   HalfFourier = 10 << basis_shift
      94             : };
      95             : 
      96             : /// All possible values of Basis
      97           1 : std::array<Basis, 11> all_bases();
      98             : 
      99             : /// Convert a string to a Basis enum.
     100           1 : Basis to_basis(const std::string& basis);
     101             : 
     102             : /// Output operator for a Basis.
     103           1 : std::ostream& operator<<(std::ostream& os, const Basis& basis);
     104             : 
     105             : /// Shortcuts for common Basis products where the default for I1Basis is
     106             : /// Basis::Legendre
     107           1 : namespace bases {
     108             : template <size_t VolumeDim, Basis I1Basis = Basis::Legendre>
     109           0 : static constexpr auto hypercube = make_array<VolumeDim>(Basis::Legendre);
     110             : 
     111             : template <size_t VolumeDim>
     112           0 : static constexpr auto hypertorus = make_array<VolumeDim>(Basis::Fourier);
     113             : 
     114             : template <Basis I1Basis = Basis::Legendre>
     115           0 : static constexpr auto annulus = std::array{I1Basis, Basis::Fourier};
     116             : 
     117           0 : static constexpr auto spherical_surface =
     118             :     make_array<2>(Basis::SphericalHarmonic);
     119             : 
     120           0 : static constexpr auto disk = make_array<2>(Basis::ZernikeB2);
     121             : 
     122             : template <Basis I1Basis = Basis::Legendre>
     123           0 : static constexpr auto spherical_shell =
     124             :     std::array{I1Basis, Basis::SphericalHarmonic, Basis::SphericalHarmonic};
     125             : 
     126             : template <Basis I1Basis = Basis::Legendre>
     127           0 : static constexpr auto cylindrical_shell =
     128             :     std::array{I1Basis, Basis::Fourier, I1Basis};
     129             : 
     130             : template <Basis I1Basis = Basis::Legendre>
     131           0 : static constexpr auto full_cylinder =
     132             :     std::array{Basis::ZernikeB2, Basis::ZernikeB2, I1Basis};
     133             : 
     134           0 : static constexpr auto full_sphere = make_array<3>(Basis::ZernikeB3);
     135             : 
     136             : template <Basis I1Basis = Basis::Legendre>
     137           0 : static constexpr auto cartoon_sphere =
     138             :     std::array{I1Basis, Basis::Cartoon, Basis::Cartoon};
     139             : 
     140           0 : static constexpr auto cartoon_sphere_inner =
     141             :     std::array{Basis::ZernikeB1, Basis::Cartoon, Basis::Cartoon};
     142             : 
     143             : template <Basis I1Basis = Basis::Legendre>
     144           0 : static constexpr auto cartoon_cylinder =
     145             :     std::array{I1Basis, I1Basis, Basis::Cartoon};
     146             : 
     147             : template <Basis I1Basis = Basis::Legendre>
     148           0 : static constexpr auto cartoon_cylinder_inner =
     149             :     std::array{Basis::ZernikeB1, I1Basis, Basis::Cartoon};
     150             : }  // namespace bases
     151             : }  // namespace Spectral
     152             : 
     153             : template <>
     154           0 : struct Options::create_from_yaml<Spectral::Basis> {
     155             :   template <typename Metavariables>
     156           0 :   static Spectral::Basis create(const Options::Option& options) {
     157             :     return create<void>(options);
     158             :   }
     159             : };
     160             : 
     161             : template <>
     162           0 : Spectral::Basis Options::create_from_yaml<Spectral::Basis>::create<void>(
     163             :     const Options::Option& options);

Generated by: LCOV version 1.14