SpecBoundaryData.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 
8 #include "DataStructures/ComplexDataVector.hpp"
10 #include "DataStructures/DataVector.hpp"
11 #include "DataStructures/SpinWeighted.hpp"
14 #include "Evolution/Systems/Cce/BoundaryData.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/SpacetimeMetric.hpp"
21 #include "PointwiseFunctions/GeneralRelativity/TimeDerivativeOfSpacetimeMetric.hpp"
22 #include "Utilities/Gsl.hpp"
23 
24 namespace Cce {
25 /*
26  * \brief Compute \f$\gamma_{i j}\f$, \f$\gamma^{i j}\f$,
27  * \f$\partial_i \gamma_{j k}\f$, and
28  * \f$\partial_t g_{i j}\f$ from input libsharp-compatible modal spatial
29  * metric quantities.
30  *
31  * \details This function will apply a correction factor associated with a SpEC
32  * bug.
33  */
34 void cartesian_spatial_metric_and_derivatives_from_unnormalized_spec_modes(
35  gsl::not_null<tnsr::ii<DataVector, 3>*> cartesian_spatial_metric,
36  gsl::not_null<tnsr::II<DataVector, 3>*> inverse_cartesian_spatial_metric,
37  gsl::not_null<tnsr::ijj<DataVector, 3>*> d_cartesian_spatial_metric,
38  gsl::not_null<tnsr::ii<DataVector, 3>*> dt_cartesian_spatial_metric,
40  interpolation_modal_buffer,
42  interpolation_buffer,
44  gsl::not_null<Scalar<DataVector>*> radial_correction_factor,
45  const tnsr::ii<ComplexModalVector, 3>& spatial_metric_coefficients,
46  const tnsr::ii<ComplexModalVector, 3>& dr_spatial_metric_coefficients,
47  const tnsr::ii<ComplexModalVector, 3>& dt_spatial_metric_coefficients,
48  const CartesianiSphericalJ& inverse_cartesian_to_spherical_jacobian,
49  const tnsr::I<DataVector, 3>& unit_cartesian_coords, size_t l_max) noexcept;
50 
51 /*!
52  * \brief Compute \f$\beta^{i}\f$, \f$\partial_i \beta^{j}\f$, and
53  * \f$\partial_t \beta^i\f$ from input libsharp-compatible modal spatial
54  * metric quantities.
55  *
56  * \details This function will apply a correction factor associated with a SpEC
57  * bug.
58  */
59 void cartesian_shift_and_derivatives_from_unnormalized_spec_modes(
60  gsl::not_null<tnsr::I<DataVector, 3>*> cartesian_shift,
61  gsl::not_null<tnsr::iJ<DataVector, 3>*> d_cartesian_shift,
62  gsl::not_null<tnsr::I<DataVector, 3>*> dt_cartesian_shift,
64  interpolation_modal_buffer,
66  interpolation_buffer,
68  const tnsr::I<ComplexModalVector, 3>& shift_coefficients,
69  const tnsr::I<ComplexModalVector, 3>& dr_shift_coefficients,
70  const tnsr::I<ComplexModalVector, 3>& dt_shift_coefficients,
71  const CartesianiSphericalJ& inverse_cartesian_to_spherical_jacobian,
72  const Scalar<DataVector>& radial_derivative_correction_factor,
73  size_t l_max) noexcept;
74 
75 /*!
76  * \brief Compute \f$\alpha\f$, \f$\partial_i \alpha\f$, and
77  * \f$\partial_t \beta^i\f$ from input libsharp-compatible modal spatial
78  * metric quantities.
79  *
80  * \details This function will apply a correction factor associated with a SpEC
81  * bug.
82  */
83 void cartesian_lapse_and_derivatives_from_unnormalized_spec_modes(
84  gsl::not_null<Scalar<DataVector>*> cartesian_lapse,
85  gsl::not_null<tnsr::i<DataVector, 3>*> d_cartesian_lapse,
86  gsl::not_null<Scalar<DataVector>*> dt_cartesian_lapse,
88  interpolation_modal_buffer,
90  interpolation_buffer,
92  const Scalar<ComplexModalVector>& lapse_coefficients,
93  const Scalar<ComplexModalVector>& dr_lapse_coefficients,
94  const Scalar<ComplexModalVector>& dt_lapse_coefficients,
95  const CartesianiSphericalJ& inverse_cartesian_to_spherical_jacobian,
96  const Scalar<DataVector>& radial_derivative_correction_factor,
97  size_t l_max) noexcept;
98 
99 /*!
100  * \brief Process the worldtube data from modal metric components and
101  * derivatives with incorrectly normalized radial derivatives from an old
102  * version of SpEC to desired Bondi quantities, placing the result in the passed
103  * \ref DataBoxGroup.
104  *
105  * \details
106  * The mathematics are a bit complicated for all of the coordinate
107  * transformations that are necessary to obtain the Bondi gauge quantities.
108  * For full mathematical details, see the documentation for functions in
109  * `BoundaryData.hpp` and \cite Barkett2019uae \cite Bishop1998uk.
110  *
111  * This function takes as input the full set of ADM metric data and its radial
112  * and time derivatives on a two-dimensional surface of constant \f$r\f$ and
113  * \f$t\f$ in numerical coordinates. This data must be provided as spherical
114  * harmonic coefficients in the libsharp format. This data is provided in nine
115  * `Tensor`s.
116  *
117  * Sufficient tags to provide full worldtube boundary data at a particular
118  * time are set in `bondi_boundary_data`. In particular, the set of tags in
119  * `Tags::characteristic_worldtube_boundary_tags` in the provided \ref
120  * DataBoxGroup are assigned to the worldtube boundary values associated with
121  * the input metric components.
122  *
123  * The majority of the mathematical transformations are implemented as a set of
124  * individual cascaded functions below. The details of the manipulations that
125  * are performed to the input data may be found in the individual functions
126  * themselves, which are called in the following order:
127  * - `trigonometric_functions_on_swsh_collocation()`
128  * - `cartesian_to_spherical_coordinates_and_jacobians()`
129  * - `cartesian_spatial_metric_and_derivatives_from_unnormalized_spec_modes()`
130  * - `cartesian_shift_and_derivatives_from_unnormalized_spec_modes()`
131  * - `cartesian_lapse_and_derivatives_from_unnormalized_spec_modes()`
132  * - `GeneralizedHarmonic::phi()`
133  * - `gr::time_derivative_of_spacetime_metric`
134  * - `gr::spacetime_metric`
135  * - `generalized_harmonic_quantities()`
136  * - `worldtube_normal_and_derivatives()`
137  * - `null_vector_l_and_derivatives()`
138  * - `null_metric_and_derivative()`
139  * - `dlambda_null_metric_and_inverse()`
140  * - `bondi_r()`
141  * - `d_bondi_r()`
142  * - `dyads()`
143  * - `beta_worldtube_data()`
144  * - `bondi_u_worldtube_data()`
145  * - `bondi_w_worldtube_data()`
146  * - `bondi_j_worldtube_data()`
147  * - `dr_bondi_j()`
148  * - `d2lambda_bondi_r()`
149  * - `bondi_q_worldtube_data()`
150  * - `bondi_h_worldtube_data()`
151  * - `du_j_worldtube_data()`
152  */
153 template <typename DataBoxTagList>
155  const gsl::not_null<db::DataBox<DataBoxTagList>*> bondi_boundary_data,
156  const tnsr::ii<ComplexModalVector, 3>& spatial_metric_coefficients,
157  const tnsr::ii<ComplexModalVector, 3>& dt_spatial_metric_coefficients,
158  const tnsr::ii<ComplexModalVector, 3>& dr_spatial_metric_coefficients,
159  const tnsr::I<ComplexModalVector, 3>& shift_coefficients,
160  const tnsr::I<ComplexModalVector, 3>& dt_shift_coefficients,
161  const tnsr::I<ComplexModalVector, 3>& dr_shift_coefficients,
162  const Scalar<ComplexModalVector>& lapse_coefficients,
163  const Scalar<ComplexModalVector>& dt_lapse_coefficients,
164  const Scalar<ComplexModalVector>& dr_lapse_coefficients,
165  const double extraction_radius, const size_t l_max) noexcept {
166  const size_t size = Spectral::Swsh::number_of_swsh_collocation_points(l_max);
167 
168  // Most allocations required for the full boundary computation are merged into
169  // a single, large Variables allocation. There remain a handful of cases in
170  // the computational functions called where an intermediate quantity that is
171  // not re-used is allocated rather than taking a buffer. These cases are
172  // marked with code comments 'Allocation'; In future, allocations are
173  // identified as a point to optimize, those buffers may be allocated here and
174  // passed as function arguments
175  Variables<tmpl::list<
176  Tags::detail::CosPhi, Tags::detail::CosTheta, Tags::detail::SinPhi,
177  Tags::detail::SinTheta, Tags::detail::CartesianCoordinates,
178  Tags::detail::CartesianToSphericalJacobian,
179  Tags::detail::InverseCartesianToSphericalJacobian,
183  tmpl::size_t<3>, ::Frame::Inertial>,
187  tmpl::size_t<3>, ::Frame::Inertial>,
196  Tags::detail::WorldtubeNormal, ::Tags::dt<Tags::detail::WorldtubeNormal>,
197  Tags::detail::NullL, ::Tags::dt<Tags::detail::NullL>,
198  // for the detail function called at the end
202  Tags::detail::AngularDNullL,
203  Tags::detail::DLambda<
205  Tags::detail::DLambda<
209  Tags::detail::DLambda<Tags::detail::DLambda<Tags::detail::RealBondiR>>,
211  tmpl::size_t<2>, Frame::RadialNull>,
213  computation_variables{size};
214 
215  Variables<
216  tmpl::list<::Tags::SpinWeighted<::Tags::TempScalar<0, ComplexDataVector>,
220  derivative_buffers{size};
221  auto& cos_phi = get<Tags::detail::CosPhi>(computation_variables);
222  auto& cos_theta = get<Tags::detail::CosTheta>(computation_variables);
223  auto& sin_phi = get<Tags::detail::SinPhi>(computation_variables);
224  auto& sin_theta = get<Tags::detail::SinTheta>(computation_variables);
225  trigonometric_functions_on_swsh_collocation(
226  make_not_null(&cos_phi), make_not_null(&cos_theta),
227  make_not_null(&sin_phi), make_not_null(&sin_theta), l_max);
228 
229  // NOTE: to handle the singular values of polar coordinates, the phi
230  // components of all tensors are scaled according to their sin(theta)
231  // prefactors.
232  // so, any down-index component get<2>(A) represents 1/sin(theta) A_\phi,
233  // and any up-index component get<2>(A) represents sin(theta) A^\phi.
234  // This holds for Jacobians, and so direct application of the Jacobians
235  // brings the factors through.
236  auto& cartesian_coords =
237  get<Tags::detail::CartesianCoordinates>(computation_variables);
238  auto& cartesian_to_spherical_jacobian =
239  get<Tags::detail::CartesianToSphericalJacobian>(computation_variables);
240  auto& inverse_cartesian_to_spherical_jacobian =
241  get<Tags::detail::InverseCartesianToSphericalJacobian>(
242  computation_variables);
243  cartesian_to_spherical_coordinates_and_jacobians(
244  make_not_null(&cartesian_coords),
245  make_not_null(&cartesian_to_spherical_jacobian),
246  make_not_null(&inverse_cartesian_to_spherical_jacobian), cos_phi,
247  cos_theta, sin_phi, sin_theta, extraction_radius);
248 
249  auto& cartesian_spatial_metric =
250  get<gr::Tags::SpatialMetric<3, ::Frame::Inertial, DataVector>>(
251  computation_variables);
252  auto& inverse_spatial_metric =
253  get<gr::Tags::InverseSpatialMetric<3, ::Frame::Inertial, DataVector>>(
254  computation_variables);
255  auto& d_cartesian_spatial_metric = get<
257  tmpl::size_t<3>, ::Frame::Inertial>>(computation_variables);
258  auto& dt_cartesian_spatial_metric = get<
260  computation_variables);
261  auto& interpolation_buffer =
262  get<::Tags::SpinWeighted<::Tags::TempScalar<0, ComplexDataVector>,
264  derivative_buffers);
265  Scalar<SpinWeighted<ComplexModalVector, 0>> interpolation_modal_buffer{size};
266  auto& eth_buffer =
267  get<::Tags::SpinWeighted<::Tags::TempScalar<0, ComplexDataVector>,
269  derivative_buffers);
270  auto& radial_correction_factor =
271  get<::Tags::TempScalar<0, DataVector>>(computation_variables);
272  cartesian_spatial_metric_and_derivatives_from_unnormalized_spec_modes(
273  make_not_null(&cartesian_spatial_metric),
274  make_not_null(&inverse_spatial_metric),
275  make_not_null(&d_cartesian_spatial_metric),
276  make_not_null(&dt_cartesian_spatial_metric),
277  make_not_null(&interpolation_modal_buffer),
278  make_not_null(&interpolation_buffer), make_not_null(&eth_buffer),
279  make_not_null(&radial_correction_factor), spatial_metric_coefficients,
280  dr_spatial_metric_coefficients, dt_spatial_metric_coefficients,
281  inverse_cartesian_to_spherical_jacobian, cartesian_coords, l_max);
282 
283  auto& cartesian_shift =
284  get<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>(
285  computation_variables);
286  auto& d_cartesian_shift =
287  get<::Tags::deriv<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>,
288  tmpl::size_t<3>, ::Frame::Inertial>>(
289  computation_variables);
290  auto& dt_cartesian_shift =
291  get<::Tags::dt<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>>(
292  computation_variables);
293 
294  cartesian_shift_and_derivatives_from_unnormalized_spec_modes(
295  make_not_null(&cartesian_shift), make_not_null(&d_cartesian_shift),
296  make_not_null(&dt_cartesian_shift),
297  make_not_null(&interpolation_modal_buffer),
298  make_not_null(&interpolation_buffer), make_not_null(&eth_buffer),
299  shift_coefficients, dr_shift_coefficients, dt_shift_coefficients,
300  inverse_cartesian_to_spherical_jacobian, radial_correction_factor, l_max);
301 
302  auto& cartesian_lapse =
303  get<gr::Tags::Lapse<DataVector>>(computation_variables);
304  auto& d_cartesian_lapse =
305  get<::Tags::deriv<gr::Tags::Lapse<DataVector>, tmpl::size_t<3>,
306  ::Frame::Inertial>>(computation_variables);
307  auto& dt_cartesian_lapse =
308  get<::Tags::dt<gr::Tags::Lapse<DataVector>>>(computation_variables);
309  cartesian_lapse_and_derivatives_from_unnormalized_spec_modes(
310  make_not_null(&cartesian_lapse), make_not_null(&d_cartesian_lapse),
311  make_not_null(&dt_cartesian_lapse),
312  make_not_null(&interpolation_modal_buffer),
313  make_not_null(&interpolation_buffer), make_not_null(&eth_buffer),
314  lapse_coefficients, dr_lapse_coefficients, dt_lapse_coefficients,
315  inverse_cartesian_to_spherical_jacobian, radial_correction_factor, l_max);
316 
317  auto& phi = get<GeneralizedHarmonic::Tags::Phi<3, ::Frame::Inertial>>(
318  computation_variables);
319  auto& dt_spacetime_metric = get<
321  computation_variables);
322  auto& spacetime_metric =
323  get<gr::Tags::SpacetimeMetric<3, ::Frame::Inertial, DataVector>>(
324  computation_variables);
326  make_not_null(&phi), cartesian_lapse, d_cartesian_lapse, cartesian_shift,
327  d_cartesian_shift, cartesian_spatial_metric, d_cartesian_spatial_metric);
329  make_not_null(&dt_spacetime_metric), cartesian_lapse, dt_cartesian_lapse,
330  cartesian_shift, dt_cartesian_shift, cartesian_spatial_metric,
331  dt_cartesian_spatial_metric);
333  cartesian_shift, cartesian_spatial_metric);
334 
335  auto& dt_worldtube_normal =
336  get<::Tags::dt<Tags::detail::WorldtubeNormal>>(computation_variables);
337  auto& worldtube_normal =
338  get<Tags::detail::WorldtubeNormal>(computation_variables);
339  worldtube_normal_and_derivatives(
340  make_not_null(&worldtube_normal), make_not_null(&dt_worldtube_normal),
341  cos_phi, cos_theta, spacetime_metric, dt_spacetime_metric, sin_phi,
342  sin_theta, inverse_spatial_metric);
343 
344  auto& du_null_l = get<::Tags::dt<Tags::detail::NullL>>(computation_variables);
345  auto& null_l = get<Tags::detail::NullL>(computation_variables);
346  null_vector_l_and_derivatives(
347  make_not_null(&du_null_l), make_not_null(&null_l), dt_worldtube_normal,
348  dt_cartesian_lapse, dt_spacetime_metric, dt_cartesian_shift,
349  cartesian_lapse, spacetime_metric, cartesian_shift, worldtube_normal);
350 
351  // pass to the next step that is common between the 'modal' input and 'GH'
352  // input strategies
353  detail::create_bondi_boundary_data(
354  bondi_boundary_data, make_not_null(&computation_variables),
355  make_not_null(&derivative_buffers), dt_spacetime_metric, phi,
356  spacetime_metric, null_l, du_null_l, cartesian_to_spherical_jacobian,
357  l_max, extraction_radius);
358 }
359 } // namespace Cce
std::integral_constant
Frame::Inertial
Definition: IndexType.hpp:44
gr::Tags::SpatialMetric
Definition: Tags.hpp:26
get
constexpr Tag::type & get(Variables< TagList > &v) noexcept
Return Tag::type pointing into the contiguous array.
Definition: Variables.hpp:689
DeterminantAndInverse.hpp
Tags::SpinWeighted
Given a Tag with a type of Tensor<VectorType, ...>, acts as a new version of the tag with type of Ten...
Definition: Tags.hpp:59
SpinWeighted
Make a spin-weighted type T with spin-weight Spin. Mathematical operators are restricted to addition,...
Definition: SpinWeighted.hpp:24
DataBox.hpp
cstddef
Tags::spacetime_deriv
Prefix indicating spacetime derivatives.
Definition: PartialDerivatives.hpp:90
gr::Tags::InverseSpacetimeMetric
Definition: Tags.hpp:21
gr::Tags::SpacetimeMetric
Definition: Tags.hpp:17
GeneralizedHarmonic::phi
void phi(gsl::not_null< tnsr::iaa< DataType, SpatialDim, Frame > * > phi, const Scalar< DataType > &lapse, const tnsr::i< DataType, SpatialDim, Frame > &deriv_lapse, const tnsr::I< DataType, SpatialDim, Frame > &shift, const tnsr::iJ< DataType, SpatialDim, Frame > &deriv_shift, const tnsr::ii< DataType, SpatialDim, Frame > &spatial_metric, const tnsr::ijj< DataType, SpatialDim, Frame > &deriv_spatial_metric) noexcept
Computes the auxiliary variable used by the generalized harmonic formulation of Einstein's equations...
gr::Tags::Shift
Definition: Tags.hpp:48
gr::time_derivative_of_spacetime_metric
void time_derivative_of_spacetime_metric(gsl::not_null< tnsr::aa< DataType, SpatialDim, Frame > * > dt_spacetime_metric, const Scalar< DataType > &lapse, const Scalar< DataType > &dt_lapse, const tnsr::I< DataType, SpatialDim, Frame > &shift, const tnsr::I< DataType, SpatialDim, Frame > &dt_shift, const tnsr::ii< DataType, SpatialDim, Frame > &spatial_metric, const tnsr::ii< DataType, SpatialDim, Frame > &dt_spatial_metric) noexcept
Computes the time derivative of the spacetime metric from spatial metric, lapse, shift,...
GeneralizedHarmonic::Tags::Phi
Auxiliary variable which is analytically the spatial derivative of the spacetime metric.
Definition: Tags.hpp:40
Tags::dt
Prefix indicating a time derivative.
Definition: Prefixes.hpp:29
Scalar
Tensor< T, Symmetry<>, index_list<> > Scalar
Definition: TypeAliases.hpp:21
Cce
The set of utilities for performing Cauchy characteristic evolution and Cauchy characteristic matchin...
Definition: BoundaryComputeAndSendToEvolution.hpp:28
Tags::TempTensor
Definition: Variables.hpp:937
Gsl.hpp
Cce::Frame::RadialNull
The frame for the spherical metric in which the radial coordinate is an affine parameter along outwar...
Definition: BoundaryDataTags.hpp:14
TypeAliases.hpp
gr::spacetime_metric
void spacetime_metric(gsl::not_null< tnsr::aa< DataType, Dim, Frame > * > spacetime_metric, const Scalar< DataType > &lapse, const tnsr::I< DataType, Dim, Frame > &shift, const tnsr::ii< DataType, Dim, Frame > &spatial_metric) noexcept
Computes the spacetime metric from the spatial metric, lapse, and shift.
Tags::deriv
Prefix indicating spatial derivatives.
Definition: PartialDerivatives.hpp:54
make_not_null
gsl::not_null< T * > make_not_null(T *ptr) noexcept
Construct a not_null from a pointer. Often this will be done as an implicit conversion,...
Definition: Gsl.hpp:880
Cce::create_bondi_boundary_data_from_unnormalized_spec_modes
void create_bondi_boundary_data_from_unnormalized_spec_modes(const gsl::not_null< db::DataBox< DataBoxTagList > * > bondi_boundary_data, const tnsr::ii< ComplexModalVector, 3 > &spatial_metric_coefficients, const tnsr::ii< ComplexModalVector, 3 > &dt_spatial_metric_coefficients, const tnsr::ii< ComplexModalVector, 3 > &dr_spatial_metric_coefficients, const tnsr::I< ComplexModalVector, 3 > &shift_coefficients, const tnsr::I< ComplexModalVector, 3 > &dt_shift_coefficients, const tnsr::I< ComplexModalVector, 3 > &dr_shift_coefficients, const Scalar< ComplexModalVector > &lapse_coefficients, const Scalar< ComplexModalVector > &dt_lapse_coefficients, const Scalar< ComplexModalVector > &dr_lapse_coefficients, const double extraction_radius, const size_t l_max) noexcept
Process the worldtube data from modal metric components and derivatives with incorrectly normalized r...
Definition: SpecBoundaryData.hpp:154
db::DataBox
Definition: InterpolationTargetWedgeSectionTorus.hpp:24
gr::Tags::Lapse
Definition: Tags.hpp:52
gr::Tags::InverseSpatialMetric
Inverse of the spatial metric.
Definition: Tags.hpp:33
gsl::not_null
Require a pointer to not be a nullptr
Definition: Gsl.hpp:183
Spectral::Swsh::number_of_swsh_collocation_points
constexpr size_t number_of_swsh_collocation_points(const size_t l_max) noexcept
Convenience function for determining the number of spin-weighted spherical harmonic collocation value...
Definition: SwshCollocation.hpp:25