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
|