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 : /// \cond 12 : namespace Options { 13 : class Option; 14 : template <typename T> 15 : struct create_from_yaml; 16 : } // namespace Options 17 : /// \endcond 18 : 19 : namespace Spectral { 20 : /// \brief The amount we left-shift the basis integers by. 21 : /// 22 : /// We do this to be able to represent the combined Basis and Quadrature as one 23 : /// 8-bit integer. 24 1 : constexpr uint8_t basis_shift = 4; 25 : /*! 26 : * \brief Either the basis functions used by a spectral or discontinuous 27 : * Galerkin (DG) method, or the value `FiniteDifference` when a finite 28 : * difference method is used 29 : * 30 : * \details The particular choices of Basis and Quadrature determine where the 31 : * collocation points of a Mesh are located in an Element. For a spectral or DG 32 : * method, the Basis also represents the choice of basis functions used to 33 : * represent a function on an Element, which then provides a convenient choice 34 : * for the operators used for differentiation, interpolation, etc. For a finite 35 : * difference method, one needs to choose the order of the scheme (and hence the 36 : * weights, differentiation matrix, integration weights, and interpolant) 37 : * locally in space and time to handle discontinuous solutions. 38 : * 39 : * \note Choose `Legendre` for a general-purpose spectral or DG mesh, unless 40 : * you have a particular reason for choosing `Chebyshev`. 41 : * 42 : * \note Choose `Fourier` for a dimension that is spatially periodic and in 43 : * which the expected solution is smooth. A Mesh with this Basis cannot be 44 : * split by h-refinement in this dimension. 45 : * 46 : * \note Choose two consecutive dimensions to have `SphericalHarmonic` to choose 47 : * a spherical harmonic basis. By convention, the first dimension represents 48 : * the polar/zenith angle (or colatitude), while the second dimension represents 49 : * the azimuthal angle (or longitude). A Mesh with this Basis cannot be split 50 : * by h-refinement in these dimensions. 51 : * 52 : * \note Choose two consecutive dimensions to have `ZernikeB2` to choose 53 : * a basis used on a disk or cross-section of a cylinder. By convention, the 54 : * first dimension represents the radial direction, while the second dimension 55 : * represents the azimuthal angle. A Mesh with this Basis cannot be split by 56 : * h-refinement in these dimensions. 57 : * 58 : * \note Choose three consecutive dimensions to have `ZernikeB3` to choose 59 : * a basis used on a sphere. By convention, the first dimension represents the 60 : * radial direction, the second dimension represents the polar/zenith angle (or 61 : * colatitude), while the third dimension represents the azimuthal angle (or 62 : * longitude). A Mesh with this Basis cannot be split by h-refinement in these 63 : * dimensions. 64 : * 65 : * \note Choose `Cartoon` for a dimension (or consecutive dimensions) that 66 : * represent axial (or spherical) symmetry. 67 : * 68 : * \remark We store these effectively as a 4-bit integer using the highest 4 69 : * bits of a uint8_t, which is why we do the left shift. We cannot have more 70 : * than 16 bases to fit into the 4 bits, including the `Uninitialized` value. 71 : * The number of bits to shift is encoded in the variable 72 : * `Spectral::detail::basis_shift`. 73 : */ 74 0 : enum class Basis : uint8_t { 75 : Uninitialized = 0 << basis_shift, 76 : Chebyshev = 1 << basis_shift, 77 : Legendre = 2 << basis_shift, 78 : FiniteDifference = 3 << basis_shift, 79 : SphericalHarmonic = 4 << basis_shift, 80 : Fourier = 5 << basis_shift, 81 : ZernikeB2 = 6 << basis_shift, 82 : ZernikeB3 = 7 << basis_shift, 83 : Cartoon = 8 << basis_shift 84 : }; 85 : 86 : /// All possible values of Basis 87 1 : std::array<Basis, 9> all_bases(); 88 : 89 : /// Convert a string to a Basis enum. 90 1 : Basis to_basis(const std::string& basis); 91 : 92 : /// Output operator for a Basis. 93 1 : std::ostream& operator<<(std::ostream& os, const Basis& basis); 94 : } // namespace Spectral 95 : 96 : template <> 97 0 : struct Options::create_from_yaml<Spectral::Basis> { 98 : template <typename Metavariables> 99 0 : static Spectral::Basis create(const Options::Option& options) { 100 : return create<void>(options); 101 : } 102 : }; 103 : 104 : template <> 105 0 : Spectral::Basis Options::create_from_yaml<Spectral::Basis>::create<void>( 106 : const Options::Option& options);