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 : #include <type_traits> 8 : 9 : #include "NumericalAlgorithms/Spectral/Basis.hpp" 10 : #include "NumericalAlgorithms/Spectral/Mesh.hpp" 11 : #include "NumericalAlgorithms/Spectral/Quadrature.hpp" 12 : #include "Utilities/ErrorHandling/Error.hpp" 13 : 14 : namespace Spectral::detail { 15 : template <typename F> 16 : decltype(auto) get_spectral_quantity_for_mesh(F&& f, const Mesh<1>& mesh) { 17 : const auto num_points = mesh.extents(0); 18 : // Switch on runtime values of basis and quadrature to select 19 : // corresponding template specialization. For basis functions spanning 20 : // multiple dimensions we can generalize this function to take a 21 : // higher-dimensional Mesh. 22 : switch (mesh.basis(0)) { 23 : case Basis::Legendre: 24 : switch (mesh.quadrature(0)) { 25 : case Quadrature::Gauss: 26 : return f(std::integral_constant<Basis, Basis::Legendre>{}, 27 : std::integral_constant<Quadrature, Quadrature::Gauss>{}, 28 : num_points); 29 : case Quadrature::GaussLobatto: 30 : return f( 31 : std::integral_constant<Basis, Basis::Legendre>{}, 32 : std::integral_constant<Quadrature, Quadrature::GaussLobatto>{}, 33 : num_points); 34 : default: 35 : ERROR("Missing quadrature case for spectral quantity"); 36 : } 37 : case Basis::Chebyshev: 38 : switch (mesh.quadrature(0)) { 39 : case Quadrature::Gauss: 40 : return f(std::integral_constant<Basis, Basis::Chebyshev>{}, 41 : std::integral_constant<Quadrature, Quadrature::Gauss>{}, 42 : num_points); 43 : case Quadrature::GaussLobatto: 44 : return f( 45 : std::integral_constant<Basis, Basis::Chebyshev>{}, 46 : std::integral_constant<Quadrature, Quadrature::GaussLobatto>{}, 47 : num_points); 48 : default: 49 : ERROR("Missing quadrature case for spectral quantity"); 50 : } 51 : case Basis::Cartoon: 52 : switch (mesh.quadrature(0)) { 53 : case Quadrature::AxialSymmetry: 54 : return f( 55 : std::integral_constant<Basis, Basis::Cartoon>{}, 56 : std::integral_constant<Quadrature, Quadrature::AxialSymmetry>{}, 57 : num_points); 58 : case Quadrature::SphericalSymmetry: 59 : return f(std::integral_constant<Basis, Basis::Cartoon>{}, 60 : std::integral_constant<Quadrature, 61 : Quadrature::SphericalSymmetry>{}, 62 : num_points); 63 : default: 64 : ERROR( 65 : "Only Axial and Spherical Symmetry quadratures are allowed for " 66 : "a Cartoon basis."); 67 : } 68 : case Basis::FiniteDifference: 69 : switch (mesh.quadrature(0)) { 70 : case Quadrature::CellCentered: 71 : return f( 72 : std::integral_constant<Basis, Basis::FiniteDifference>{}, 73 : std::integral_constant<Quadrature, Quadrature::CellCentered>{}, 74 : num_points); 75 : case Quadrature::FaceCentered: 76 : return f( 77 : std::integral_constant<Basis, Basis::FiniteDifference>{}, 78 : std::integral_constant<Quadrature, Quadrature::FaceCentered>{}, 79 : num_points); 80 : default: 81 : ERROR( 82 : "Only CellCentered and FaceCentered are supported for finite " 83 : "difference quadrature."); 84 : } 85 : case Basis::SphericalHarmonic: 86 : ERROR( 87 : "Basis::SphericalHarmonic is a two-dimensional basis and is not " 88 : "supported for this function. If you want the collocation points, " 89 : "use the function logical_coordinates."); 90 : default: 91 : ERROR("Missing basis case for spectral quantity. The missing basis is: " 92 : << mesh.basis(0)); 93 : } 94 : } 95 : } // namespace Spectral::detail