Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <type_traits> 7 : 8 : #include "DataStructures/DataBox/DataBox.hpp" 9 : #include "DataStructures/DataVector.hpp" 10 : #include "DataStructures/Tensor/TypeAliases.hpp" 11 : #include "DataStructures/Variables.hpp" 12 : #include "Utilities/Gsl.hpp" 13 : #include "Utilities/TMPL.hpp" 14 : 15 : /// \cond 16 : namespace Frame { 17 : struct ElementLogical; 18 : struct Grid; 19 : struct Inertial; 20 : } // namespace Frame 21 : template <size_t Dim> 22 : struct Mesh; 23 : struct DataVector; 24 : /// \endcond 25 : 26 : namespace intrp::protocols { 27 : /*! 28 : * \brief A protocol for the type alias `compute_vars_to_interpolate` that can 29 : * potentially be found in an InterpolationTargetTag (potentially because an 30 : * InterpolationTargetTag does not require this type alias). 31 : * 32 : * \details A struct conforming to the `ComputeVarsToInterpolate` protocol must 33 : * have 34 : * 35 : * - a type alias `allowed_src_tags` which is a `tmpl::list` of tags from the 36 : * volume that can be used to compute quantities that will be interpolated 37 : * onto the target. 38 : * 39 : * - a type alias `required_src_tags` which is a `tmpl::list` of tags from the 40 : * volume that are necessary to compute quantities that will be interpolated 41 : * onto the target. This list must be a subset of `allowed_src_tags`. 42 : * 43 : * - a type alias `allowed_dest_tags<Frame>` which is a `tmpl::list` of tags on 44 : * the target that can be computed from the source tags. 45 : * 46 : * - a type alias `required_dest_tags<Frame>` which is a `tmpl::list` of tags on 47 : * the target that must be computed from the source tags. This list must be a 48 : * subset of `allowed_dest_tags<Frame>` 49 : * 50 : * - an `apply` function with at least one of the signatures in the example. 51 : * This apply function fills the `vars_to_interpolate_to_target` type alias 52 : * from the InterpolationTargetTag. Here `Dim` is `Metavariables::volume_dim`, 53 : * SrcFrame is the frame of `Metavariables::interpolator_source_vars` and 54 : * TargetFrame is the frame of `vars_to_interpolate_to_target` from the 55 : * InterpolationTargetTag. The overload without Jacobians treats the case in 56 : * which TargetFrame is the same as SrcFrame. 57 : * 58 : * Here is an example of a class that conforms to this protocols: 59 : * 60 : * \snippet Helpers/ParallelAlgorithms/Interpolation/Examples.hpp ComputeVarsToInterpolate 61 : */ 62 1 : struct ComputeVarsToInterpolate { 63 : template <typename ConformingType> 64 0 : struct test { 65 : template <size_t Dim> 66 0 : struct DummyTag : db::SimpleTag { 67 0 : using type = tnsr::a<DataVector, Dim, Frame::Grid>; 68 : }; 69 : template <size_t Dim> 70 0 : using example_list = tmpl::list<DummyTag<Dim>>; 71 : 72 : template <typename T, size_t Dim, typename = std::void_t<>> 73 0 : struct has_signature_1 : std::false_type {}; 74 : 75 : template <typename T, size_t Dim> 76 : struct has_signature_1< 77 : T, Dim, 78 : std::void_t<decltype(T::apply( 79 : std::declval<const gsl::not_null<Variables<example_list<Dim>>*>>(), 80 : std::declval<const Variables<example_list<Dim>>&>(), 81 : std::declval<const Mesh<Dim>&>()))>> : std::true_type {}; 82 : 83 : template <typename T, size_t Dim, typename = std::void_t<>> 84 0 : struct has_signature_2 : std::false_type {}; 85 : 86 : template <typename T, size_t Dim> 87 : struct has_signature_2< 88 : T, Dim, 89 : std::void_t<decltype(T::apply( 90 : std::declval<const gsl::not_null<Variables<example_list<Dim>>*>>(), 91 : std::declval<const Variables<example_list<Dim>>&>(), 92 : std::declval<const Mesh<Dim>&>(), 93 : std::declval<const Jacobian<DataVector, Dim, Frame::Grid, 94 : Frame::Inertial>&>(), 95 : std::declval<const InverseJacobian<DataVector, Dim, Frame::Grid, 96 : Frame::Inertial>&>(), 97 : std::declval<const Jacobian<DataVector, Dim, Frame::ElementLogical, 98 : Frame::Grid>&>(), 99 : std::declval<const InverseJacobian< 100 : DataVector, Dim, Frame::ElementLogical, Frame::Grid>&>(), 101 : std::declval<const tnsr::I<DataVector, Dim, Frame::Inertial>&>(), 102 : std::declval<const tnsr::I<DataVector, Dim, Frame::Grid>&>()))>> 103 : : std::true_type {}; 104 : 105 : static_assert(has_signature_1<ConformingType, 1>::value or 106 : has_signature_2<ConformingType, 1>::value or 107 : has_signature_1<ConformingType, 2>::value or 108 : has_signature_2<ConformingType, 2>::value or 109 : has_signature_1<ConformingType, 3>::value or 110 : has_signature_2<ConformingType, 3>::value); 111 : 112 0 : using allowed_src_tags = typename ConformingType::allowed_src_tags; 113 0 : using required_src_tags = typename ConformingType::required_src_tags; 114 : static_assert( 115 : tmpl::size<tmpl::list_difference<required_src_tags, 116 : allowed_src_tags>>::value == 0, 117 : "Some of the required source tags are not in the allowed source tags."); 118 : 119 : // Checking this in the grid frame is just a choice, but it suffices to 120 : // check conformance. 121 0 : using allowed_dest_tags = 122 : typename ConformingType::template allowed_dest_tags<Frame::Grid>; 123 0 : using required_dest_tags = 124 : typename ConformingType::template required_dest_tags<Frame::Grid>; 125 : static_assert(tmpl::size<tmpl::list_difference<required_dest_tags, 126 : allowed_dest_tags>>::value == 127 : 0, 128 : "Some of the required destination tags are not in the " 129 : "allowed destination tags."); 130 : }; 131 : }; 132 : } // namespace intrp::protocols