10 #include "DataStructures/ComplexDataVector.hpp"
12 #include "DataStructures/Tags.hpp"
15 #include "Evolution/Systems/Cce/IntegrandInputSteps.hpp"
16 #include "Evolution/Systems/Cce/Tags.hpp"
19 #include "NumericalAlgorithms/Spectral/SwshDerivatives.hpp"
20 #include "NumericalAlgorithms/Spectral/SwshTags.hpp"
23 #include "Utilities/TypeTraits.hpp"
24 #include "Utilities/TypeTraits/IsA.hpp"
44 template <
typename Tag,
typename SpinConstant,
typename Select>
45 struct OnDemandInputsForSwshJacobianImpl;
49 template <
typename Tag>
50 struct OnDemandInputsForSwshJacobianImpl<
53 not tt::is_a_v<Tags::Dy, Tag>>> {
54 template <
typename DataBoxTagList>
56 const
db::DataBox<DataBoxTagList>& box) noexcept {
57 return get(
db::get<Tags::Dy<Tag>>(box)).data();
63 template <
typename Tag>
64 struct OnDemandInputsForSwshJacobianImpl<
67 template <
typename DataBoxTagList>
69 const
db::DataBox<DataBoxTagList>& box) noexcept {
70 return get(
db::get<Tags::Dy<Tags::Dy<Tag>>>(box)).data();
76 template <
typename LhsTag,
typename RhsTag>
77 struct OnDemandInputsForSwshJacobianImpl<
78 Tags::Dy<::Tags::Multiplies<LhsTag, RhsTag>>,
80 LhsTag::type::type::spin + RhsTag::type::type::spin>,
82 not std::is_same_v<LhsTag, Tags::BondiUbar> and
83 not std::is_same_v<RhsTag, Tags::BondiJbar>>> {
84 template <
typename DataBoxTagList>
86 const
db::DataBox<DataBoxTagList>& box) noexcept {
87 decltype(
auto) lhs =
get(
db::
get<LhsTag>(box)).data();
88 decltype(auto) dy_lhs =
get(
db::
get<Tags::Dy<LhsTag>>(box)).data();
89 decltype(auto) rhs =
get(
db::
get<RhsTag>(box)).data();
90 decltype(auto) dy_rhs =
get(
db::
get<Tags::Dy<RhsTag>>(box)).data();
91 return lhs * dy_rhs + dy_lhs * rhs;
98 template <typename LhsTag>
99 struct OnDemandInputsForSwshJacobianImpl<
100 Tags::Dy<::Tags::Multiplies<LhsTag, Tags::BondiJbar>>,
101 std::integral_constant<
int, LhsTag::type::type::spin - 2>, std::true_type> {
102 template <
typename DataBoxTagList>
104 const
db::DataBox<DataBoxTagList>& box) noexcept {
105 decltype(
auto) lhs =
get(
get<LhsTag>(box)).data();
106 decltype(auto) dy_lhs =
get(
get<Tags::Dy<LhsTag>>(box)).data();
107 decltype(auto) jbar = conj(
get(
get<Tags::BondiJ>(box)).data());
108 decltype(auto) dy_jbar = conj(
get(
get<Tags::Dy<Tags::BondiJ>>(box)).data());
109 return lhs * dy_jbar + dy_lhs * jbar;
116 template <typename RhsTag>
117 struct OnDemandInputsForSwshJacobianImpl<
118 Tags::Dy<::Tags::Multiplies<Tags::BondiJbar, RhsTag>>,
119 std::integral_constant<
int, RhsTag::type::type::spin - 2>, std::true_type> {
120 template <
typename DataBoxTagList>
122 const
db::DataBox<DataBoxTagList>& box) noexcept {
123 decltype(
auto) rhs =
get(
get<RhsTag>(box)).data();
124 decltype(auto) dy_rhs =
get(
get<Tags::Dy<RhsTag>>(box)).data();
125 decltype(auto) jbar = conj(
get(
get<Tags::BondiJ>(box)).data());
126 decltype(auto) dy_jbar = conj(
get(
get<Tags::Dy<Tags::BondiJ>>(box)).data());
127 return dy_jbar * rhs + jbar * dy_rhs;
134 template <typename RhsTag>
135 struct OnDemandInputsForSwshJacobianImpl<
136 Tags::Dy<::Tags::Multiplies<Tags::BondiUbar, RhsTag>>,
137 std::integral_constant<
int, RhsTag::type::type::spin - 1>, std::true_type> {
138 template <
typename DataBoxTagList>
140 const
db::DataBox<DataBoxTagList>& box) noexcept {
141 decltype(
auto) ubar = conj(
get(
get<Tags::BondiU>(box)).data());
142 decltype(auto) dy_ubar = conj(
get(
get<Tags::Dy<Tags::BondiU>>(box)).data());
143 decltype(auto) rhs =
get(
get<RhsTag>(box)).data();
144 decltype(auto) dy_rhs =
get(
get<Tags::Dy<RhsTag>>(box)).data();
145 return ubar * dy_rhs + dy_ubar * rhs;
152 template <typename LhsTag>
153 struct OnDemandInputsForSwshJacobianImpl<
154 Tags::Dy<Tags::Dy<::Tags::Multiplies<LhsTag, Tags::BondiJbar>>>,
155 std::integral_constant<
int, LhsTag::type::type::spin - 2>, std::true_type> {
156 template <
typename DataBoxTagList>
158 const
db::DataBox<DataBoxTagList>& box) noexcept {
159 decltype(
auto) lhs =
get(
get<LhsTag>(box)).data();
160 decltype(auto) dy_lhs =
get(
get<Tags::Dy<LhsTag>>(box)).data();
161 decltype(auto) dy_dy_lhs =
get(
get<Tags::Dy<Tags::Dy<LhsTag>>>(box)).data();
162 decltype(auto) jbar = conj(
get(
get<Tags::BondiJ>(box)).data());
163 decltype(auto) dy_jbar = conj(
get(
get<Tags::Dy<Tags::BondiJ>>(box)).data());
164 decltype(auto) dy_dy_jbar =
165 conj(
get(
get<Tags::Dy<Tags::Dy<Tags::BondiJ>>>(box)).data());
166 return lhs * dy_dy_jbar + 2.0 * dy_lhs * dy_jbar + dy_dy_lhs * jbar;
172 template <typename Tag, typename DerivKind>
173 struct OnDemandInputsForSwshJacobianImpl<
174 Spectral::Swsh::Tags::Derivative<Tags::Dy<Tag>, DerivKind>,
175 std::integral_constant<
176 int,
Spectral::Swsh::Tags::Derivative<Tags::Dy<Tag>, DerivKind>::spin>,
178 template <
typename DataBoxTagList>
180 const
db::DataBox<DataBoxTagList>& box) noexcept {
191 struct OnDemandInputsForSwshJacobianImpl<Tags::Dy<Tags::JbarQMinus2EthBeta>,
194 template <
typename DataBoxTagList>
196 const
db::DataBox<DataBoxTagList>& box) noexcept {
197 decltype(
auto) dy_beta =
get(
get<Tags::Dy<Tags::BondiBeta>>(box)).data();
198 decltype(auto) dy_j =
get(
get<Tags::Dy<Tags::BondiJ>>(box)).data();
199 decltype(auto) dy_q =
get(
get<Tags::Dy<Tags::BondiQ>>(box)).data();
200 decltype(auto) eth_beta =
205 decltype(auto) eth_dy_beta =
206 get(
get<
Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::BondiBeta>,
210 decltype(auto) eth_r_divided_by_r =
211 get(
get<Tags::EthRDividedByR>(box)).data();
212 decltype(auto) j =
get(
get<Tags::BondiJ>(box)).data();
213 decltype(auto) q =
get(
get<Tags::BondiQ>(box)).data();
214 return conj(j) * dy_q + conj(dy_j) * q - 2.0 * conj(j) * eth_dy_beta -
215 2.0 * eth_beta * conj(dy_j) -
216 2.0 * conj(j) * eth_r_divided_by_r * dy_beta;
225 template <typename Tag>
227 Tag, std::integral_constant<
int, Tag::type::type::spin>, std::true_type>;
247 template <typename DerivativeTag>
261 template <typename ArgumentTag>
264 using pre_swsh_derivative_tags = tmpl::list<>;
265 using swsh_derivative_tags = tmpl::list<>;
266 using integration_independent_tags =
267 tmpl::list<Tags::OneMinusY, Tags::EthRDividedByR>;
269 using return_tags = tmpl::list<
271 using argument_tags = tmpl::append<integration_independent_tags>;
272 using on_demand_argument_tags = tmpl::list<Tags::Dy<ArgumentTag>>;
274 static constexpr
int spin =
277 template <
typename DyArgumentType>
283 const DyArgumentType& dy_argument) {
284 get(*eth_argument) -=
get(one_minus_y) *
get(eth_r_divided_by_r) *
303 template <
typename ArgumentTag>
305 ArgumentTag, Spectral::Swsh::Tags::Ethbar>> {
306 using pre_swsh_derivative_tags = tmpl::list<>;
307 using swsh_derivative_tags = tmpl::list<>;
308 using integration_independent_tags =
309 tmpl::list<Tags::OneMinusY, Tags::EthRDividedByR>;
313 using argument_tags = tmpl::append<integration_independent_tags>;
314 using on_demand_argument_tags = tmpl::list<Tags::Dy<ArgumentTag>>;
316 static constexpr
int spin =
319 template <
typename DyArgumentType>
325 const DyArgumentType& dy_argument) {
326 get(*ethbar_argument) -=
327 get(one_minus_y) * conj(
get(eth_r_divided_by_r)) *
349 template <
typename ArgumentTag>
351 ArgumentTag, Spectral::Swsh::Tags::EthEthbar>> {
352 using pre_swsh_derivative_tags = tmpl::list<>;
353 using swsh_derivative_tags = tmpl::list<>;
354 using integration_independent_tags =
360 using argument_tags = tmpl::append<integration_independent_tags>;
361 using on_demand_argument_tags =
368 static constexpr
int spin =
371 template <
typename DyArgumentType,
typename DyDyArgumentType,
372 typename EthDyArgumentType,
typename EthbarDyArgumentType>
379 eth_ethbar_r_divided_by_r,
380 const DyArgumentType& dy_argument,
const DyDyArgumentType& dy_dy_argument,
381 const EthDyArgumentType& eth_dy_argument,
382 const EthbarDyArgumentType ethbar_dy_argument) {
383 get(*eth_ethbar_argument) -=
384 get(eth_r_divided_by_r) * conj(
get(eth_r_divided_by_r)) *
388 (
get(eth_r_divided_by_r) *
390 ethbar_dy_argument} +
391 conj(
get(eth_r_divided_by_r)) *
393 get(eth_ethbar_r_divided_by_r) *
415 template <
typename ArgumentTag>
417 ArgumentTag, Spectral::Swsh::Tags::EthbarEth>> {
418 using pre_swsh_derivative_tags = tmpl::list<>;
419 using swsh_derivative_tags = tmpl::list<>;
420 using integration_independent_tags =
426 using argument_tags = tmpl::append<integration_independent_tags>;
427 using on_demand_argument_tags =
434 static constexpr
int spin =
437 template <
typename DyArgumentType,
typename DyDyArgumentType,
438 typename EthDyArgumentType,
typename EthbarDyArgumentType>
445 eth_ethbar_r_divided_by_r,
446 const DyArgumentType& dy_argument,
const DyDyArgumentType& dy_dy_argument,
447 const EthDyArgumentType& eth_dy_argument,
448 const EthbarDyArgumentType ethbar_dy_argument) {
449 get(*ethbar_eth_argument) -=
450 get(eth_r_divided_by_r) * conj(
get(eth_r_divided_by_r)) *
454 (
get(eth_r_divided_by_r) *
456 ethbar_dy_argument} +
457 conj(
get(eth_r_divided_by_r)) *
459 get(eth_ethbar_r_divided_by_r) *
480 template <
typename ArgumentTag>
482 ArgumentTag, Spectral::Swsh::Tags::EthEth>> {
483 using pre_swsh_derivative_tags = tmpl::list<>;
484 using swsh_derivative_tags = tmpl::list<>;
485 using integration_independent_tags =
491 using argument_tags = tmpl::append<integration_independent_tags>;
492 using on_demand_argument_tags =
497 static constexpr
int spin =
500 template <
typename DyArgumentType,
typename DyDyArgumentType,
501 typename EthDyArgumentType>
508 const DyArgumentType& dy_argument,
const DyDyArgumentType& dy_dy_argument,
509 const EthDyArgumentType& eth_dy_argument) {
510 get(*eth_eth_argument) -=
513 SpinWeighted<DyDyArgumentType, spin - 2>{dy_dy_argument}) +
515 (2.0 *
get(eth_r_divided_by_r) *
516 SpinWeighted<EthDyArgumentType, spin - 1>{eth_dy_argument} +
517 get(eth_eth_r_divided_by_r) *
539 template <
typename ArgumentTag>
541 ArgumentTag, Spectral::Swsh::Tags::EthbarEthbar>> {
542 using pre_swsh_derivative_tags = tmpl::list<>;
543 using swsh_derivative_tags = tmpl::list<>;
544 using integration_independent_tags =
550 using argument_tags = tmpl::append<integration_independent_tags>;
551 using on_demand_argument_tags =
558 template <
typename DyArgumentType,
typename DyDyArgumentType,
559 typename EthbarDyArgumentType>
562 ethbar_ethbar_argument,
566 const DyArgumentType& dy_argument,
const DyDyArgumentType& dy_dy_argument,
567 const EthbarDyArgumentType& ethbar_dy_argument) {
568 get(*ethbar_ethbar_argument) -=
573 (2.0 * conj(
get(eth_r_divided_by_r)) *
575 ethbar_dy_argument} +
576 conj(
get(eth_eth_r_divided_by_r)) *
588 template <
typename DerivativeTag,
typename DataBoxTagList,
589 typename... OnDemandTags>
590 void apply_swsh_jacobian_helper(
592 tmpl::list<OnDemandTags...> ) noexcept {
593 db::mutate_apply<ApplySwshJacobianInplace<DerivativeTag>>(
615 template <
typename BondiValueTag,
typename DataBoxTagList>
617 const gsl::not_null<db::DataBox<DataBoxTagList>*> box) noexcept {
624 single_swsh_derivative_tags_to_compute_for_t<BondiValueTag>>>(box);
625 tmpl::for_each<single_swsh_derivative_tags_to_compute_for_t<BondiValueTag>>(
626 [&box](
auto derivative_tag_v) noexcept {
627 using derivative_tag =
typename decltype(derivative_tag_v)::type;
628 detail::apply_swsh_jacobian_helper<derivative_tag>(
630 derivative_tag>::on_demand_argument_tags{});
634 second_swsh_derivative_tags_to_compute_for_t<BondiValueTag>>>(box);
635 tmpl::for_each<second_swsh_derivative_tags_to_compute_for_t<BondiValueTag>>(
636 [&box](
auto derivative_tag_v) noexcept {
637 using derivative_tag =
typename decltype(derivative_tag_v)::type;
638 detail::apply_swsh_jacobian_helper<derivative_tag>(
640 derivative_tag>::on_demand_argument_tags{});