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