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 : 8 : #include "DataStructures/DataBox/Tag.hpp" 9 : #include "DataStructures/DataBox/TagName.hpp" 10 : #include "DataStructures/SpinWeighted.hpp" 11 : #include "DataStructures/Tags/TempTensor.hpp" 12 : #include "DataStructures/Tensor/Metafunctions.hpp" 13 : #include "DataStructures/Tensor/TypeAliases.hpp" 14 : 15 : /// \cond 16 : class DataVector; 17 : class ModalVector; 18 : class ComplexDataVector; 19 : class ComplexModalVector; 20 : /// \endcond 21 : 22 : namespace Tags { 23 : /// Given the `Tag` holding a `Tensor<DataVector, ...>`, swap the 24 : /// `DataVector` with a `double`. 25 : template <typename Tag> 26 1 : struct Mean : db::SimpleTag, db::PrefixTag { 27 0 : using tag = Tag; 28 : static_assert(std::is_same_v<typename Tag::type::type, DataVector>, 29 : "The Mean tag should only be used on tags that hold " 30 : "Tensors of DataVectors"); 31 0 : using type = TensorMetafunctions::swap_type<double, typename Tag::type>; 32 : }; 33 : 34 : /// Given the `NodalTag` holding a `Tensor<DataVector, ...>`, swap the 35 : /// `DataVector` with a `ModalVector`. 36 : template <typename NodalTag> 37 1 : struct Modal : db::SimpleTag, db::PrefixTag { 38 0 : using tag = NodalTag; 39 : static_assert(std::is_same_v<typename NodalTag::type::type, DataVector>, 40 : "The Modal tag should only be used on tags that hold " 41 : "Tensors of DataVectors"); 42 0 : using type = 43 : TensorMetafunctions::swap_type<ModalVector, typename NodalTag::type>; 44 : }; 45 : 46 : /// Given a Tag with a `type` of `Tensor<VectorType, ...>`, acts as a new 47 : /// version of the tag with `type` of `Tensor<SpinWeighted<VectorType, 48 : /// SpinConstant::value>, ...>`, which is the preferred tensor type associated 49 : /// with spin-weighted quantities. Here, `SpinConstant` must be a 50 : /// `std::integral_constant` or similar type wrapper for a compile-time 51 : /// constant, in order to work properly with DataBox utilities. 52 : /// \note There are restrictions of which vector types can be wrapped 53 : /// by SpinWeighted in a Tensor, so some `Tag`s that have valid `type`s may 54 : /// give rise to compilation errors when used as `Tags::SpinWeighted<Tag, 55 : /// SpinConstant>`. If you find such trouble, consult the whitelist of possible 56 : /// Tensor storage types in `Tensor.hpp`. 57 : template <typename Tag, typename SpinConstant> 58 1 : struct SpinWeighted : db::PrefixTag, db::SimpleTag { 59 : static_assert(not is_any_spin_weighted_v<typename Tag::type::type>, 60 : "The SpinWeighted tag should only be used to create a " 61 : "spin-weighted version of a non-spin-weighted tag. The " 62 : "provided tag already has a spin-weighted type"); 63 0 : using type = TensorMetafunctions::swap_type< 64 : ::SpinWeighted<typename Tag::type::type, SpinConstant::value>, 65 : typename Tag::type>; 66 0 : using tag = Tag; 67 0 : static std::string name() { 68 : return "SpinWeighted(" + db::tag_name<Tag>() + ", " + 69 : std::to_string(SpinConstant::value) + ")"; 70 : } 71 : }; 72 : 73 : /// Succinct alias for often-used nodal spin-weighted temp tag 74 : template <size_t index, int spin> 75 1 : using TempSpinWeightedScalar = 76 : SpinWeighted<TempScalar<index, ComplexDataVector>, 77 : std::integral_constant<int, spin>>; 78 : 79 : /// Succinct alias for often-used modal spin-weighted temp tag 80 : template <size_t index, int spin> 81 1 : using ModalTempSpinWeightedScalar = 82 : SpinWeighted<TempScalar<index, ComplexModalVector>, 83 : std::integral_constant<int, spin>>; 84 : 85 : namespace detail { 86 : template <typename LhsType, typename RhsType> 87 : using product_t = 88 : Scalar<::SpinWeighted<ComplexDataVector, 89 : LhsType::type::spin + RhsType::type::spin>>; 90 : } // namespace detail 91 : 92 : /// A prefix tag representing the product of two other tags. Note that if 93 : /// non-spin-weighted types are needed in this tag, the type alias 94 : /// `detail::product_t` should be generalized to give a reasonable type for 95 : /// those cases, or template specializations should be constructed for this tag. 96 : template <typename LhsTag, typename RhsTag> 97 1 : struct Multiplies : db::PrefixTag, db::SimpleTag { 98 0 : using type = detail::product_t<typename LhsTag::type, typename RhsTag::type>; 99 0 : using tag = LhsTag; 100 0 : static std::string name() { 101 : return "Multiplies(" + db::tag_name<LhsTag>() + ", " + 102 : db::tag_name<RhsTag>() + ")"; 103 : } 104 : }; 105 : 106 : } // namespace Tags