9 #include "DataStructures/ComplexDataVector.hpp"
10 #include "DataStructures/ComplexDiagonalModalOperator.hpp"
11 #include "DataStructures/ComplexModalVector.hpp"
12 #include "DataStructures/DataVector.hpp"
13 #include "DataStructures/SpinWeighted.hpp"
14 #include "DataStructures/Tags/TempTensor.hpp"
15 #include "DataStructures/TempBuffer.hpp"
16 #include "NumericalAlgorithms/Spectral/ComplexDataView.hpp"
17 #include "NumericalAlgorithms/Spectral/SwshCoefficients.hpp"
18 #include "NumericalAlgorithms/Spectral/SwshCollocation.hpp"
19 #include "NumericalAlgorithms/Spectral/SwshSettings.hpp"
20 #include "NumericalAlgorithms/Spectral/SwshTags.hpp"
21 #include "NumericalAlgorithms/Spectral/SwshTransform.hpp"
35 template <
typename DerivativeKind>
41 const int l,
const int s) noexcept {
47 const int l,
const int s) noexcept {
53 const int l,
const int s) noexcept {
55 (l - s) * (l + s + 1)));
60 derivative_factor<Tags::EthbarEthbar>(
const int l,
const int s) noexcept {
62 (l + s) * (l - s + 1)));
67 const int l,
const int s) noexcept {
73 const int l,
const int s) noexcept {
79 const int l,
const int s) noexcept {
80 return (l - s + 1) * (l + s) == 0
88 derivative_factor<Tags::InverseEthbar>(
const int l,
const int s) noexcept {
89 return (l + s + 1) * (l - s) == 0
98 template <
typename DerivativeKind,
int Spin>
99 void compute_coefficients_of_derivative(
102 Spin + Tags::derivative_spin_weight<DerivativeKind>>*>
105 size_t l_max,
size_t number_of_radial_points) noexcept;
112 template <
typename DerivativeTag,
typename PreDerivativeTagList>
113 struct dispatch_to_compute_coefficients_of_derivative {
114 template <
int Spin,
typename... ModalTypes>
119 const size_t number_of_radial_points) noexcept {
120 compute_coefficients_of_derivative<typename DerivativeTag::derivative_kind>(
122 get<tmpl::index_of<PreDerivativeTagList,
123 typename DerivativeTag::derivative_of>::value>(
124 pre_derivative_mode_tuple),
125 l_max, number_of_radial_points);
144 template <
typename Transform,
typename TagList>
145 struct dispatch_to_transform;
149 struct dispatch_to_transform<
150 SwshTransform<tmpl::list<TransformTags...>, Representation>, TagList> {
151 template <
typename... ModalTypes,
typename... NodalTypes>
155 const size_t number_of_radial_points) noexcept {
156 SwshTransform<tmpl::list<TransformTags...>, Representation>::
158 get<tmpl::index_of<TagList, TransformTags>::value>(*modal_tuple)...,
159 get<tmpl::index_of<TagList, TransformTags>::value>(nodal_tuple)...,
160 l_max, number_of_radial_points);
166 struct dispatch_to_transform<
167 InverseSwshTransform<tmpl::list<TransformTags...>, Representation>,
169 template <
typename... NodalTypes,
typename... ModalTypes>
173 const size_t number_of_radial_points) noexcept {
174 InverseSwshTransform<tmpl::list<TransformTags...>, Representation>::
176 get<tmpl::index_of<TagList, TransformTags>::value>(*nodal_tuple)...,
177 *
get<tmpl::index_of<TagList, TransformTags>::value>(modal_tuple)...,
178 l_max, number_of_radial_points);
185 template <
typename DerivativeTagList,
typename UniqueDifferentiatedFromTagList,
187 struct AngularDerivativesImpl;
189 template <
typename... DerivativeTags,
typename... UniqueDifferentiatedFromTags,
191 struct AngularDerivativesImpl<tmpl::list<DerivativeTags...>,
192 tmpl::list<UniqueDifferentiatedFromTags...>,
195 tmpl::list<DerivativeTags..., Tags::SwshTransform<DerivativeTags>...,
196 Tags::SwshTransform<UniqueDifferentiatedFromTags>...>;
197 using argument_tags =
198 tmpl::list<UniqueDifferentiatedFromTags..., Tags::LMaxBase,
199 Tags::NumberOfRadialPointsBase>;
204 DerivativeTags>::type*>... transform_of_derivative_scalars,
206 UniqueDifferentiatedFromTags>::type*>... transform_of_input_scalars,
207 const typename UniqueDifferentiatedFromTags::type&... input_scalars,
208 const size_t l_max,
const size_t number_of_radial_points) noexcept {
212 get(input_scalars)..., l_max, number_of_radial_points);
216 typename... DerivativeKinds,
typename... ArgumentTypes,
219 friend void angular_derivatives_impl(
227 static void apply_to_vectors(
229 DerivativeTags>::type::type*>... transform_of_derivatives,
231 UniqueDifferentiatedFromTags>::type::type*>... transform_of_inputs,
233 const typename UniqueDifferentiatedFromTags::type::type&... inputs,
234 const size_t l_max,
const size_t number_of_radial_points) noexcept {
237 using ForwardTransformList =
239 tmpl::list<DerivativeTags...>>;
241 tmpl::for_each<ForwardTransformList>(
242 [&number_of_radial_points, &l_max, &inputs...,
243 &transform_of_inputs...](
auto transform_v) noexcept {
244 using transform = typename decltype(transform_v)::type;
245 auto input_transforms = std::make_tuple(transform_of_inputs...);
246 dispatch_to_transform<transform,
247 tmpl::list<UniqueDifferentiatedFromTags...>>::
248 apply(make_not_null(&input_transforms),
249 std::forward_as_tuple(inputs...), l_max,
250 number_of_radial_points);
256 dispatch_to_compute_coefficients_of_derivative<
257 DerivativeTags, tmpl::list<UniqueDifferentiatedFromTags...>>::
258 apply(transform_of_derivatives,
259 std::make_tuple(transform_of_inputs...), l_max,
260 number_of_radial_points));
264 using InverseTransformList =
265 make_inverse_transform_list<Representation,
266 tmpl::list<DerivativeTags...>>;
268 tmpl::for_each<InverseTransformList>([&number_of_radial_points, &l_max,
270 &transform_of_derivatives...](
271 auto transform_v) noexcept {
272 using transform = typename decltype(transform_v)::type;
273 auto derivative_tuple = std::make_tuple(derivatives...);
274 dispatch_to_transform<transform, tmpl::list<DerivativeTags...>>::apply(
275 make_not_null(&derivative_tuple),
276 std::make_tuple(transform_of_derivatives...), l_max,
277 number_of_radial_points);
284 template <
typename DerivativeTagList>
285 struct unique_derived_from_list;
287 template <
typename... DerivativeTags>
288 struct unique_derived_from_list<tmpl::list<DerivativeTags...>> {
289 using type = tmpl::remove_duplicates<
290 tmpl::list<
typename DerivativeTags::derivative_of...>>;
323 ComplexRepresentation::Interleaved>
326 typename detail::unique_derived_from_list<DerivativeTagList>::type,
343 const size_t number_of_radial_points) noexcept {
353 typename... ArgumentTypes,
size_t... Is>
354 void angular_derivatives_impl(
357 tmpl::list<DerivativeKinds...> ,
360 tmpl::list<Tags::Derivative<
365 argument_tuple))>::spin>>,
366 DerivativeKinds>...>,
367 Representation>::apply_to_vectors(get<Is>(argument_tuple)...,
368 get<Is +
sizeof...(Is)>(
370 get<Is + 2 *
sizeof...(Is)>(
372 get<Is + 3 *
sizeof...(Is)>(
374 l_max, number_of_radial_points);
378 typename... ArgumentTypes,
size_t... Is>
379 void angular_derivatives_impl(
381 const size_t number_of_radial_points,
383 tmpl::list<DerivativeKinds...> derivative_kinds,
385 auto derivative_buffer_tuple = std::make_tuple(
387 l_max, number_of_radial_points)...);
388 auto input_buffer_tuple = std::make_tuple(
390 argument_tuple))>::spin>(l_max, number_of_radial_points)...);
391 angular_derivatives_impl<Representation>(
392 std::forward_as_tuple(
make_not_null(&get<Is>(derivative_buffer_tuple))...,
394 get<Is>(argument_tuple)...,
395 get<Is +
sizeof...(Is)>(argument_tuple)...),
396 l_max, number_of_radial_points, index_sequence, derivative_kinds,
454 typename DerivativeKindList,
456 typename... ArgumentTypes>
458 const size_t number_of_radial_points,
459 const ArgumentTypes&... arguments) noexcept {
461 tmpl::size<DerivativeKindList>::value * 2 ==
sizeof...(ArgumentTypes) or
462 tmpl::size<DerivativeKindList>::value * 4 ==
sizeof...(ArgumentTypes),
463 "When using the tagless `angular_derivatives` interface, you must "
464 "provide either one nodal input and one nodal output per derivative "
465 "or one nodal input, one nodal output, and two appropriate "
466 "intermediate transform buffers per derivative.");
468 detail::angular_derivatives_impl<Representation>(
469 std::forward_as_tuple(arguments...), l_max, number_of_radial_points,
471 DerivativeKindList{},
473 sizeof...(ArgumentTypes)>{});
487 size_t l_max,
size_t number_of_radial_points,