Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <string>
7 : #include <type_traits>
8 :
9 : #include "ParallelAlgorithms/Interpolation/InterpolationTargetDetail.hpp"
10 : #include "ParallelAlgorithms/Interpolation/Protocols/ComputeTargetPoints.hpp"
11 : #include "ParallelAlgorithms/Interpolation/Protocols/ComputeVarsToInterpolate.hpp"
12 : #include "ParallelAlgorithms/Interpolation/Protocols/PostInterpolationCallback.hpp"
13 : #include "Utilities/ProtocolHelpers.hpp"
14 :
15 : namespace intrp::protocols {
16 : namespace detail {
17 : // if_alias_exists_assert_conforms_to::value will always be `true` because we
18 : // want the static assert in the protocol to pass regardless of if the
19 : // `compute_vars_to_interpolate` alias exists in the conforming type. It's just
20 : // that if the alias does exist, there's an additional static assert to ensure
21 : // that the alias conforms to the ComputeVarsToInterpolate protocol
22 : template <typename ConformingType, bool HasAlias>
23 : struct if_alias_exists_assert_conforms_to;
24 :
25 : template <typename ConformingType>
26 : struct if_alias_exists_assert_conforms_to<ConformingType, false> {
27 : static constexpr bool value = true;
28 : };
29 :
30 : template <typename ConformingType>
31 : struct if_alias_exists_assert_conforms_to<ConformingType, true> {
32 : static constexpr bool value = true;
33 : static_assert(tt::assert_conforms_to_v<
34 : typename ConformingType::compute_vars_to_interpolate,
35 : ComputeVarsToInterpolate>);
36 : };
37 :
38 : template <typename ConformingType, bool HasAlias>
39 : constexpr bool if_alias_exists_assert_conforms_to_v =
40 : if_alias_exists_assert_conforms_to<ConformingType, HasAlias>::value;
41 : } // namespace detail
42 :
43 : /*!
44 : * \brief A protocol for `InterpolationTargetTag`s that are used in the
45 : * intrp::InterpolationTarget parallel component.
46 : *
47 : * \details A struct conforming to the `InterpolationTargetTag` protocol must
48 : * have
49 : *
50 : * - a type alias `temporal_id` to a tag that tells the interpolation target
51 : * what values of time to use (for example, `::Tags::Time`).
52 : *
53 : * - a type alias `vars_to_interpolate_to_target` which is a `tmpl::list` of
54 : * tags describing variables to interpolate. Will be used to construct a
55 : * `Variables`.
56 : *
57 : * - a type alias `compute_items_on_target` which is a `tmpl::list` of compute
58 : * items that uses `vars_to_interpolate_to_target` as input.
59 : *
60 : * - a type alias `compute_target_points` that conforms to the
61 : * intrp::protocols::ComputeTargetPoints protocol. This will compute the
62 : * points on the surface that we are interpolating onto.
63 : *
64 : * - a type alias `post_interpolation_callbacks` which is a `tmpl::list` where
65 : * every element of that list conforms to the
66 : * intrp::protocols::PostInterpolationCallback protocol. Only one callback
67 : * with the signature with `gsl::not_null` for both the DataBox and
68 : * GlobalCache (see `intrp::protocols::PostInterpolationCallback`) is allowed
69 : * in this list. Furthermore, if a callback with this signature is in the
70 : * list, it must also be the *only* callback in the list. After the
71 : * interpolation is complete, call this struct's `apply` function.
72 : *
73 : * A struct conforming to this protocol can also optionally have
74 : *
75 : * - a type alias `compute_vars_to_interpolate` that conforms to the
76 : * intrp::protocols::ComputeVarsToInterpolate protocol. This is a struct that
77 : * computes quantities in the volume that are required to compute different
78 : * quantities on the surface we are interpolating to.
79 : *
80 : * - a type alias `interpolating_component` to the parallel component that will
81 : * be interpolating to the interpolation target. Only needed when *not* using
82 : * the Interpolator ParallelComponent.
83 : *
84 : * An example of a struct that conforms to this protocol is
85 : *
86 : * \snippet Helpers/ParallelAlgorithms/Interpolation/Examples.hpp InterpolationTargetTag
87 : */
88 1 : struct InterpolationTargetTag {
89 : template <typename ConformingType>
90 0 : struct test {
91 0 : using temporal_id = typename ConformingType::temporal_id;
92 :
93 0 : using vars_to_interpolate_to_target =
94 : typename ConformingType::vars_to_interpolate_to_target;
95 :
96 : // If the conforming type has a `compute_vars_to_interpolate` alias, make
97 : // sure it conforms to the ComputeVarsToInterpolate protocol, otherwise just
98 : // return true
99 : static_assert(detail::if_alias_exists_assert_conforms_to_v<
100 : ConformingType,
101 : InterpolationTarget_detail::has_compute_vars_to_interpolate_v<
102 : ConformingType>>);
103 :
104 0 : using compute_items_on_target =
105 : typename ConformingType::compute_items_on_target;
106 :
107 0 : using compute_target_points =
108 : typename ConformingType::compute_target_points;
109 : static_assert(
110 : tt::assert_conforms_to_v<compute_target_points, ComputeTargetPoints>);
111 :
112 0 : using post_interpolation_callbacks =
113 : typename ConformingType::post_interpolation_callbacks;
114 : static_assert(tmpl::all<post_interpolation_callbacks,
115 : tt::assert_conforms_to<
116 : tmpl::_1, PostInterpolationCallback>>::value);
117 : };
118 : };
119 : } // namespace intrp::protocols
|