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/RuntimeCache.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,
74 : const size_t N) {
75 : constexpr size_t max_num_points =
76 : Spectral::maximum_number_of_points<BasisType>;
77 : constexpr size_t min_num_points =
78 : Spectral::minimum_number_of_points<BasisType, QuadratureType>;
79 : ASSERT(num_points >= min_num_points,
80 : "Tried to work with less than the minimum number of collocation "
81 : "points for this quadrature.");
82 : ASSERT(num_points <= max_num_points,
83 : "Exceeded maximum number of collocation points.");
84 : static const auto precomputed_data =
85 : make_runtime_cache<CacheRange<min_num_points, max_num_points + 1>,
86 : CacheRange<size_t{0}, 2 * max_num_points - 1>,
87 : CacheRange<size_t{0}, 2 * max_num_points - 1>>(
88 : SpectralQuantityGenerator{});
89 : return precomputed_data(num_points, m, N);
90 : }
91 : } // namespace Spectral::detail
92 :
93 : // clang-tidy: Macro arguments should be in parentheses, but we want to append
94 : // template parameters here.
95 : #define PRECOMPUTED_SPECTRAL_QUANTITY(function_name, return_type, \
96 0 : generator_name) \
97 : template <Basis BasisType, Quadrature QuadratureType> \
98 : const return_type& function_name(const size_t num_points) { \
99 : return Spectral::detail::precomputed_spectral_quantity< \
100 : BasisType, QuadratureType, \
101 : generator_name<BasisType, QuadratureType>>(/* NOLINT */ \
102 : num_points); \
103 : }
104 : #define PRECOMPUTED_SPECTRAL_QUANTITY_WITH_PARITY(function_name, return_type, \
105 0 : generator_name) \
106 : template <Basis BasisType, Quadrature QuadratureType> \
107 : const return_type& function_name(const size_t num_points, \
108 : const Parity parity) { \
109 : return Spectral::detail::precomputed_spectral_quantity_with_parity< \
110 : BasisType, QuadratureType, \
111 : generator_name<BasisType, QuadratureType>>(/* NOLINT */ \
112 : num_points, parity); \
113 : }
114 : #define PRECOMPUTED_TWO_INDEXED_SPECTRAL_QUANTITY(function_name, return_type, \
115 0 : generator_name) \
116 : template <Basis BasisType, Quadrature QuadratureType> \
117 : const return_type& function_name(const size_t num_points, const size_t m, \
118 : const size_t N) { \
119 : return Spectral::detail::precomputed_two_indexed_spectral_quantity< \
120 : BasisType, QuadratureType, \
121 : generator_name<BasisType, QuadratureType>>(/* NOLINT */ \
122 : num_points, m, N); \
123 : }
|