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 "NumericalAlgorithms/Spectral/Basis.hpp"
9 : #include "NumericalAlgorithms/Spectral/Quadrature.hpp"
10 :
11 : /// Limits on the extents of a Mesh based on Basis and Quadrature. The minima
12 : /// are strict requirements except for spherical harmonics which are set by the
13 : /// package (SPHEREPACK) used to implement them. The maxima are set to limit
14 : /// the sizes of static caches, so can be changed if desired.
15 1 : namespace Spectral::limits {
16 : /// The minimum allowed mode \f$L\f$ for SPHEREPACK, the package used for a
17 : /// spherical harmonic basis
18 1 : static constexpr size_t min_spherical_harmonic_mode = 2;
19 :
20 : /// The maximum allowed mode \f$L\f$ for spherical harmonics in S2 or B3
21 : /// topologies
22 1 : static constexpr size_t max_spherical_harmonic_mode = 40;
23 :
24 : /// The maximum allowed mode \f$M\f$ for a Fourier series in S1 or B2 topologies
25 1 : static constexpr size_t max_fourier_mode = 40;
26 :
27 : /// The maximum allowed mode \f$N\f$ for polynomial series in I1 or B1
28 : /// topologies
29 1 : static constexpr size_t max_i1_polynomial_mode = 20;
30 :
31 : /// \brief The maximum allowed extent for a given Basis and Quadrature
32 : ///
33 : /// \details The maxima are chosen to limit the size of static caches.
34 : /// Let \f$N\f$ be the highest represented polynomial mode, \f$L\f$ the highest
35 : /// represented spherical harmonic mode, and \f$M\f$ the highest represented
36 : /// Fourier mode. Then the maxima are set as follows:
37 : /// - \f$N+1\f$ for Basis::Legendre, Basis::Chebyshev and Basis::ZernikeB1
38 : /// - \f$2N+2\f$ for Basis::FiniteDifference as for DG-subcell
39 : /// \f$n_{FD} = 2 n_{DG}\f$ for Quadrature::FaceCentered
40 : /// - \f$(L+1, 2L+1)\f$ for Basis::SphericalHarmonic
41 : /// - \f$2M+1\f$ for Basis::Fourier
42 : /// - \f$(M/2 + 1, 2M+1)\f$ for Basis::ZernikeB2
43 : /// - \f$(L/2 + 1, L+1, 2L+1)\f$ for Basis::ZernikeB3
44 : /// - 1 for Basis::Cartoon
45 1 : constexpr size_t max(const Basis basis, const Quadrature quadrature) {
46 : if (basis == Basis::Legendre or basis == Basis::Chebyshev or
47 : basis == Basis::ZernikeB1) {
48 : return max_i1_polynomial_mode + 1;
49 : } else if (basis == Basis::FiniteDifference) {
50 : return 2 * max_i1_polynomial_mode + 2;
51 : } else if (basis == Basis::Cartoon) {
52 : return 1;
53 : } else if (basis == Basis::SphericalHarmonic or basis == Basis::ZernikeB3) {
54 : if (quadrature == Quadrature::Gauss) {
55 : return max_spherical_harmonic_mode + 1;
56 : } else if (quadrature == Quadrature::Equiangular) {
57 : return 2 * max_spherical_harmonic_mode + 1;
58 : } else if (quadrature == Quadrature::GaussRadauUpper) {
59 : return max_spherical_harmonic_mode / 2 + 1;
60 : }
61 : } else if (basis == Basis::ZernikeB2 and
62 : quadrature == Quadrature::GaussRadauUpper) {
63 : return max_fourier_mode / 2 + 1;
64 : } else if (basis == Basis::HalfFourier) {
65 : return max_fourier_mode + 1;
66 : } else if (quadrature == Quadrature::Equiangular) {
67 : return 2 * max_fourier_mode + 1;
68 : }
69 : return 0;
70 : }
71 :
72 : /// \brief The minimum extent for a given Basis and Quadrature
73 : ///
74 : /// \details The minimum is 1 except for the following:
75 : /// - 2 for Quadrature::GaussLobatto and Quadrature::FaceCentered as they have
76 : /// collocation points on the boundaries
77 : /// - \f$(3, 5)\f$ for the angular directions of Basis::SphericalHarmonic or
78 : /// \f$(2, 3, 5)\f$ for the directions of Basis::ZernikeB3 as this is a
79 : /// requirement of the package SPHEREPACK that implements spherical harmonics
80 1 : constexpr size_t min(const Basis basis, const Quadrature quadrature) {
81 : if (quadrature == Quadrature::GaussLobatto or
82 : quadrature == Quadrature::FaceCentered or
83 : (basis == Basis::ZernikeB3 and
84 : quadrature == Quadrature::GaussRadauUpper)) {
85 : return 2;
86 : } else if (basis == Basis::SphericalHarmonic or basis == Basis::ZernikeB3) {
87 : if (quadrature == Quadrature::Gauss) {
88 : return min_spherical_harmonic_mode + 1;
89 : } else if (quadrature == Quadrature::Equiangular) {
90 : return 2 * min_spherical_harmonic_mode + 1;
91 : }
92 : }
93 : return 1;
94 : }
95 : } // namespace Spectral::limits
|