AnalyticDataHelpers.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
7 
8 #include <complex>
9 #include <cstddef>
10 
11 #include "DataStructures/ComplexDataVector.hpp"
12 #include "DataStructures/DataVector.hpp"
13 #include "DataStructures/SpinWeighted.hpp"
15 #include "Evolution/Systems/Cce/AnalyticSolutions/SphericalMetricData.hpp"
16 #include "Evolution/Systems/Cce/Tags.hpp"
17 #include "Framework/Pypp.hpp"
18 #include "NumericalAlgorithms/Spectral/SwshCollocation.hpp"
19 #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/SpatialDerivOfLapse.hpp"
20 #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/SpatialDerivOfShift.hpp"
21 #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/TimeDerivOfLapse.hpp"
22 #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/TimeDerivOfShift.hpp"
23 #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/TimeDerivOfSpatialMetric.hpp"
24 #include "PointwiseFunctions/GeneralRelativity/GeneralizedHarmonic/TimeDerivativeOfSpacetimeMetric.hpp"
25 #include "PointwiseFunctions/GeneralRelativity/InverseSpacetimeMetric.hpp"
26 #include "PointwiseFunctions/GeneralRelativity/Lapse.hpp"
27 #include "PointwiseFunctions/GeneralRelativity/Shift.hpp"
28 #include "PointwiseFunctions/GeneralRelativity/SpacetimeNormalVector.hpp"
29 #include "PointwiseFunctions/GeneralRelativity/SpatialMetric.hpp"
30 #include "Utilities/TaggedTuple.hpp"
31 
32 namespace Cce {
33 namespace Solutions {
34 namespace TestHelpers {
35 
36 template <typename SphericalSolution>
37 struct SphericalSolutionWrapper : public SphericalSolution {
38  using taglist =
39  tmpl::list<gr::Tags::SpacetimeMetric<
45  Tags::News>;
46  using SphericalSolution::SphericalSolution;
47 
48  template <typename... Args>
49  void test_spherical_metric(const std::string python_file, const size_t l_max,
50  const double time, Approx custom_approx,
51  const Args... args) const noexcept {
52  const size_t size =
54  Scalar<DataVector> sin_theta{size};
55  Scalar<DataVector> cos_theta{size};
56  const auto& collocation = Spectral::Swsh::cached_collocation_metadata<
57  Spectral::Swsh::ComplexRepresentation::Interleaved>(l_max);
58  for (const auto collocation_point : collocation) {
59  get(sin_theta)[collocation_point.offset] = sin(collocation_point.theta);
60  get(cos_theta)[collocation_point.offset] = cos(collocation_point.theta);
61  }
62  tnsr::aa<DataVector, 3, ::Frame::Spherical<::Frame::Inertial>>
63  local_spherical_metric{size};
64  tnsr::aa<DataVector, 3, ::Frame::Spherical<::Frame::Inertial>>
65  local_dr_spherical_metric{size};
66  tnsr::aa<DataVector, 3, ::Frame::Spherical<::Frame::Inertial>>
67  local_dt_spherical_metric{size};
68  Scalar<SpinWeighted<ComplexDataVector, -2>> local_news{size};
69 
70  this->spherical_metric(make_not_null(&local_spherical_metric), l_max, time);
71  this->dr_spherical_metric(make_not_null(&local_dr_spherical_metric), l_max,
72  time);
73  this->dt_spherical_metric(make_not_null(&local_dt_spherical_metric), l_max,
74  time);
75  this->variables_impl(make_not_null(&local_news), l_max, time,
76  tmpl::type_<Tags::News>{});
77 
78  // Pypp call expects all of the objects to be the same category -- here we
79  // need to use tensors, so we must pack up the `double` arguments into
80  // tensors.
81  Scalar<DataVector> time_vector;
82  get(time_vector) = DataVector{size, time};
83 
84  const auto py_spherical_metric = pypp::call<
85  tnsr::aa<DataVector, 3, ::Frame::Spherical<::Frame::Inertial>>>(
86  python_file, "spherical_metric", sin_theta, cos_theta, time_vector,
87  Scalar<DataVector>{DataVector{size, args}}...);
88  const auto py_dt_spherical_metric = pypp::call<
89  tnsr::aa<DataVector, 3, ::Frame::Spherical<::Frame::Inertial>>>(
90  python_file, "dt_spherical_metric", sin_theta, cos_theta, time_vector,
91  Scalar<DataVector>{DataVector{size, args}}...);
92  const auto py_dr_spherical_metric = pypp::call<
93  tnsr::aa<DataVector, 3, ::Frame::Spherical<::Frame::Inertial>>>(
94  python_file, "dr_spherical_metric", sin_theta, cos_theta, time_vector,
95  Scalar<DataVector>{DataVector{size, args}}...);
96  const auto py_news = pypp::call<Scalar<SpinWeighted<ComplexDataVector, 2>>>(
97  python_file, "news", sin_theta, time_vector,
98  Scalar<DataVector>{DataVector{size, args}}...);
99 
100  for (size_t a = 0; a < 4; ++a) {
101  for (size_t b = a; b < 4; ++b) {
102  CAPTURE(a);
103  CAPTURE(b);
104  const auto& lhs = local_spherical_metric.get(a, b);
105  const auto& rhs = py_spherical_metric.get(a, b);
106  CHECK_ITERABLE_CUSTOM_APPROX(lhs, rhs, custom_approx);
107  const auto& dt_lhs = local_dt_spherical_metric.get(a, b);
108  const auto& dt_rhs = py_dt_spherical_metric.get(a, b);
109  CHECK_ITERABLE_CUSTOM_APPROX(dt_lhs, dt_rhs, custom_approx);
110  const auto& dr_lhs = local_dr_spherical_metric.get(a, b);
111  const auto& dr_rhs = py_dr_spherical_metric.get(a, b);
112  CHECK_ITERABLE_CUSTOM_APPROX(dr_lhs, dr_rhs, custom_approx);
113  }
114  }
115  }
116 
117  void test_serialize_and_deserialize(const size_t l_max,
118  const double time) noexcept {
119  const size_t size =
121  tnsr::aa<DataVector, 3, ::Frame::Spherical<::Frame::Inertial>>
122  expected_spherical_metric{size};
123  this->spherical_metric(make_not_null(&expected_spherical_metric), l_max,
124  time);
125  auto serialized_and_deserialized_solution =
127  tnsr::aa<DataVector, 3, ::Frame::Spherical<::Frame::Inertial>>
128  local_spherical_metric{size};
129  serialized_and_deserialized_solution.spherical_metric(
130  make_not_null(&local_spherical_metric), l_max, time);
131  CHECK(expected_spherical_metric == local_spherical_metric);
132  }
133 
134  protected:
135  using SphericalSolution::extraction_radius_;
136 };
137 
138 // Test the `InitializeJ` object produced by the `WorldtubeData` against an
139 // expected `InitializeJ` object also provided in the arguments.
140 void test_initialize_j(
141  size_t l_max, size_t number_of_radial_points, double extraction_radius,
142  double time,
143  std::unique_ptr<InitializeJ::InitializeJ> expected_initialize_j,
144  std::unique_ptr<WorldtubeData> analytic_solution) noexcept;
145 
146 // This function determines the Bondi-Sachs scalars from a Cartesian spacetime
147 // metric, assuming that the metric is already in null form, so the spatial
148 // coordinates are related to standard Bondi-Sachs coordinates by just the
149 // standard Cartesian to spherical Jacobian.
151 extract_bondi_scalars_from_cartesian_metric(
152  const tnsr::aa<DataVector, 3>& spacetime_metric,
153  const CartesianiSphericalJ& inverse_jacobian,
154  double extraction_radius) noexcept;
155 
156 // This function determines the time derivative of the Bondi-Sachs scalars
157 // from the time derivative of a Cartesian spacetime metric, the Cartesian
158 // metric, and Jacobian factors. This procedure assumes that the metric is
159 // already in null form, so the spatial coordinates are related to standard
160 // Bondi-Sachs coordinates by just the standard cartesian to spherical Jacobian.
163 extract_dt_bondi_scalars_from_cartesian_metric(
164  const tnsr::aa<DataVector, 3>& dt_spacetime_metric,
165  const tnsr::aa<DataVector, 3>& spacetime_metric,
166  const CartesianiSphericalJ& inverse_jacobian,
167  double extraction_radius) noexcept;
168 
169 // This function determines the radial derivative of the Bondi-Sachs scalars
170 // from the radial derivative of a Cartesian spacetime metric, the Cartesian
171 // metric, and Jacobian factors. This procedure assumes that the metric is
172 // already in null form, so the spatial coordinates are related to standard
173 // Bondi-Sachs coordinates by just the standard cartesian to spherical Jacobian.
176 extract_dr_bondi_scalars_from_cartesian_metric(
177  const tnsr::aa<DataVector, 3>& dr_spacetime_metric,
178  const tnsr::aa<DataVector, 3>& spacetime_metric,
179  const CartesianiSphericalJ& inverse_jacobian,
180  const CartesianiSphericalJ& dr_inverse_jacobian,
181  double extraction_radius) noexcept;
182 
183 // This function checks the consistency of the 3+1 ADM quantities in the
184 // `boundary_tuple` with quantities computed from `expected_spacetime_metric`,
185 // `expected_dt_spacetime_metric`, and `expected_d_spacetime_metric`. If the
186 // expected quantities are also extracted from the tuple, this simply checks
187 // that the boundary computation has produced a consistent set of quantities
188 // and has not generated NaNs or other pathological values (e.g. a degenerate
189 // spacetime metric) in the process.
190 template <typename... TupleTags>
191 void check_adm_metric_quantities(
192  const tuples::TaggedTuple<TupleTags...>& boundary_tuple,
193  const tnsr::aa<DataVector, 3>& expected_spacetime_metric,
194  const tnsr::aa<DataVector, 3>& expected_dt_spacetime_metric,
195  const tnsr::iaa<DataVector, 3>& expected_d_spacetime_metric) noexcept {
196  // check the 3+1 quantities are computed correctly in the abstract base class
197  // `WorldtubeData`
198  const auto& dr_cartesian_coordinates =
199  get<Tags::Dr<Tags::CauchyCartesianCoords>>(boundary_tuple);
200 
201  const auto& lapse = get<gr::Tags::Lapse<DataVector>>(boundary_tuple);
202  const auto& shift =
203  get<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>(boundary_tuple);
204  const auto& spatial_metric =
205  get<gr::Tags::SpatialMetric<3, ::Frame::Inertial, DataVector>>(
206  boundary_tuple);
207 
208  const auto expected_spatial_metric =
209  gr::spatial_metric(expected_spacetime_metric);
210  const auto expected_inverse_spatial_metric =
211  determinant_and_inverse(expected_spatial_metric).second;
212  const auto expected_shift =
213  gr::shift(expected_spacetime_metric, expected_inverse_spatial_metric);
214  const auto expected_lapse =
215  gr::lapse(expected_shift, expected_spacetime_metric);
216  CHECK_ITERABLE_APPROX(spatial_metric, expected_spatial_metric);
217  CHECK_ITERABLE_APPROX(shift, expected_shift);
218  CHECK_ITERABLE_APPROX(lapse, expected_lapse);
219 
220  const auto& pi =
221  get<GeneralizedHarmonic::Tags::Pi<3, ::Frame::Inertial>>(boundary_tuple);
222  const auto dt_spacetime_metric_from_pi =
224  expected_lapse, expected_shift, pi, expected_d_spacetime_metric);
225  CHECK_ITERABLE_APPROX(expected_dt_spacetime_metric,
226  dt_spacetime_metric_from_pi);
227  // Check that the time derivative values are consistent with the Generalized
228  // Harmonic `pi` -- these are redundant if the boundary calculation uses `pi`
229  // to derive these, but it is not required to do so.
230  const auto& dt_lapse =
231  get<::Tags::dt<gr::Tags::Lapse<DataVector>>>(boundary_tuple);
232  const auto& dt_shift =
233  get<::Tags::dt<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>>(
234  boundary_tuple);
235  const auto& dt_spatial_metric = get<
237  boundary_tuple);
238  const auto expected_dt_spatial_metric =
240  expected_lapse, expected_shift, expected_d_spacetime_metric, pi);
241  const auto expected_spacetime_unit_normal =
242  gr::spacetime_normal_vector(expected_lapse, expected_shift);
243  const auto expected_dt_lapse = GeneralizedHarmonic::time_deriv_of_lapse(
244  expected_lapse, expected_shift, expected_spacetime_unit_normal,
245  expected_d_spacetime_metric, pi);
246  const auto expected_dt_shift = GeneralizedHarmonic::time_deriv_of_shift(
247  expected_lapse, expected_shift, expected_inverse_spatial_metric,
248  expected_spacetime_unit_normal, expected_d_spacetime_metric, pi);
249  CHECK_ITERABLE_APPROX(dt_lapse, expected_dt_lapse);
250  CHECK_ITERABLE_APPROX(dt_shift, expected_dt_shift);
251  CHECK_ITERABLE_APPROX(dt_spatial_metric, expected_dt_spatial_metric);
252 
253  const auto& dr_lapse =
254  get<Tags::Dr<gr::Tags::Lapse<DataVector>>>(boundary_tuple);
255  const auto& dr_shift =
256  get<Tags::Dr<gr::Tags::Shift<3, ::Frame::Inertial, DataVector>>>(
257  boundary_tuple);
258  const auto& dr_spatial_metric =
259  get<Tags::Dr<gr::Tags::SpatialMetric<3, ::Frame::Inertial, DataVector>>>(
260  boundary_tuple);
261  const auto expected_spatial_derivative_of_lapse =
263  expected_lapse, expected_spacetime_unit_normal,
264  expected_d_spacetime_metric);
265  const auto expected_inverse_spacetime_metric = gr::inverse_spacetime_metric(
266  expected_lapse, expected_shift, expected_inverse_spatial_metric);
267  const auto expected_spatial_derivative_of_shift =
269  expected_lapse, expected_inverse_spacetime_metric,
270  expected_spacetime_unit_normal, expected_d_spacetime_metric);
271  DataVector expected_buffer =
272  get<0>(dr_cartesian_coordinates) *
273  get<0>(expected_spatial_derivative_of_lapse) +
274  get<1>(dr_cartesian_coordinates) *
275  get<1>(expected_spatial_derivative_of_lapse) +
276  get<2>(dr_cartesian_coordinates) *
277  get<2>(expected_spatial_derivative_of_lapse);
278  CHECK_ITERABLE_APPROX(expected_buffer, get(dr_lapse));
279  for (size_t i = 0; i < 3; ++i) {
280  expected_buffer = get<0>(dr_cartesian_coordinates) *
281  expected_spatial_derivative_of_shift.get(0, i) +
282  get<1>(dr_cartesian_coordinates) *
283  expected_spatial_derivative_of_shift.get(1, i) +
284  get<2>(dr_cartesian_coordinates) *
285  expected_spatial_derivative_of_shift.get(2, i);
286  CHECK_ITERABLE_APPROX(expected_buffer, dr_shift.get(i));
287  for (size_t j = i; j < 3; ++j) {
288  expected_buffer = get<0>(dr_cartesian_coordinates) *
289  expected_d_spacetime_metric.get(0, i + 1, j + 1) +
290  get<1>(dr_cartesian_coordinates) *
291  expected_d_spacetime_metric.get(1, i + 1, j + 1) +
292  get<2>(dr_cartesian_coordinates) *
293  expected_d_spacetime_metric.get(2, i + 1, j + 1);
294  CHECK_ITERABLE_APPROX(expected_buffer, dr_spatial_metric.get(i, j));
295  }
296  }
297 }
298 
299 } // namespace TestHelpers
300 } // namespace Solutions
301 } // 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 .
std::string
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...
TestingFramework.hpp
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.
db::get
const auto & get(const DataBox< TagList > &box) noexcept
Retrieve the item with tag Tag from the DataBox.
Definition: DataBox.hpp:791
CHECK_ITERABLE_CUSTOM_APPROX
#define CHECK_ITERABLE_CUSTOM_APPROX(a, b, appx)
Same as CHECK_ITERABLE_APPROX with user-defined Approx. The third argument should be of type Approx.
Definition: TestingFramework.hpp:134
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:122
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 ...
SpinWeighted
Make a spin-weighted type T with spin-weight Spin. Mathematical operators are restricted to addition,...
Definition: SpinWeighted.hpp:24
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.
pypp::call
ReturnType call(const std::string &module_name, const std::string &function_name, const Args &... t)
Calls a Python function from a module/file with given parameters.
Definition: Pypp.hpp:494
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
Pypp.hpp
cstddef
gr::Tags::SpacetimeMetric
Definition: Tags.hpp:17
tuples::TaggedTuple
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:271
DataVector
Stores a collection of function values.
Definition: DataVector.hpp:46
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 ,...
Cce::Solutions::TestHelpers::SphericalSolutionWrapper
Definition: AnalyticDataHelpers.hpp:37
serialize_and_deserialize
T serialize_and_deserialize(const T &t)
Serializes and deserializes an object t of type T
Definition: TestHelpers.hpp:45
Cce::Tags::News
Definition: Tags.hpp:152
Frame::Spherical
Represents a spherical-coordinate frame that is associated with a Cartesian frame,...
Definition: IndexType.hpp:54
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
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: CharacteristicExtractFwd.hpp:6
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
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
ComplexDataVector
Stores a collection of complex function values.
Definition: ComplexDataVector.hpp:53
Spectral::Swsh::cached_collocation_metadata
const CollocationMetadata< Representation > & cached_collocation_metadata(size_t l_max) noexcept
precomputation function for those collocation grids that are requested
std::unique_ptr
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.
Cce::Tags::Dr
The derivative with respect to Bondi .
Definition: Tags.hpp:125
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:24