SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/Spectral - Basis.hpp Hit Total Coverage
Commit: ecb8a275e1aebab77dcce48a5e098ed4e486ab4b Lines: 5 23 21.7 %
Date: 2026-08-22 01:05:40
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 two consecutive dimensions to have `SphericalHarmonic` to choose
      49             :  * a spherical harmonic basis.  By convention, the first dimension represents
      50             :  * the polar/zenith angle (or colatitude), while the second dimension represents
      51             :  * the azimuthal angle (or longitude).  A Mesh with this Basis cannot be split
      52             :  * by h-refinement in these dimensions.
      53             :  *
      54             :  * \note Choose two consecutive dimensions to have `ZernikeB2` to choose
      55             :  * a basis used on a disk or cross-section of a cylinder.  By convention, the
      56             :  * first dimension represents the radial direction, while the second dimension
      57             :  * represents the azimuthal angle. A Mesh with this Basis cannot be split by
      58             :  * h-refinement in these dimensions.
      59             :  *
      60             :  * \note Choose three consecutive dimensions to have `ZernikeB3` to choose
      61             :  * a basis used on a sphere.  By convention, the first dimension represents the
      62             :  * radial direction, the second dimension represents the polar/zenith angle (or
      63             :  * colatitude), while the third dimension represents the azimuthal angle (or
      64             :  * longitude). A Mesh with this Basis cannot be split by h-refinement in these
      65             :  * dimensions.
      66             :  *
      67             :  * \note Choose `Cartoon` for a dimension (or consecutive dimensions) that
      68             :  * represent axial (or spherical) symmetry.
      69             :  *
      70             :  * \remark We store these effectively as a 4-bit integer using the highest 4
      71             :  * bits of a uint8_t, which is why we do the left shift.  We cannot have more
      72             :  * than 16 bases to fit into the 4 bits, including the `Uninitialized` value.
      73             :  * The number of bits to shift is encoded in the variable
      74             :  * `Spectral::detail::basis_shift`.
      75             :  */
      76           0 : enum class Basis : uint8_t {
      77             :   Uninitialized = 0 << basis_shift,
      78             :   Chebyshev = 1 << basis_shift,
      79             :   Legendre = 2 << basis_shift,
      80             :   FiniteDifference = 3 << basis_shift,
      81             :   SphericalHarmonic = 4 << basis_shift,
      82             :   Fourier = 5 << basis_shift,
      83             :   ZernikeB1 = 6 << basis_shift,
      84             :   ZernikeB2 = 7 << basis_shift,
      85             :   ZernikeB3 = 8 << basis_shift,
      86             :   Cartoon = 9 << basis_shift
      87             : };
      88             : 
      89             : /// All possible values of Basis
      90           1 : std::array<Basis, 10> all_bases();
      91             : 
      92             : /// Convert a string to a Basis enum.
      93           1 : Basis to_basis(const std::string& basis);
      94             : 
      95             : /// Output operator for a Basis.
      96           1 : std::ostream& operator<<(std::ostream& os, const Basis& basis);
      97             : 
      98             : /// Shortcuts for common Basis products where the default for I1Basis is
      99             : /// Basis::Legendre
     100           1 : namespace bases {
     101             : template <size_t VolumeDim, Basis I1Basis = Basis::Legendre>
     102           0 : static constexpr auto hypercube = make_array<VolumeDim>(Basis::Legendre);
     103             : 
     104             : template <size_t VolumeDim>
     105           0 : static constexpr auto hypertorus = make_array<VolumeDim>(Basis::Fourier);
     106             : 
     107             : template <Basis I1Basis = Basis::Legendre>
     108           0 : static constexpr auto annulus = std::array{I1Basis, Basis::Fourier};
     109             : 
     110           0 : static constexpr auto spherical_surface =
     111             :     make_array<2>(Basis::SphericalHarmonic);
     112             : 
     113           0 : static constexpr auto disk = make_array<2>(Basis::ZernikeB2);
     114             : 
     115             : template <Basis I1Basis = Basis::Legendre>
     116           0 : static constexpr auto spherical_shell =
     117             :     std::array{I1Basis, Basis::SphericalHarmonic, Basis::SphericalHarmonic};
     118             : 
     119             : template <Basis I1Basis = Basis::Legendre>
     120           0 : static constexpr auto cylindrical_shell =
     121             :     std::array{I1Basis, Basis::Fourier, I1Basis};
     122             : 
     123             : template <Basis I1Basis = Basis::Legendre>
     124           0 : static constexpr auto full_cylinder =
     125             :     std::array{Basis::ZernikeB2, Basis::ZernikeB2, I1Basis};
     126             : 
     127           0 : static constexpr auto full_sphere = make_array<3>(Basis::ZernikeB3);
     128             : 
     129             : template <Basis I1Basis = Basis::Legendre>
     130           0 : static constexpr auto cartoon_sphere =
     131             :     std::array{I1Basis, Basis::Cartoon, Basis::Cartoon};
     132             : 
     133           0 : static constexpr auto cartoon_sphere_inner =
     134             :     std::array{Basis::ZernikeB1, Basis::Cartoon, Basis::Cartoon};
     135             : 
     136             : template <Basis I1Basis = Basis::Legendre>
     137           0 : static constexpr auto cartoon_cylinder =
     138             :     std::array{I1Basis, I1Basis, Basis::Cartoon};
     139             : 
     140             : template <Basis I1Basis = Basis::Legendre>
     141           0 : static constexpr auto cartoon_cylinder_inner =
     142             :     std::array{Basis::ZernikeB1, I1Basis, Basis::Cartoon};
     143             : }  // namespace bases
     144             : }  // namespace Spectral
     145             : 
     146             : template <>
     147           0 : struct Options::create_from_yaml<Spectral::Basis> {
     148             :   template <typename Metavariables>
     149           0 :   static Spectral::Basis create(const Options::Option& options) {
     150             :     return create<void>(options);
     151             :   }
     152             : };
     153             : 
     154             : template <>
     155           0 : Spectral::Basis Options::create_from_yaml<Spectral::Basis>::create<void>(
     156             :     const Options::Option& options);

Generated by: LCOV version 1.14