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 <complex>
8 : #include <cstddef>
9 : #include <type_traits>
10 : #include <vector>
11 :
12 : #include "Utilities/Gsl.hpp"
13 : #include "Utilities/Kokkos/KokkosMacros.hpp"
14 : #include "Utilities/MakeWithValue.hpp"
15 : #include "Utilities/TMPL.hpp"
16 :
17 : /// Implementations of \link set_number_of_grid_points \endlink
18 : ///
19 : /// Specializations may be trivial, meaning the object is similar to a
20 : /// `double` and doesn't actually represent grid data. The only
21 : /// requirement for trivial specializations is defining `is_trivial`
22 : /// as `true`.
23 : ///
24 : /// Non-trivial specializations must define `is_trivial` to `false`,
25 : /// and must define a static `apply` function with the signature shown
26 : /// in the below example. Non-trivial specializations must also be
27 : /// accompanied by a specialization of the
28 : /// MakeWithValueImpls::NumberOfPoints struct. The `apply` function
29 : /// will only be called if the current size is incorrect, so
30 : /// implementations should not check the current size.
31 : ///
32 : /// \snippet Test_SetNumberOfGridPoints.cpp SetNumberOfGridPointsImpl
33 1 : namespace SetNumberOfGridPointsImpls {
34 : /// Default implementation is not defined.
35 : template <typename T, typename = std::nullptr_t>
36 1 : struct SetNumberOfGridPointsImpl;
37 : } // namespace SetNumberOfGridPointsImpls
38 :
39 : /// \ingroup DataStructuresGroup
40 : /// Change the number of grid points in an object.
41 : ///
42 : /// Change the number of points stored in \p result to a given value
43 : /// or to match another object. If \p pattern is a `size_t` it will
44 : /// be used as the number of points, otherwise it will be interpreted
45 : /// as data on a collection of grid points.
46 : ///
47 : /// This can be called in Kokkos kernels for types that don't need resizing,
48 : /// such as `double`s and tensors of `double`s, for which it does nothing.
49 : ///
50 : /// \see SetNumberOfGridPointsImpls, make_with_value
51 : SPECTRE_KOKKOS_DISABLE_EXEC_CHECK
52 : template <typename T, typename U>
53 1 : KOKKOS_FUNCTION void set_number_of_grid_points(const gsl::not_null<T*> result,
54 : const U& pattern) {
55 : (void)result;
56 : (void)pattern;
57 : if constexpr (not SetNumberOfGridPointsImpls::SetNumberOfGridPointsImpl<
58 : T>::is_trivial) {
59 : const size_t size = MakeWithValueImpls::number_of_points(pattern);
60 : if (UNLIKELY(MakeWithValueImpls::number_of_points(*result) != size)) {
61 : SetNumberOfGridPointsImpls::SetNumberOfGridPointsImpl<T>::apply(result,
62 : size);
63 : }
64 : }
65 : }
66 :
67 : template <>
68 0 : struct SetNumberOfGridPointsImpls::SetNumberOfGridPointsImpl<double> {
69 0 : static constexpr bool is_trivial = true;
70 : };
71 :
72 : template <>
73 : struct SetNumberOfGridPointsImpls::SetNumberOfGridPointsImpl<
74 : std::complex<double>> {
75 : static constexpr bool is_trivial = true;
76 : };
77 :
78 : template <typename T, size_t N>
79 : struct SetNumberOfGridPointsImpls::SetNumberOfGridPointsImpl<std::array<T, N>> {
80 : static constexpr bool is_trivial =
81 : N == 0 or SetNumberOfGridPointsImpl<T>::is_trivial;
82 : static void apply(const gsl::not_null<std::array<T, N>*> result,
83 : const size_t size) {
84 : for (auto& entry : *result) {
85 : set_number_of_grid_points(make_not_null(&entry), size);
86 : }
87 : }
88 : };
89 :
90 : template <typename T>
91 : struct SetNumberOfGridPointsImpls::SetNumberOfGridPointsImpl<std::vector<T>> {
92 : static constexpr bool is_trivial = SetNumberOfGridPointsImpl<T>::is_trivial;
93 : static void apply(const gsl::not_null<std::vector<T>*> result,
94 : const size_t size) {
95 : for (auto& entry : *result) {
96 : set_number_of_grid_points(make_not_null(&entry), size);
97 : }
98 : }
99 : };
100 :
|