SwshTags.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <string>
7 
8 #include "DataStructures/ComplexDataVector.hpp" // IWYU pragma: keep
9 #include "DataStructures/ComplexModalVector.hpp" // IWYU pragma: keep
11 #include "DataStructures/SpinWeighted.hpp" // IWYU pragma: keep
12 #include "DataStructures/Tensor/Tensor.hpp" // IWYU pragma: keep
13 #include "DataStructures/Tensor/TypeAliases.hpp" // IWYU pragma: keep
14 #include "Utilities/TMPL.hpp"
15 #include "Utilities/TypeTraits.hpp"
16 
17 // IWYU pragma: no_forward_declare SpinWeighted
18 
19 namespace Spectral {
20 namespace Swsh {
21 namespace Tags {
22 
23 /// \ingroup SwshGroup
24 /// \brief Struct for labeling the \f$\eth\f$ spin-weighted derivative in tags
25 struct Eth {};
26 /// \ingroup SwshGroup
27 /// \brief Struct for labeling the \f$\bar{\eth}\f$ spin-weighted derivative in
28 /// tags
29 struct Ethbar {};
30 /// \ingroup SwshGroup
31 /// \brief Struct for labeling the \f$\eth^2\f$ spin-weighted derivative in tags
32 struct EthEth {};
33 /// \ingroup SwshGroup
34 /// \brief Struct for labeling the \f$\bar{\eth} \eth\f$ spin-weighted
35 /// derivative in tags
36 struct EthbarEth {};
37 /// \ingroup SwshGroup
38 /// \brief Struct for labeling the \f$\eth \bar{\eth}\f$ spin-weighted
39 /// derivative in tags
40 struct EthEthbar {};
41 /// \ingroup SwshGroup
42 /// \brief Struct for labeling the \f$\bar{\eth}^2\f$ spin-weighted derivative
43 /// in tags
44 struct EthbarEthbar {};
45 /// \brief Struct which acts as a placeholder for a spin-weighted derivative
46 /// label in the spin-weighted derivative utilities, but represents a 'no-op':
47 /// no derivative is taken.
48 struct NoDerivative {};
49 
50 namespace detail {
51 
52 // utility function for determining the change of spin after a spin-weighted
53 // derivative has been applied.
54 template <typename DerivativeKind>
55 constexpr int derivative_spin_weight_adjustment = 0;
56 
57 template <>
58 constexpr int derivative_spin_weight_adjustment<Eth> = 1;
59 template <>
60 constexpr int derivative_spin_weight_adjustment<Ethbar> = -1;
61 template <>
62 constexpr int derivative_spin_weight_adjustment<EthEth> = 2;
63 template <>
64 constexpr int derivative_spin_weight_adjustment<EthbarEthbar> = -2;
65 
66 // The below tags are used to find the new type represented by the spin-weighted
67 // derivative of a spin-weighted quantity. The derivatives alter the spin
68 // weights, and so the utility `adjust_spin_weight_t<Tag, DerivativeKind>` is a
69 // metafunction that determines the correct spin-weighted type for the
70 // spin-weighted derivative `DerivativeKind` of `Tag`.
71 //
72 // if there is no `Tag::type::spin`, but the internal type is a compatible
73 // complex vector type, the spin associated with `Tag` is assumed to be 0.
74 template <typename DataType, typename DerivativeKind>
75 struct adjust_spin_weight {
76  using type =
77  Scalar<SpinWeighted<DataType,
78  derivative_spin_weight_adjustment<DerivativeKind>>>;
79 };
80 
81 // case for if there is a `Tag::type::spin`
82 template <typename DataType, int Spin, typename DerivativeKind>
83 struct adjust_spin_weight<SpinWeighted<DataType, Spin>, DerivativeKind> {
84  using type = Scalar<SpinWeighted<
85  DataType, Spin + derivative_spin_weight_adjustment<DerivativeKind>>>;
86 };
87 
88 template <typename Tag, typename DerivativeKind>
89 using adjust_spin_weight_t =
90  typename adjust_spin_weight<typename Tag::type::type, DerivativeKind>::type;
91 
92 // Helper function for creating an appropriate prefix tag name from one of the
93 // spin-weighted derivative types and an existing tag name
94 template <typename DerivativeKind>
95 std::string compose_spin_weighted_derivative_name(
96  const std::string& suffix) noexcept;
97 
98 } // namespace detail
99 
100 /// \ingroup SwshGroup
101 /// \brief Prefix tag representing the spin-weighted derivative of a
102 /// spin-weighted scalar.
103 ///
104 /// Template Parameters:
105 /// - `Tag`: The tag to prefix
106 /// - `DerivativeKind`: The type of spin-weighted derivative. This may be any of
107 /// the labeling structs: `Eth`, `Ethbar`, `EthEth`, `EthbarEth`, `EthEthbar`,
108 /// `EthbarEthbar`, or `NoDerivative`.
109 ///
110 /// Type Aliases and static values:
111 /// - `type`: Always a `SpinWeighted<Scalar<ComplexDataVector>, Spin>`, where
112 /// `Spin` is the spin weight after the derivative `DerivativeKind` has been
113 /// applied.
114 /// - `tag`: An alias to the wrapped tag `Tag`. Provided for applicability to
115 /// general `db::PrefixTag` functionality.
116 /// - `derived_from`: Another alias to the wrapped tag `Tag`. Provided so that
117 /// utilities that use this prefix for taking derivatives can have a more
118 /// expressive code style.
119 /// - `derivative_kind`: Type alias to `DerivativeKind`, represents the kind of
120 /// spin-weighted derivative applied to `Tag`
121 /// - `spin`: The spin weight of the scalar after the derivative has been
122 /// applied.
123 template <typename Tag, typename DerivativeKind>
125  using type = detail::adjust_spin_weight_t<Tag, DerivativeKind>;
126  using tag = Tag;
127  // derived_from is provided as a second alias so that utilities that assume a
128  // derivative prefix tag fail earlier during compilation
129  using derived_from = Tag;
130  using derivative_kind = DerivativeKind;
131  const static int spin = type::type::spin;
132  static std::string name() noexcept {
133  return detail::compose_spin_weighted_derivative_name<DerivativeKind>(
134  Tag::name());
135  }
136 };
137 
138 /// \ingroup SwshGroup
139 /// \brief Prefix tag representing the spin-weighted spherical harmonic
140 /// transform of a spin-weighted scalar.
141 ///
142 /// Template Parameters:
143 /// - `Tag`: The tag to prefix.
144 ///
145 /// Type aliases and static values:
146 /// - `type`: Always a `SpinWeighted<Scalar<ComplexModalVector>, Spin>`, where
147 /// `Spin` is the same spin weight of the pre-transformed `Tag`, and 0 if
148 /// provided a `Tag` with a `Type` that is not `SpinWeighted`
149 /// - `tag`: An alias to the wrapped tag `Tag`. Provided for applicability to
150 /// general `db::PrefixTag` functionality
151 /// - `transform_of`: Another alias to the wrapped tag `Tag`. Provided so that
152 /// utilities that use this prefix for taking transforms can have a more
153 /// expressive code style.
154 template <typename Tag>
156  using type = Scalar<SpinWeighted<
158  detail::adjust_spin_weight_t<Tag, NoDerivative>::type::spin>>;
159  using tag = Tag;
160  // transform_of is provided as a second alias so that utilities that assume a
161  // derivative prefix tag fail earlier during compilation
162  using transform_of = Tag;
163  const static int spin = type::type::spin;
164  static std::string name() noexcept {
165  return "SwshTransform(" + Tag::name() + ")";
166  }
167 };
168 } // namespace Tags
169 
170 namespace detail {
171 // implementation for get_tags_with_spin
172 template <typename Tag, typename S>
173 struct has_spin : cpp17::bool_constant<Tag::type::type::spin == S::value> {};
174 
175 template <typename PrefixTag, typename S>
176 struct wrapped_has_spin : has_spin<typename PrefixTag::tag, S> {};
177 
178 } // namespace detail
179 
180 /// \ingroup SwshGroup
181 /// \brief Extract from `TagList` the subset of those tags that have a static
182 /// int member `spin` equal to the template parameter `Spin`.
183 ///
184 /// \snippet Test_SwshTags.cpp get_tags_with_spin
185 template <int Spin, typename TagList>
186 using get_tags_with_spin = tmpl::remove_duplicates<tmpl::filter<
187  TagList, detail::has_spin<tmpl::_1, std::integral_constant<int, Spin>>>>;
188 
189 /// \ingroup SwshGroup
190 /// \brief Extract from `TagList` the subset of those tags that wrap a tag
191 /// that has a static int member `spin` equal to the template parameter `Spin`.
192 ///
193 /// \snippet Test_SwshTags.cpp get_prefix_tags_that_wrap_tags_with_spin
194 template <int Spin, typename TagList>
196  tmpl::filter<TagList, tmpl::bind<detail::wrapped_has_spin, tmpl::_1,
198 
199 } // namespace Swsh
200 } // namespace Spectral
tmpl::filter< TagList, tmpl::bind< detail::wrapped_has_spin, tmpl::_1, std::integral_constant< int, Spin > >> get_prefix_tags_that_wrap_tags_with_spin
Extract from TagList the subset of those tags that wrap a tag that has a static int member spin equal...
Definition: SwshTags.hpp:197
Struct which acts as a placeholder for a spin-weighted derivative label in the spin-weighted derivati...
Definition: SwshTags.hpp:48
Struct for labeling the spin-weighted derivative in tags.
Definition: SwshTags.hpp:44
Tags for the DataBox inherit from this type.
Definition: DataBoxTag.hpp:65
Struct for labeling the spin-weighted derivative in tags.
Definition: SwshTags.hpp:36
Prefix tag representing the spin-weighted spherical harmonic transform of a spin-weighted scalar...
Definition: SwshTags.hpp:155
Prefix tag representing the spin-weighted derivative of a spin-weighted scalar.
Definition: SwshTags.hpp:124
tmpl::remove_duplicates< tmpl::filter< TagList, detail::has_spin< tmpl::_1, std::integral_constant< int, Spin > >> > get_tags_with_spin
Extract from TagList the subset of those tags that have a static int member spin equal to the templat...
Definition: SwshTags.hpp:187
Definition: Determinant.hpp:11
Make a spin-weighted type T with spin-weight Spin. Mathematical operators are restricted to addition...
Definition: SpinWeighted.hpp:24
A class for storing complex spectral coefficients on a spectral grid.
Definition: ComplexModalVector.hpp:39
Definition: DataBoxTag.hpp:29
Defines classes for Tensor.
Defines a list of useful type aliases for tensors.
Struct for labeling the spin-weighted derivative in tags.
Definition: SwshTags.hpp:25
Wraps the template metaprogramming library used (brigand)
Struct for labeling the spin-weighted derivative in tags.
Definition: SwshTags.hpp:32
Functionality associated with a particular choice of basis functions and quadrature for spectral oper...
Definition: Chebyshev.cpp:19
Marks an item as being a prefix to another tag.
Definition: DataBoxTag.hpp:112
Struct for labeling the spin-weighted derivative in tags.
Definition: SwshTags.hpp:40
Defines classes SimpleTag, PrefixTag, ComputeTag and several functions for retrieving tag info...
Defines type traits, some of which are future STL type_traits header.
Tensor< T, Symmetry<>, index_list<> > Scalar
Scalar type.
Definition: TypeAliases.hpp:21
Struct for labeling the spin-weighted derivative in tags.
Definition: SwshTags.hpp:29