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/MaximumNumberOfPoints.hpp" 9 : #include "NumericalAlgorithms/Spectral/MinimumNumberOfPoints.hpp" 10 : #include "NumericalAlgorithms/Spectral/Parity.hpp" 11 : #include "Utilities/ErrorHandling/Assert.hpp" 12 : #include "Utilities/StaticCache.hpp" 13 : 14 : /// \cond 15 : namespace Spectral { 16 : enum class Basis : uint8_t; 17 : enum class Quadrature : uint8_t; 18 : } // namespace Spectral 19 : /// \endcond 20 : 21 : namespace Spectral::detail { 22 : template <Basis BasisType, Quadrature QuadratureType, 23 : typename SpectralQuantityGenerator> 24 : const auto& precomputed_spectral_quantity(const size_t num_points) { 25 : constexpr size_t max_num_points = 26 : Spectral::maximum_number_of_points<BasisType>; 27 : constexpr size_t min_num_points = 28 : Spectral::minimum_number_of_points<BasisType, QuadratureType>; 29 : ASSERT(num_points >= min_num_points, 30 : "Tried to work with less than the minimum number of collocation " 31 : "points for this quadrature."); 32 : ASSERT(num_points <= max_num_points, 33 : "Exceeded maximum number of collocation points."); 34 : // We compute the quantity for all possible `num_point`s the first time this 35 : // function is called and keep the data around for the lifetime of the 36 : // program. The computation is handled by the call operator of the 37 : // `SpectralQuantityType` instance. 38 : static const auto precomputed_data = 39 : make_static_cache<CacheRange<min_num_points, max_num_points + 1>>( 40 : SpectralQuantityGenerator{}); 41 : return precomputed_data(num_points); 42 : } 43 : 44 : template <Basis BasisType, Quadrature QuadratureType, 45 : typename SpectralQuantityGenerator> 46 : const auto& precomputed_spectral_quantity_with_parity(const size_t num_points, 47 : const Parity parity) { 48 : constexpr size_t max_num_points = 49 : Spectral::maximum_number_of_points<BasisType>; 50 : constexpr size_t min_num_points = 51 : Spectral::minimum_number_of_points<BasisType, QuadratureType>; 52 : ASSERT(num_points >= min_num_points, 53 : "Tried to work with less than the minimum number of collocation " 54 : "points for this quadrature."); 55 : ASSERT(num_points <= max_num_points, 56 : "Exceeded maximum number of collocation points."); 57 : ASSERT(parity != Parity::Uninitialized, 58 : "Tried to use a parity-based function without a definite parity"); 59 : // We compute the quantity for all possible `num_point`s the first time this 60 : // function is called and keep the data around for the lifetime of the 61 : // program. The computation is handled by the call operator of the 62 : // `SpectralQuantityType` instance. 63 : static const auto precomputed_data = 64 : make_static_cache<CacheRange<min_num_points, max_num_points + 1>, 65 : CacheEnumeration<Parity, Parity::Even, Parity::Odd>>( 66 : SpectralQuantityGenerator{}); 67 : return precomputed_data(num_points, parity); 68 : } 69 : 70 : template <Basis BasisType, Quadrature QuadratureType, 71 : typename SpectralQuantityGenerator> 72 : const auto& precomputed_two_indexed_spectral_quantity(const size_t num_points, 73 : const size_t m, const size_t N) { 74 : constexpr size_t max_num_points = 75 : Spectral::maximum_number_of_points<BasisType>; 76 : constexpr size_t min_num_points = 77 : Spectral::minimum_number_of_points<BasisType, QuadratureType>; 78 : ASSERT(num_points >= min_num_points, 79 : "Tried to work with less than the minimum number of collocation " 80 : "points for this quadrature."); 81 : ASSERT(num_points <= max_num_points, 82 : "Exceeded maximum number of collocation points."); 83 : // We compute the quantity for all possible `num_point`s the first time this 84 : // function is called and keep the data around for the lifetime of the 85 : // program. The computation is handled by the call operator of the 86 : // `SpectralQuantityType` instance. 87 : static const auto precomputed_data = 88 : make_static_cache<CacheRange<min_num_points, max_num_points + 1>, 89 : CacheRange<0_st, 2 * max_num_points - 1>, 90 : CacheRange<0_st, 2 * max_num_points - 1>>( 91 : SpectralQuantityGenerator{}); 92 : return precomputed_data(num_points, m, N); 93 : } 94 : } // namespace Spectral::detail 95 : 96 : // clang-tidy: Macro arguments should be in parentheses, but we want to append 97 : // template parameters here. 98 : #define PRECOMPUTED_SPECTRAL_QUANTITY(function_name, return_type, \ 99 0 : generator_name) \ 100 : template <Basis BasisType, Quadrature QuadratureType> \ 101 : const return_type& function_name(const size_t num_points) { \ 102 : return Spectral::detail::precomputed_spectral_quantity< \ 103 : BasisType, QuadratureType, \ 104 : generator_name<BasisType, QuadratureType>>(/* NOLINT */ \ 105 : num_points); \ 106 : } 107 : #define PRECOMPUTED_SPECTRAL_QUANTITY_WITH_PARITY(function_name, return_type, \ 108 0 : generator_name) \ 109 : template <Basis BasisType, Quadrature QuadratureType> \ 110 : const return_type& function_name(const size_t num_points, \ 111 : const Parity parity) { \ 112 : return Spectral::detail::precomputed_spectral_quantity_with_parity< \ 113 : BasisType, QuadratureType, \ 114 : generator_name<BasisType, QuadratureType>>(/* NOLINT */ \ 115 : num_points, parity); \ 116 : } 117 : #define PRECOMPUTED_TWO_INDEXED_SPECTRAL_QUANTITY(function_name, return_type, \ 118 0 : generator_name) \ 119 : template <Basis BasisType, Quadrature QuadratureType> \ 120 : const return_type& function_name(const size_t num_points, const size_t m, \ 121 : const size_t N) { \ 122 : return Spectral::detail::precomputed_two_indexed_spectral_quantity< \ 123 : BasisType, QuadratureType, \ 124 : generator_name<BasisType, QuadratureType>>(/* NOLINT */ \ 125 : num_points, m, N); \ 126 : }