9 #include "DataStructures/DataBox/PrefixHelpers.hpp"
11 #include "DataStructures/DataVector.hpp"
12 #include "DataStructures/SpinWeighted.hpp"
15 #include "Evolution/Systems/Cce/BoundaryDataTags.hpp"
16 #include "Evolution/Systems/Cce/Tags.hpp"
17 #include "NumericalAlgorithms/Spectral/SwshCollocation.hpp"
18 #include "NumericalAlgorithms/Spectral/SwshDerivatives.hpp"
19 #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/Phi.hpp"
20 #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/TimeDerivOfLapse.hpp"
21 #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/TimeDerivOfShift.hpp"
22 #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/TimeDerivativeOfSpacetimeMetric.hpp"
23 #include "PointwiseFunctions/GeneralRelativity/Lapse.hpp"
24 #include "PointwiseFunctions/GeneralRelativity/Shift.hpp"
25 #include "PointwiseFunctions/GeneralRelativity/SpacetimeMetric.hpp"
26 #include "PointwiseFunctions/GeneralRelativity/SpacetimeNormalVector.hpp"
27 #include "PointwiseFunctions/GeneralRelativity/SpatialMetric.hpp"
28 #include "PointwiseFunctions/GeneralRelativity/TimeDerivativeOfSpacetimeMetric.hpp"
81 inverse_cartesian_to_spherical_jacobian,
84 double extraction_radius) noexcept;
97 void cartesian_spatial_metric_and_derivatives_from_modes(
98 gsl::not_null<tnsr::ii<DataVector, 3>*> cartesian_spatial_metric,
99 gsl::not_null<tnsr::II<DataVector, 3>*> inverse_cartesian_spatial_metric,
100 gsl::not_null<tnsr::ijj<DataVector, 3>*> d_cartesian_spatial_metric,
101 gsl::not_null<tnsr::ii<DataVector, 3>*> dt_cartesian_spatial_metric,
103 interpolation_modal_buffer,
105 interpolation_buffer,
107 const tnsr::ii<ComplexModalVector, 3>& spatial_metric_coefficients,
108 const tnsr::ii<ComplexModalVector, 3>& dr_spatial_metric_coefficients,
109 const tnsr::ii<ComplexModalVector, 3>& dt_spatial_metric_coefficients,
110 const CartesianiSphericalJ& inverse_cartesian_to_spherical_jacobian,
111 size_t l_max) noexcept;
129 interpolation_modal_buffer,
131 interpolation_buffer,
133 const tnsr::I<ComplexModalVector, 3>& shift_coefficients,
134 const tnsr::I<ComplexModalVector, 3>& dr_shift_coefficients,
135 const tnsr::I<ComplexModalVector, 3>& dt_shift_coefficients,
136 const CartesianiSphericalJ& inverse_cartesian_to_spherical_jacobian,
137 size_t l_max) noexcept;
155 interpolation_modal_buffer,
157 interpolation_buffer,
162 const CartesianiSphericalJ& inverse_cartesian_to_spherical_jacobian,
163 size_t l_max) noexcept;
192 gsl::not_null<tnsr::aa<DataVector, 3, Frame::RadialNull>*> du_null_metric,
193 gsl::not_null<tnsr::aa<DataVector, 3, Frame::RadialNull>*> null_metric,
194 const SphericaliCartesianJ& cartesian_to_spherical_jacobian,
195 const tnsr::aa<DataVector, 3>& dt_spacetime_metric,
213 const tnsr::aa<DataVector, 3>& dt_spacetime_metric,
215 const tnsr::II<DataVector, 3>& inverse_spatial_metric) noexcept;
231 const tnsr::I<DataVector, 3>& dt_worldtube_normal,
233 const tnsr::aa<DataVector, 3>& dt_spacetime_metric,
236 const tnsr::I<DataVector, 3>&
shift,
237 const tnsr::I<DataVector, 3>& worldtube_normal) noexcept;
254 dlambda_inverse_null_metric,
255 const AngulariCartesianA& angular_d_null_l,
256 const SphericaliCartesianJ& cartesian_to_spherical_jacobian,
257 const tnsr::iaa<DataVector, 3>&
phi,
258 const tnsr::aa<DataVector, 3>& dt_spacetime_metric,
259 const tnsr::A<DataVector, 3>& du_null_l,
260 const tnsr::AA<DataVector, 3, Frame::RadialNull>& inverse_null_metric,
261 const tnsr::A<DataVector, 3>& null_l,
280 const tnsr::aa<DataVector, 3, Frame::RadialNull>& null_metric) noexcept;
301 const tnsr::aa<DataVector, 3, Frame::RadialNull>& dlambda_null_metric,
302 const tnsr::aa<DataVector, 3, Frame::RadialNull>& du_null_metric,
303 const tnsr::AA<DataVector, 3, Frame::RadialNull>& inverse_null_metric,
304 size_t l_max) noexcept;
323 gsl::not_null<tnsr::i<ComplexDataVector, 2, Frame::RadialNull>*> down_dyad,
324 gsl::not_null<tnsr::I<ComplexDataVector, 2, Frame::RadialNull>*>
341 const tnsr::a<DataVector, 3, Frame::RadialNull>&
d_bondi_r) noexcept;
358 const tnsr::i<ComplexDataVector, 2, Frame::RadialNull>& dyad,
359 const tnsr::a<DataVector, 3, Frame::RadialNull>&
d_bondi_r,
360 const tnsr::AA<DataVector, 3, Frame::RadialNull>&
361 inverse_null_metric) noexcept;
380 const tnsr::a<DataVector, 3, Frame::RadialNull>&
d_bondi_r,
381 const tnsr::AA<DataVector, 3, Frame::RadialNull>& inverse_null_metric,
395 const tnsr::aa<DataVector, 3, Frame::RadialNull>& null_metric,
397 const tnsr::I<ComplexDataVector, 2, Frame::RadialNull>& dyad) noexcept;
417 const tnsr::aa<DataVector, 3, Frame::RadialNull>& dlambda_null_metric,
418 const tnsr::a<DataVector, 3, Frame::RadialNull>&
d_bondi_r,
421 const tnsr::I<ComplexDataVector, 2, Frame::RadialNull>& dyad) noexcept;
443 const tnsr::a<DataVector, 3, Frame::RadialNull>&
d_bondi_r,
481 const tnsr::AA<DataVector, 3, Frame::RadialNull>&
482 dlambda_inverse_null_metric,
483 const tnsr::a<DataVector, 3, Frame::RadialNull>&
d_bondi_r,
484 const tnsr::i<ComplexDataVector, 2, Frame::RadialNull>& dyad,
485 const tnsr::i<DataVector, 2, Frame::RadialNull>& angular_d_dlambda_r,
486 const tnsr::AA<DataVector, 3, Frame::RadialNull>& inverse_null_metric,
512 const tnsr::a<DataVector, 3, Frame::RadialNull>&
d_bondi_r,
514 const tnsr::aa<DataVector, 3, Frame::RadialNull>& du_null_metric,
516 const tnsr::I<ComplexDataVector, 2, Frame::RadialNull>& dyad) noexcept;
538 const tnsr::a<DataVector, 3, Frame::RadialNull>&
d_bondi_r,
540 const tnsr::aa<DataVector, 3, Frame::RadialNull>& du_null_metric,
541 const tnsr::aa<DataVector, 3, Frame::RadialNull>& dlambda_null_metric,
543 const tnsr::I<ComplexDataVector, 2, Frame::RadialNull>& dyad) noexcept;
547 template <
template <
typename>
class BoundaryPrefix>
550 tmpl::list<Tags::BondiBeta, Tags::BondiU, Tags::Dr<Tags::BondiU>,
551 Tags::BondiQ, Tags::BondiW, Tags::BondiJ, Tags::Dr<Tags::BondiJ>,
560 template <
typename BoundaryTagList,
typename BufferTagList,
561 typename ComplexBufferTagList>
563 const gsl::not_null<Variables<BoundaryTagList>*> bondi_boundary_data,
564 const gsl::not_null<Variables<BufferTagList>*> computation_variables,
565 const gsl::not_null<Variables<ComplexBufferTagList>*> derivative_buffers,
566 const tnsr::aa<DataVector, 3>& dt_spacetime_metric,
567 const tnsr::iaa<DataVector, 3>&
phi,
569 const tnsr::A<DataVector, 3>& null_l,
570 const tnsr::A<DataVector, 3>& du_null_l,
571 const SphericaliCartesianJ& cartesian_to_spherical_jacobian,
572 const size_t l_max,
const double extraction_radius) noexcept {
577 Variables<tmpl::list<Tags::detail::DownDyad, Tags::detail::UpDyad>>
578 dyad_variables{size};
581 get<gr::Tags::SpacetimeMetric<3, Frame::RadialNull, DataVector>>(
582 *computation_variables);
583 auto& du_null_metric =
get<
585 *computation_variables);
590 auto& inverse_null_metric =
591 get<gr::Tags::InverseSpacetimeMetric<3, Frame::RadialNull, DataVector>>(
592 *computation_variables);
599 auto& scaled_null_metric =
600 get<gr::Tags::InverseSpacetimeMetric<3, Frame::RadialNull, DataVector>>(
601 *computation_variables);
602 for (
size_t i = 0; i < 4; ++i) {
603 for (
size_t j = i; j < 4; ++j) {
604 if (i > 1 and j > 1) {
605 scaled_null_metric.get(i, j) =
606 null_metric.get(i, j) /
square(extraction_radius);
607 }
else if (i > 1 or j > 1) {
608 scaled_null_metric.get(i, j) =
609 null_metric.get(i, j) / extraction_radius;
611 scaled_null_metric.get(i, j) = null_metric.get(i, j);
616 const auto scaled_inverse_null_metric =
618 for (
size_t i = 0; i < 4; ++i) {
619 for (
size_t j = i; j < 4; ++j) {
620 if (i > 1 and j > 1) {
621 inverse_null_metric.get(i, j) =
622 scaled_inverse_null_metric.get(i, j) /
square(extraction_radius);
623 }
else if (i > 1 or j > 1) {
624 inverse_null_metric.get(i, j) =
625 scaled_inverse_null_metric.get(i, j) / extraction_radius;
627 inverse_null_metric.get(i, j) = scaled_inverse_null_metric.get(i, j);
632 auto& angular_d_null_l =
633 get<Tags::detail::AngularDNullL>(*computation_variables);
634 auto& buffer_for_derivatives =
637 *derivative_buffers));
641 *derivative_buffers));
642 for (
size_t a = 0; a < 4; ++a) {
643 buffer_for_derivatives.data() =
645 Spectral::Swsh::angular_derivatives<tmpl::list<Spectral::Swsh::Tags::Eth>>(
646 l_max, 1,
make_not_null(ð_buffer), buffer_for_derivatives);
647 angular_d_null_l.get(0, a) = -real(eth_buffer.data());
648 angular_d_null_l.get(1, a) = -imag(eth_buffer.data());
651 auto& dlambda_null_metric =
get<Tags::detail::DLambda<
653 *computation_variables);
654 auto& dlambda_inverse_null_metric =
get<Tags::detail::DLambda<
656 *computation_variables);
659 make_not_null(&dlambda_inverse_null_metric), angular_d_null_l,
660 cartesian_to_spherical_jacobian,
phi, dt_spacetime_metric, du_null_l,
663 auto& r = get<Tags::BoundaryValue<Tags::BondiR>>(*bondi_boundary_data);
667 get<::Tags::spacetime_deriv<Tags::detail::RealBondiR, tmpl::size_t<3>,
670 inverse_null_metric, l_max);
677 auto& down_dyad = get<Tags::detail::DownDyad>(dyad_variables);
678 auto& up_dyad = get<Tags::detail::UpDyad>(dyad_variables);
682 *bondi_boundary_data)),
685 auto& bondi_u = get<Tags::BoundaryValue<Tags::BondiU>>(*bondi_boundary_data);
687 inverse_null_metric);
690 *bondi_boundary_data)),
691 d_r, inverse_null_metric, r);
694 get<Tags::BoundaryValue<Tags::BondiJ>>(*bondi_boundary_data);
698 get<Tags::BoundaryValue<Tags::Dr<Tags::BondiJ>>>(*bondi_boundary_data);
699 auto& denominator_buffer =
700 get<::Tags::SpinWeighted<::Tags::TempScalar<0, ComplexDataVector>,
702 *derivative_buffers);
704 *bondi_boundary_data)),
705 make_not_null(&denominator_buffer), dlambda_null_metric, d_r,
706 bondi_j, r, up_dyad);
708 auto& d2lambda_r =
get<
709 Tags::detail::DLambda<Tags::detail::DLambda<Tags::detail::RealBondiR>>>(
710 *computation_variables);
713 auto& angular_d_dlambda_r =
714 get<::Tags::deriv<Tags::detail::DLambda<Tags::detail::RealBondiR>,
716 *computation_variables);
718 Spectral::Swsh::angular_derivatives<tmpl::list<Spectral::Swsh::Tags::Eth>>(
719 l_max, 1,
make_not_null(ð_buffer), buffer_for_derivatives);
720 angular_d_dlambda_r.get(0) = -real(eth_buffer.data());
721 angular_d_dlambda_r.get(1) = -imag(eth_buffer.data());
727 *bondi_boundary_data)),
728 d2lambda_r, dlambda_inverse_null_metric, d_r, down_dyad,
729 angular_d_dlambda_r, inverse_null_metric, bondi_j, r, bondi_u);
732 *bondi_boundary_data)),
733 d_r, bondi_j, du_null_metric, r, up_dyad);
737 *bondi_boundary_data)),
738 d_r, bondi_j, du_null_metric, dlambda_null_metric, r, up_dyad);
791 template <
typename BoundaryTagList>
793 const gsl::not_null<Variables<BoundaryTagList>*> bondi_boundary_data,
794 const tnsr::iaa<DataVector, 3>&
phi,
const tnsr::aa<DataVector, 3>&
pi,
796 const double extraction_radius,
const size_t l_max) noexcept {
805 Variables<tmpl::list<
806 Tags::detail::CosPhi, Tags::detail::CosTheta, Tags::detail::SinPhi,
807 Tags::detail::SinTheta, Tags::detail::CartesianCoordinates,
808 Tags::detail::CartesianToSphericalJacobian,
809 Tags::detail::InverseCartesianToSphericalJacobian,
823 Tags::detail::AngularDNullL,
824 Tags::detail::DLambda<
826 Tags::detail::DLambda<
830 Tags::detail::DLambda<Tags::detail::DLambda<Tags::detail::RealBondiR>>,
833 computation_variables{size};
836 tmpl::list<::Tags::SpinWeighted<::Tags::TempScalar<0, ComplexDataVector>,
840 derivative_buffers{size};
842 auto& cos_phi = get<Tags::detail::CosPhi>(computation_variables);
843 auto& cos_theta = get<Tags::detail::CosTheta>(computation_variables);
844 auto& sin_phi = get<Tags::detail::SinPhi>(computation_variables);
845 auto& sin_theta = get<Tags::detail::SinTheta>(computation_variables);
857 auto& cartesian_coords =
858 get<Tags::detail::CartesianCoordinates>(computation_variables);
859 auto& cartesian_to_spherical_jacobian =
860 get<Tags::detail::CartesianToSphericalJacobian>(computation_variables);
861 auto& inverse_cartesian_to_spherical_jacobian =
862 get<Tags::detail::InverseCartesianToSphericalJacobian>(
863 computation_variables);
867 make_not_null(&inverse_cartesian_to_spherical_jacobian), cos_phi,
868 cos_theta, sin_phi, sin_theta, extraction_radius);
871 get<gr::Tags::SpatialMetric<3, ::Frame::Inertial, DataVector>>(
872 computation_variables);
875 auto& inverse_spatial_metric =
876 get<gr::Tags::InverseSpatialMetric<3, ::Frame::Inertial, DataVector>>(
877 computation_variables);
881 auto&
shift = get<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>(
882 computation_variables);
885 auto&
lapse = get<gr::Tags::Lapse<DataVector>>(computation_variables);
888 auto& dt_spacetime_metric =
get<
890 computation_variables);
895 auto& dt_worldtube_normal =
896 get<::Tags::dt<Tags::detail::WorldtubeNormal>>(computation_variables);
897 auto& worldtube_normal =
898 get<Tags::detail::WorldtubeNormal>(computation_variables);
902 sin_theta, inverse_spatial_metric);
903 auto& spacetime_unit_normal =
904 get<gr::Tags::SpacetimeNormalVector<3, ::Frame::Inertial, DataVector>>(
905 computation_variables);
909 get<::Tags::dt<gr::Tags::Lapse<DataVector>>>(computation_variables);
913 get<::Tags::dt<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>>(
914 computation_variables);
916 shift, inverse_spatial_metric,
917 spacetime_unit_normal,
phi,
pi);
919 auto& du_null_l = get<::Tags::dt<Tags::detail::NullL>>(computation_variables);
920 auto& null_l = get<Tags::detail::NullL>(computation_variables);
923 dt_lapse, dt_spacetime_metric, dt_shift,
lapse,
928 detail::create_bondi_boundary_data(
932 l_max, extraction_radius);
988 template <
typename BoundaryTagList>
990 const gsl::not_null<Variables<BoundaryTagList>*> bondi_boundary_data,
991 const tnsr::ii<ComplexModalVector, 3>& spatial_metric_coefficients,
992 const tnsr::ii<ComplexModalVector, 3>& dt_spatial_metric_coefficients,
993 const tnsr::ii<ComplexModalVector, 3>& dr_spatial_metric_coefficients,
994 const tnsr::I<ComplexModalVector, 3>& shift_coefficients,
995 const tnsr::I<ComplexModalVector, 3>& dt_shift_coefficients,
996 const tnsr::I<ComplexModalVector, 3>& dr_shift_coefficients,
1000 const double extraction_radius,
const size_t l_max) noexcept {
1010 Variables<tmpl::list<
1011 Tags::detail::CosPhi, Tags::detail::CosTheta, Tags::detail::SinPhi,
1012 Tags::detail::SinTheta, Tags::detail::CartesianCoordinates,
1013 Tags::detail::CartesianToSphericalJacobian,
1014 Tags::detail::InverseCartesianToSphericalJacobian,
1037 Tags::detail::AngularDNullL,
1038 Tags::detail::DLambda<
1040 Tags::detail::DLambda<
1044 Tags::detail::DLambda<Tags::detail::DLambda<Tags::detail::RealBondiR>>,
1047 computation_variables{size};
1050 tmpl::list<::Tags::SpinWeighted<::Tags::TempScalar<0, ComplexDataVector>,
1054 derivative_buffers{size};
1055 auto& cos_phi = get<Tags::detail::CosPhi>(computation_variables);
1056 auto& cos_theta = get<Tags::detail::CosTheta>(computation_variables);
1057 auto& sin_phi = get<Tags::detail::SinPhi>(computation_variables);
1058 auto& sin_theta = get<Tags::detail::SinTheta>(computation_variables);
1070 auto& cartesian_coords =
1071 get<Tags::detail::CartesianCoordinates>(computation_variables);
1072 auto& cartesian_to_spherical_jacobian =
1073 get<Tags::detail::CartesianToSphericalJacobian>(computation_variables);
1074 auto& inverse_cartesian_to_spherical_jacobian =
1075 get<Tags::detail::InverseCartesianToSphericalJacobian>(
1076 computation_variables);
1080 make_not_null(&inverse_cartesian_to_spherical_jacobian), cos_phi,
1081 cos_theta, sin_phi, sin_theta, extraction_radius);
1083 auto& cartesian_spatial_metric =
1084 get<gr::Tags::SpatialMetric<3, ::Frame::Inertial, DataVector>>(
1085 computation_variables);
1086 auto& inverse_spatial_metric =
1087 get<gr::Tags::InverseSpatialMetric<3, ::Frame::Inertial, DataVector>>(
1088 computation_variables);
1089 auto& d_cartesian_spatial_metric =
get<
1092 auto& dt_cartesian_spatial_metric =
get<
1094 computation_variables);
1095 auto& interpolation_buffer =
1096 get<::Tags::SpinWeighted<::Tags::TempScalar<0, ComplexDataVector>,
1098 derivative_buffers);
1101 get<::Tags::SpinWeighted<::Tags::TempScalar<0, ComplexDataVector>,
1103 derivative_buffers);
1104 cartesian_spatial_metric_and_derivatives_from_modes(
1111 spatial_metric_coefficients, dr_spatial_metric_coefficients,
1112 dt_spatial_metric_coefficients, inverse_cartesian_to_spherical_jacobian,
1115 auto& cartesian_shift =
1116 get<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>(
1117 computation_variables);
1118 auto& d_cartesian_shift =
1119 get<::Tags::deriv<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>,
1121 computation_variables);
1122 auto& dt_cartesian_shift =
1123 get<::Tags::dt<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>>(
1124 computation_variables);
1131 shift_coefficients, dr_shift_coefficients, dt_shift_coefficients,
1132 inverse_cartesian_to_spherical_jacobian, l_max);
1134 auto& cartesian_lapse =
1135 get<gr::Tags::Lapse<DataVector>>(computation_variables);
1136 auto& d_cartesian_lapse =
1137 get<::Tags::deriv<gr::Tags::Lapse<DataVector>, tmpl::size_t<3>,
1139 auto& dt_cartesian_lapse =
1140 get<::Tags::dt<gr::Tags::Lapse<DataVector>>>(computation_variables);
1146 lapse_coefficients, dr_lapse_coefficients, dt_lapse_coefficients,
1147 inverse_cartesian_to_spherical_jacobian, l_max);
1149 auto&
phi = get<GeneralizedHarmonic::Tags::Phi<3, ::Frame::Inertial>>(
1150 computation_variables);
1151 auto& dt_spacetime_metric =
get<
1153 computation_variables);
1155 get<gr::Tags::SpacetimeMetric<3, ::Frame::Inertial, DataVector>>(
1156 computation_variables);
1159 d_cartesian_shift, cartesian_spatial_metric, d_cartesian_spatial_metric);
1161 make_not_null(&dt_spacetime_metric), cartesian_lapse, dt_cartesian_lapse,
1162 cartesian_shift, dt_cartesian_shift, cartesian_spatial_metric,
1163 dt_cartesian_spatial_metric);
1165 cartesian_shift, cartesian_spatial_metric);
1167 auto& dt_worldtube_normal =
1168 get<::Tags::dt<Tags::detail::WorldtubeNormal>>(computation_variables);
1169 auto& worldtube_normal =
1170 get<Tags::detail::WorldtubeNormal>(computation_variables);
1174 sin_theta, inverse_spatial_metric);
1176 auto& du_null_l = get<::Tags::dt<Tags::detail::NullL>>(computation_variables);
1177 auto& null_l = get<Tags::detail::NullL>(computation_variables);
1180 dt_cartesian_lapse, dt_spacetime_metric, dt_cartesian_shift,
1185 detail::create_bondi_boundary_data(
1189 l_max, extraction_radius);