AnalyticDataHelpers.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <complex>
7 #include <cstddef>
8 
9 #include "DataStructures/ComplexDataVector.hpp"
10 #include "DataStructures/DataVector.hpp"
11 #include "DataStructures/SpinWeighted.hpp"
13 #include "Evolution/Systems/Cce/AnalyticSolutions/SphericalMetricData.hpp"
14 #include "Evolution/Systems/Cce/Tags.hpp"
15 #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/SpatialDerivOfLapse.hpp"
16 #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/SpatialDerivOfShift.hpp"
17 #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/TimeDerivOfLapse.hpp"
18 #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/TimeDerivOfShift.hpp"
19 #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/TimeDerivOfSpatialMetric.hpp"
20 #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/TimeDerivativeOfSpacetimeMetric.hpp"
21 #include "PointwiseFunctions/GeneralRelativity/InverseSpacetimeMetric.hpp"
22 #include "PointwiseFunctions/GeneralRelativity/Lapse.hpp"
23 #include "PointwiseFunctions/GeneralRelativity/Shift.hpp"
24 #include "PointwiseFunctions/GeneralRelativity/SpacetimeNormalVector.hpp"
25 #include "PointwiseFunctions/GeneralRelativity/SpatialMetric.hpp"
26 #include "Utilities/TaggedTuple.hpp"
27 
28 namespace Cce {
29 namespace Solutions {
30 namespace TestHelpers {
31 
32 // This function determines the Bondi-Sachs scalars from a Cartesian spacetime
33 // metric, assuming that the metric is already in null form, so the spatial
34 // coordinates are related to standard Bondi-Sachs coordinates by just the
35 // standard Cartesian to spherical Jacobian.
37 extract_bondi_scalars_from_cartesian_metric(
38  const tnsr::aa<DataVector, 3>& spacetime_metric,
39  const CartesianiSphericalJ& inverse_jacobian,
40  double extraction_radius) noexcept;
41 
42 // This function determines the time derivative of the Bondi-Sachs scalars
43 // from the time derivative of a Cartesian spacetime metric, the Cartesian
44 // metric, and Jacobian factors. This procedure assumes that the metric is
45 // already in null form, so the spatial coordinates are related to standard
46 // Bondi-Sachs coordinates by just the standard cartesian to spherical Jacobian.
49 extract_dt_bondi_scalars_from_cartesian_metric(
50  const tnsr::aa<DataVector, 3>& dt_spacetime_metric,
51  const tnsr::aa<DataVector, 3>& spacetime_metric,
52  const CartesianiSphericalJ& inverse_jacobian,
53  double extraction_radius) noexcept;
54 
55 // This function determines the radial derivative of the Bondi-Sachs scalars
56 // from the radial derivative of a Cartesian spacetime metric, the Cartesian
57 // metric, and Jacobian factors. This procedure assumes that the metric is
58 // already in null form, so the spatial coordinates are related to standard
59 // Bondi-Sachs coordinates by just the standard cartesian to spherical Jacobian.
60 tuples::TaggedTuple<Tags::Dr<Tags::BondiBeta>, Tags::Dr<Tags::BondiU>,
61  Tags::Dr<Tags::BondiW>, Tags::Dr<Tags::BondiJ>>
62 extract_dr_bondi_scalars_from_cartesian_metric(
63  const tnsr::aa<DataVector, 3>& dr_spacetime_metric,
64  const tnsr::aa<DataVector, 3>& spacetime_metric,
65  const CartesianiSphericalJ& inverse_jacobian,
66  const CartesianiSphericalJ& dr_inverse_jacobian,
67  double extraction_radius) noexcept;
68 
69 // This function checks the consistency of the 3+1 ADM quantities in the
70 // `boundary_tuple` with quantities computed from `expected_spacetime_metric`,
71 // `expected_dt_spacetime_metric`, and `expected_d_spacetime_metric`. If the
72 // expected quantities are also extracted from the tuple, this simply checks
73 // that the boundary computation has produced a consistent set of quantities
74 // and has not generated NaNs or other pathological values (e.g. a degenerate
75 // spacetime metric) in the process.
76 template <typename... TupleTags>
77 void check_adm_metric_quantities(
78  const tuples::TaggedTuple<TupleTags...>& boundary_tuple,
79  const tnsr::aa<DataVector, 3>& expected_spacetime_metric,
80  const tnsr::aa<DataVector, 3>& expected_dt_spacetime_metric,
81  const tnsr::iaa<DataVector, 3>& expected_d_spacetime_metric) noexcept {
82  // check the 3+1 quantities are computed correctly in the abstract base class
83  // `WorldtubeData`
84  const auto& dr_cartesian_coordinates =
85  get<Tags::Dr<Tags::CauchyCartesianCoords>>(boundary_tuple);
86 
87  const auto& lapse = get<gr::Tags::Lapse<DataVector>>(boundary_tuple);
88  const auto& shift =
89  get<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>(boundary_tuple);
90  const auto& spatial_metric =
91  get<gr::Tags::SpatialMetric<3, ::Frame::Inertial, DataVector>>(
92  boundary_tuple);
93 
94  const auto expected_spatial_metric =
95  gr::spatial_metric(expected_spacetime_metric);
96  const auto expected_inverse_spatial_metric =
97  determinant_and_inverse(expected_spatial_metric).second;
98  const auto expected_shift =
99  gr::shift(expected_spacetime_metric, expected_inverse_spatial_metric);
100  const auto expected_lapse =
101  gr::lapse(expected_shift, expected_spacetime_metric);
102  CHECK_ITERABLE_APPROX(spatial_metric, expected_spatial_metric);
103  CHECK_ITERABLE_APPROX(shift, expected_shift);
104  CHECK_ITERABLE_APPROX(lapse, expected_lapse);
105 
106  const auto& pi =
107  get<GeneralizedHarmonic::Tags::Pi<3, ::Frame::Inertial>>(boundary_tuple);
108  const auto dt_spacetime_metric_from_pi =
110  expected_lapse, expected_shift, pi, expected_d_spacetime_metric);
111  CHECK_ITERABLE_APPROX(expected_dt_spacetime_metric,
112  dt_spacetime_metric_from_pi);
113  // Check that the time derivative values are consistent with the Generalized
114  // Harmonic `pi` -- these are redundant if the boundary calculation uses `pi`
115  // to derive these, but it is not required to do so.
116  const auto& dt_lapse =
117  get<::Tags::dt<gr::Tags::Lapse<DataVector>>>(boundary_tuple);
118  const auto& dt_shift =
119  get<::Tags::dt<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>>(
120  boundary_tuple);
121  const auto& dt_spatial_metric = get<
123  boundary_tuple);
124  const auto expected_dt_spatial_metric =
126  expected_lapse, expected_shift, expected_d_spacetime_metric, pi);
127  const auto expected_spacetime_unit_normal =
128  gr::spacetime_normal_vector(expected_lapse, expected_shift);
129  const auto expected_dt_lapse = GeneralizedHarmonic::time_deriv_of_lapse(
130  expected_lapse, expected_shift, expected_spacetime_unit_normal,
131  expected_d_spacetime_metric, pi);
132  const auto expected_dt_shift = GeneralizedHarmonic::time_deriv_of_shift(
133  expected_lapse, expected_shift, expected_inverse_spatial_metric,
134  expected_spacetime_unit_normal, expected_d_spacetime_metric, pi);
135  CHECK_ITERABLE_APPROX(dt_lapse, expected_dt_lapse);
136  CHECK_ITERABLE_APPROX(dt_shift, expected_dt_shift);
137  CHECK_ITERABLE_APPROX(dt_spatial_metric, expected_dt_spatial_metric);
138 
139  const auto& dr_lapse =
140  get<Tags::Dr<gr::Tags::Lapse<DataVector>>>(boundary_tuple);
141  const auto& dr_shift =
142  get<Tags::Dr<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>>(
143  boundary_tuple);
144  const auto& dr_spatial_metric =
145  get<Tags::Dr<gr::Tags::SpatialMetric<3, ::Frame::Inertial, DataVector>>>(
146  boundary_tuple);
147  const auto expected_spatial_derivative_of_lapse =
149  expected_lapse, expected_spacetime_unit_normal,
150  expected_d_spacetime_metric);
151  const auto expected_inverse_spacetime_metric = gr::inverse_spacetime_metric(
152  expected_lapse, expected_shift, expected_inverse_spatial_metric);
153  const auto expected_spatial_derivative_of_shift =
155  expected_lapse, expected_inverse_spacetime_metric,
156  expected_spacetime_unit_normal, expected_d_spacetime_metric);
157  DataVector expected_buffer =
158  get<0>(dr_cartesian_coordinates) *
159  get<0>(expected_spatial_derivative_of_lapse) +
160  get<1>(dr_cartesian_coordinates) *
161  get<1>(expected_spatial_derivative_of_lapse) +
162  get<2>(dr_cartesian_coordinates) *
163  get<2>(expected_spatial_derivative_of_lapse);
164  CHECK_ITERABLE_APPROX(expected_buffer, get(dr_lapse));
165  for (size_t i = 0; i < 3; ++i) {
166  expected_buffer = get<0>(dr_cartesian_coordinates) *
167  expected_spatial_derivative_of_shift.get(0, i) +
168  get<1>(dr_cartesian_coordinates) *
169  expected_spatial_derivative_of_shift.get(1, i) +
170  get<2>(dr_cartesian_coordinates) *
171  expected_spatial_derivative_of_shift.get(2, i);
172  CHECK_ITERABLE_APPROX(expected_buffer, dr_shift.get(i));
173  for (size_t j = i; j < 3; ++j) {
174  expected_buffer = get<0>(dr_cartesian_coordinates) *
175  expected_d_spacetime_metric.get(0, i + 1, j + 1) +
176  get<1>(dr_cartesian_coordinates) *
177  expected_d_spacetime_metric.get(1, i + 1, j + 1) +
178  get<2>(dr_cartesian_coordinates) *
179  expected_d_spacetime_metric.get(2, i + 1, j + 1);
180  CHECK_ITERABLE_APPROX(expected_buffer, dr_spatial_metric.get(i, j));
181  }
182  }
183 }
184 
185 } // namespace TestHelpers
186 } // namespace Solutions
187 } // namespace Cce
GeneralizedHarmonic::pi
void pi(gsl::not_null< tnsr::aa< DataType, SpatialDim, Frame > * > pi, 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, const tnsr::iaa< DataType, SpatialDim, Frame > &phi) noexcept
Computes the conjugate momentum of the spacetime metric .
GeneralizedHarmonic::spatial_deriv_of_shift
void spatial_deriv_of_shift(gsl::not_null< tnsr::iJ< DataType, SpatialDim, Frame > * > deriv_shift, const Scalar< DataType > &lapse, const tnsr::AA< DataType, SpatialDim, Frame > &inverse_spacetime_metric, const tnsr::A< DataType, SpatialDim, Frame > &spacetime_unit_normal, const tnsr::iaa< DataType, SpatialDim, Frame > &phi) noexcept
Computes spatial derivatives of the shift vector from the generalized harmonic and geometric variable...
get
constexpr Tag::type & get(Variables< TagList > &v) noexcept
Return Tag::type pointing into the contiguous array.
Definition: Variables.hpp:689
GeneralizedHarmonic::time_deriv_of_spatial_metric
void time_deriv_of_spatial_metric(gsl::not_null< tnsr::ii< DataType, SpatialDim, Frame > * > dt_spatial_metric, const Scalar< DataType > &lapse, const tnsr::I< DataType, SpatialDim, Frame > &shift, const tnsr::iaa< DataType, SpatialDim, Frame > &phi, const tnsr::aa< DataType, SpatialDim, Frame > &pi) noexcept
Computes time derivative of the spatial metric.
CHECK_ITERABLE_APPROX
#define CHECK_ITERABLE_APPROX(a, b)
A wrapper around Catch's CHECK macro that checks approximate equality of entries in iterable containe...
Definition: TestingFramework.hpp:139
GeneralizedHarmonic::spatial_deriv_of_lapse
void spatial_deriv_of_lapse(gsl::not_null< tnsr::i< DataType, SpatialDim, Frame > * > deriv_lapse, const Scalar< DataType > &lapse, const tnsr::A< DataType, SpatialDim, Frame > &spacetime_unit_normal, const tnsr::iaa< DataType, SpatialDim, Frame > &phi) noexcept
Computes spatial derivatives of lapse (N) from the generalized harmonic variables and spacetime unit ...
GeneralizedHarmonic::time_deriv_of_shift
void time_deriv_of_shift(gsl::not_null< tnsr::I< DataType, SpatialDim, Frame > * > dt_shift, const Scalar< DataType > &lapse, const tnsr::I< DataType, SpatialDim, Frame > &shift, const tnsr::II< DataType, SpatialDim, Frame > &inverse_spatial_metric, const tnsr::A< DataType, SpatialDim, Frame > &spacetime_unit_normal, const tnsr::iaa< DataType, SpatialDim, Frame > &phi, const tnsr::aa< DataType, SpatialDim, Frame > &pi) noexcept
Computes time derivative of the shift vector from the generalized harmonic and geometric variables.
gr::lapse
Scalar< DataType > lapse(const tnsr::I< DataType, SpatialDim, Frame > &shift, const tnsr::aa< DataType, SpatialDim, Frame > &spacetime_metric) noexcept
Compute lapse from shift and spacetime metric.
determinant_and_inverse
void determinant_and_inverse(const gsl::not_null< Scalar< T > * > det, const gsl::not_null< Tensor< T, Symm, tmpl::list< change_index_up_lo< Index1 >, change_index_up_lo< Index0 >>> * > inv, const Tensor< T, Symm, tmpl::list< Index0, Index1 >> &tensor) noexcept
Computes the determinant and inverse of a rank-2 Tensor.
Definition: DeterminantAndInverse.hpp:371
cstddef
tuples::TaggedTuple
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:272
DataVector
Stores a collection of function values.
Definition: DataVector.hpp:42
GeneralizedHarmonic::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 tnsr::I< DataType, SpatialDim, Frame > &shift, const tnsr::aa< DataType, SpatialDim, Frame > &pi, const tnsr::iaa< DataType, SpatialDim, Frame > &phi) noexcept
Computes the time derivative of the spacetime metric from the generalized harmonic quantities ,...
gr::shift
tnsr::I< DataType, SpatialDim, Frame > shift(const tnsr::aa< DataType, SpatialDim, Frame > &spacetime_metric, const tnsr::II< DataType, SpatialDim, Frame > &inverse_spatial_metric) noexcept
Compute shift from spacetime metric and inverse spatial metric.
Tags::dt
Prefix indicating a time derivative.
Definition: Prefixes.hpp:29
Cce
The set of utilities for performing Cauchy characteristic evolution and Cauchy characteristic matchin...
Definition: BoundaryComputeAndSendToEvolution.hpp:28
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.
Tensor.hpp
GeneralizedHarmonic::time_deriv_of_lapse
void time_deriv_of_lapse(gsl::not_null< Scalar< DataType > * > dt_lapse, const Scalar< DataType > &lapse, const tnsr::I< DataType, SpatialDim, Frame > &shift, const tnsr::A< DataType, SpatialDim, Frame > &spacetime_unit_normal, const tnsr::iaa< DataType, SpatialDim, Frame > &phi, const tnsr::aa< DataType, SpatialDim, Frame > &pi) noexcept
Computes time derivative of lapse (N) from the generalized harmonic variables, lapse,...
gr::spatial_metric
tnsr::ii< DataType, SpatialDim, Frame > spatial_metric(const tnsr::aa< DataType, SpatialDim, Frame > &spacetime_metric) noexcept
Compute spatial metric from spacetime metric.
complex
gr::inverse_spacetime_metric
void inverse_spacetime_metric(gsl::not_null< tnsr::AA< DataType, SpatialDim, Frame > * > inverse_spacetime_metric, const Scalar< DataType > &lapse, const tnsr::I< DataType, SpatialDim, Frame > &shift, const tnsr::II< DataType, SpatialDim, Frame > &inverse_spatial_metric) noexcept
Compute inverse spacetime metric from inverse spatial metric, lapse and shift.
gr::spacetime_normal_vector
tnsr::A< DataType, SpatialDim, Frame > spacetime_normal_vector(const Scalar< DataType > &lapse, const tnsr::I< DataType, SpatialDim, Frame > &shift) noexcept
Computes spacetime normal vector from lapse and shift.