GaugeTransformBoundaryData.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/SpinWeighted.hpp"
11 #include "DataStructures/Tags.hpp"
16 #include "Evolution/Systems/Cce/Tags.hpp"
17 #include "NumericalAlgorithms/Spectral/SwshCollocation.hpp"
18 #include "NumericalAlgorithms/Spectral/SwshDerivatives.hpp"
19 #include "NumericalAlgorithms/Spectral/SwshInterpolation.hpp"
20 #include "Utilities/Gsl.hpp"
21 #include "Utilities/TMPL.hpp"
22 
23 namespace Cce {
24 
25 /// The set of tags that should be calculated before the initial data is
26 /// computed on the first hypersurface.
28  tmpl::list<Tags::BondiR, Tags::BondiJ, Tags::Dr<Tags::BondiJ>>;
29 
30 template <typename Tag>
32 
33 /*!
34  * \brief Computes the evolution gauge Bondi \f$\hat R\f$ on the worldtube from
35  * Cauchy gauge quantities
36  *
37  * \details The evolution gauge Bondi \f$\hat R\f$ obeys:
38  *
39  * \f{align*}{
40  * \hat R = \hat \omega R(\hat x^{\hat A}),
41  * \f}
42  *
43  * where the evaluation of \f$R\f$ at \f$\hat x^{\hat A}\f$ requires an
44  * interpolation to the evolution coordinates, and \f$\hat \omega\f$ is the
45  * conformal factor associated with the angular part of the gauge
46  * transformation.
47  */
48 template <>
50  using return_tags =
51  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>>;
52  using argument_tags = tmpl::list<
55 
56  static void apply(
58  evolution_gauge_r,
59  const Scalar<SpinWeighted<ComplexDataVector, 0>>& cauchy_gauge_r,
61  const Spectral::Swsh::SwshInterpolator& interpolator) noexcept;
62 };
63 
64 /*!
65  * \brief Computes the evolution gauge \f$\partial_{\hat u} \hat R / \hat R\f$
66  * on the worldtube.
67  *
68  * \details The evolution gauge quantity \f$ \partial_{\hat u} \hat R / \hat
69  * R\f$ obeys
70  *
71  * \f{align*}{
72  * \frac{\partial_{\hat u} \hat R}{ \hat R}
73  * = \frac{\partial_u R (\hat x^{\hat A})}{R(\hat x^{\hat A})}
74  * + \frac{\partial_{\hat u} \hat \omega}{\hat \omega}
75  * + \frac{\mathcal U^{(0)} \bar \eth R(\hat x^{\hat A})
76  * + \bar{\mathcal U}^{(0)} \eth R(\hat x^{\hat A}) }{2 R(\hat x^{\hat A})}
77  * \f}
78  *
79  * note that the terms proportional to \f$\eth R\f$ or its conjugate arise from
80  * the conversion between \f$\partial_u\f$ and \f$\partial_{\hat u}f\f$. The
81  * right-hand side quantities with explicit \f$\hat x\f$ require interpolation.
82  * \f$\mathcal U^{(0)}\f$ is the asymptotic quantity determined by
83  * `GaugeUpdateTimeDerivatives`.
84  */
85 template <>
86 struct GaugeAdjustedBoundaryValue<Tags::DuRDividedByR> {
87  using return_tags =
88  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::DuRDividedByR>>;
89  using argument_tags = tmpl::list<
95 
96  static void apply(
98  evolution_gauge_du_r_divided_by_r,
100  cauchy_gauge_du_r_divided_by_r,
101  const Scalar<SpinWeighted<ComplexDataVector, 1>>& bondi_u_at_scri,
102  const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_r,
105  const Spectral::Swsh::SwshInterpolator& interpolator,
106  size_t l_max) noexcept;
107 };
108 
109 /*!
110  * \brief Computes the evolution gauge quantity \f$\hat J\f$ on the worldtube
111  *
112  * \details The evolution gauge quantity \f$\hat J\f$ obeys
113  *
114  * \f{align*}{
115  * \hat J = \frac{1}{4 \hat{\omega}^2} \left( \bar{\hat d}^2 J(\hat x^{\hat A})
116  * + \hat c^2 \bar J(\hat x^{\hat A})
117  * + 2 \hat c \bar{\hat d} K(\hat x^{\hat A}) \right)
118  * \f}
119  *
120  * Where \f$\hat c\f$ and \f$\hat d\f$ are the spin-weighted angular Jacobian
121  * factors computed by `GaugeUpdateJacobianFromCoords`, and \f$\hat \omega\f$ is
122  * the conformal factor associated with the angular coordinate transformation.
123  * Note that the right-hand sides with explicit \f$\hat x^{\hat A}\f$ dependence
124  * must be interpolated and that \f$K = \sqrt{1 + J \bar J}\f$.
125  */
126 template <>
128  using return_tags =
129  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiJ>>;
130  using argument_tags = tmpl::list<
134 
135  static void apply(
137  evolution_gauge_j,
138  const Scalar<SpinWeighted<ComplexDataVector, 2>>& cauchy_gauge_j,
142  const Spectral::Swsh::SwshInterpolator& interpolator) noexcept;
143 };
144 
145 /*!
146  * \brief Computes the evolution gauge quantity \f$\partial_{\hat r} \hat J\f$
147  * on the worldtube
148  *
149  * \details The evolution gauge quantity \f$\partial_{\hat r} \hat J\f$ is
150  * determined from \f$\partial_{\hat r} = \frac{\partial_r}{\hat \omega}\f$ and
151  * the expression for \f$\hat J\f$ given in the documentation for
152  * `GaugeAdjustedBoundaryValue<Tags::BondiJ>`
153  */
154 template <>
155 struct GaugeAdjustedBoundaryValue<Tags::Dr<Tags::BondiJ>> {
156  using return_tags =
157  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::Dr<Tags::BondiJ>>>;
158  using argument_tags = tmpl::list<
164 
165  static void apply(
167  evolution_gauge_dr_j,
168  const Scalar<SpinWeighted<ComplexDataVector, 2>>& cauchy_gauge_dr_j,
169  const Scalar<SpinWeighted<ComplexDataVector, 2>>& cauchy_gauge_j,
173  const Spectral::Swsh::SwshInterpolator& interpolator,
174  size_t l_max) noexcept;
175 };
176 
177 /*!
178  * \brief Computes the evolution gauge quantity \f$\hat \beta\f$ on the
179  * worldtube
180  *
181  * \details The evolution gauge quantity \f$\hat \beta\f$ obeys
182  *
183  * \f{align*}{
184  * e^{2 \hat \beta} = e^{2 \beta(\hat x^{\hat A})} / \hat \omega.
185  * \f}
186  *
187  * The explicit evaluation at \f$\hat x^{\hat A}\f$ on the right-hand side
188  * indicates the requirement of an interpolation step, and \f$\hat \omega\f$ is
189  * the conformal factor associated with the angular transformation.
190  */
191 template <>
192 struct GaugeAdjustedBoundaryValue<Tags::BondiBeta> {
193  using return_tags =
194  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiBeta>>;
195  using argument_tags = tmpl::list<
198 
199  static void apply(
201  evolution_gauge_beta,
202  const Scalar<SpinWeighted<ComplexDataVector, 0>>& cauchy_gauge_beta,
204  const Spectral::Swsh::SwshInterpolator& interpolator) noexcept;
205 };
206 
207 /*!
208  * \brief Computes the evolution gauge quantity \f$\hat Q\f$ on the worldtube.
209  *
210  * \details The evolution gauge quantity \f$\hat Q\f$ obeys
211  *
212  * \f{align*}{
213  * \hat Q =& \hat r^2 e^{-2 \hat \beta} (\hat K \partial_{\hat r} \hat U
214  * + \hat J \partial_{\hat r} \hat{\bar U}),\\
215  * \partial_{\hat r} \hat U
216  * =& \frac{1}{2 \hat \omega^3}\left(\hat{\bar d} \partial_r U(\hat x^{\hat A})
217  * - \hat c \partial_r \bar U(\hat x^{\hat A})\right)
218  * + \frac{e^{2\hat \beta}}{\hat r^2 \hat \omega}
219  * \left(\hat J \hat{\bar{\eth}} \hat \omega
220  * - \hat K \hat \eth \hat \omega\right)
221  * \left(-1 + \partial_{\hat y} \hat{\bar{J}} \partial_{\hat y} \hat J
222  * - \left[\frac{\partial_{\hat y}(\hat J \hat{\bar{J}})}
223  * {2 \hat K}\right]^2\right) \notag \\
224  * & + 2 \frac{e^{2 \hat \beta}}{\hat \omega \hat r^2}
225  * \left[ \hat{\bar{\eth}} \hat \omega \partial_{\hat y} \hat J
226  * + \hat{\eth} \hat \omega \left(-\frac{\hat J \partial_{\hat y}
227  * \hat{\bar J}
228  * + \hat{\bar J} \partial_{\hat y} \hat J}{2 \hat K}\right) \right].
229  * \f}
230  *
231  * where the explicit argument \f$\hat x^{\hat A}\f$ on the right-hand side
232  * implies the need for an interpolation operation, and
233  * \f$K = \sqrt{1 + J \bar J}\f$.
234  */
235 template <>
237  using return_tags =
238  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiQ>>;
239 
240  using argument_tags = tmpl::list<
245  Spectral::Swsh::Tags::Derivative<Tags::GaugeOmega,
249 
250  static void apply(
252  evolution_gauge_q,
253  const Scalar<SpinWeighted<ComplexDataVector, 1>>& cauchy_gauge_dr_u,
255  const Scalar<SpinWeighted<ComplexDataVector, 2>>& volume_dy_j,
256  const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_r,
257  const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_beta,
261  const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
262  const Spectral::Swsh::SwshInterpolator& interpolator,
263  const size_t l_max) noexcept {
264  apply_impl(make_not_null(&get(*evolution_gauge_q)), get(cauchy_gauge_dr_u),
265  get(volume_j), get(volume_dy_j), get(evolution_gauge_r),
266  get(evolution_gauge_beta), get(gauge_c), get(gauge_d),
267  get(omega), get(eth_omega), interpolator, l_max);
268  }
269 
270  private:
271  static void apply_impl(
273  const SpinWeighted<ComplexDataVector, 1>& cauchy_gauge_dr_u,
274  const SpinWeighted<ComplexDataVector, 2>& volume_j,
275  const SpinWeighted<ComplexDataVector, 2>& volume_dy_j,
276  const SpinWeighted<ComplexDataVector, 0>& evolution_gauge_r,
277  const SpinWeighted<ComplexDataVector, 0>& evolution_gauge_beta,
278  const SpinWeighted<ComplexDataVector, 2>& gauge_c,
279  const SpinWeighted<ComplexDataVector, 0>& gauge_d,
281  const SpinWeighted<ComplexDataVector, 1>& eth_omega,
282  const Spectral::Swsh::SwshInterpolator& interpolator,
283  size_t l_max) noexcept;
284 };
285 
286 /*!
287  * \brief Computes the evolution gauge quantity \f$\mathcal U\f$ on the
288  * worldtube.
289  *
290  * \details Note that the boundary quantity computed by this function is, by
291  * necessity, NOT the evolution gauge bondi \f$\hat U\f$, because there is
292  * insufficient information at the point in the computation this will be
293  * evaluated to completely determine \f$\hat{U}\f$. Instead, this determines
294  * the boundary value of \f$\mathcal U\f$, which satisfies,
295  *
296  * \f{align*}{
297  * \mathcal{U} - \mathcal{U}^{(0)} = \hat U,
298  * \f}
299  *
300  * where the superscript \f$(0)\f$ denotes evaluation at \f$\mathcal I^+\f$. In
301  * particular, the result of this computation may be used with the same
302  * hypersurface equations as the full evolution gauge \f$\hat U\f$, because they
303  * satisfy the same radial differential equation.
304  *
305  * \f$\mathcal U\f$ is computed by,
306  *
307  * \f{align*}{
308  * \mathcal U = \frac{1}{2\hat \omega^2} \left(\hat{\bar d} U(\hat x^{\hat A})
309  * - \hat c \bar U(\hat x^{\hat A}) \right)
310  * - \frac{e^{2 \hat \beta}}{\hat r \hat \omega}
311  * \left(\hat K \hat \eth \hat \omega
312  * - \hat J\hat{\bar{\eth}} \hat \omega\right),
313  * \f}
314  *
315  * where the explicit argument \f$\hat x^{\hat A}\f$ on the right-hand side
316  * implies the need for an interpolation operation, and
317  * \f$K = \sqrt{1 + J \bar J}\f$.
318  */
319 template <>
321  using return_tags =
322  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiU>>;
323  using argument_tags = tmpl::list<
328  Spectral::Swsh::Tags::Derivative<Tags::GaugeOmega,
332 
333  static void apply(
335  evolution_gauge_u,
336  const Scalar<SpinWeighted<ComplexDataVector, 1>>& cauchy_gauge_u,
338  const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_r,
339  const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_beta,
343  const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
344  const Spectral::Swsh::SwshInterpolator& interpolator,
345  size_t l_max) noexcept;
346 };
347 
348 /*!
349  * \brief Computes the evolution gauge quantity \f$\hat W\f$ on the worldtube.
350  *
351  * \details The evolution gauge value \f$\hat W\f$ obeys
352  *
353  * \f{align*}{
354  * \hat W =& W(\hat x^{\hat A}) + (\hat \omega - 1) / \hat r
355  * + \frac{e^{2 \hat \beta}}{2 \hat \omega^2 \hat r}
356  * \left(\hat J \left(\hat{\bar \eth} \hat \omega\right)^2
357  * + \hat{\bar{J}} \left(\hat \eth \hat \omega\right) ^2
358  * - 2 K \left( \hat \eth \hat \omega\right) \left(\hat{\bar \eth} \hat
359  * \omega\right) \right)
360  * - \frac{2 \partial_{u} \hat \omega}{\hat \omega}
361  * - \frac{ \hat U \bar \eth \hat \omega + \hat{\bar U} \eth \hat \omega }
362  * {\hat \omega},
363  * \f}
364  *
365  * where the explicit argument \f$\hat x^{\hat A}\f$ on the right-hand side
366  * implies the need for an interpolation operation and
367  * \f$K = \sqrt{1 + J \bar J}\f$.
368  */
369 template <>
371  using return_tags =
372  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiW>>;
373  using argument_tags = tmpl::list<
379  Spectral::Swsh::Tags::Derivative<Tags::GaugeOmega,
383 
384  static void apply(
386  evolution_gauge_w,
387  const Scalar<SpinWeighted<ComplexDataVector, 0>>& cauchy_gauge_w,
389  const Scalar<SpinWeighted<ComplexDataVector, 1>>& evolution_gauge_u,
390  const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_beta,
392  evolution_gauge_u_at_scri,
393  const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_r,
396  const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
397  const Spectral::Swsh::SwshInterpolator& interpolator,
398  const size_t l_max) noexcept {
399  apply_impl(make_not_null(&get(*evolution_gauge_w)), get(cauchy_gauge_w),
400  get(volume_j), get(evolution_gauge_u), get(evolution_gauge_beta),
401  get(evolution_gauge_u_at_scri), get(evolution_gauge_r),
402  get(omega), get(du_omega), get(eth_omega), interpolator, l_max);
403  }
404 
405  private:
406  static void apply_impl(
408  const SpinWeighted<ComplexDataVector, 0>& cauchy_gauge_w,
409  const SpinWeighted<ComplexDataVector, 2>& volume_j,
410  const SpinWeighted<ComplexDataVector, 1>& evolution_gauge_u,
411  const SpinWeighted<ComplexDataVector, 0>& evolution_gauge_beta,
412  const SpinWeighted<ComplexDataVector, 1>& evolution_gauge_u_at_scri,
413  const SpinWeighted<ComplexDataVector, 0>& evolution_gauge_r,
415  const SpinWeighted<ComplexDataVector, 0>& du_omega,
416  const SpinWeighted<ComplexDataVector, 1>& eth_omega,
417  const Spectral::Swsh::SwshInterpolator& interpolator,
418  size_t l_max) noexcept;
419 };
420 
421 /*!
422  * \brief Computes the evolution gauge quantity \f$\hat H\f$ on the worldtube.
423  *
424  * \details The evolution gauge \f$\hat H\f$ obeys
425  *
426  * \f{align*}{
427  * \hat H =&
428  * \frac{1}{2} \left(\mathcal{U}^{(0)} \hat{\bar \eth} \hat J
429  * + \bar{\mathcal{U}}^{(0)} \hat{\eth} \hat J\right)
430  * + \frac{\partial_{\hat u} \hat \omega
431  * - \tfrac{1}{2} \left(\mathcal{U}^{(0)} \bar{\hat \eth}\hat \omega
432  * + \bar{\mathcal{U}}^{(0)} \hat \eth \hat \omega \right) }{\hat \omega}
433  * \left(2 \hat J - 2 \partial_{\hat y} \hat J\right)
434  * - \hat J\hat{\bar \eth} \mathcal{U}^{(0)}
435  * + \hat K \hat \eth \bar{\mathcal{U}}^{(0)} \notag\\
436  * &+ \frac{1}{4 \hat \omega^2} \left(\hat{\bar d}^2 H(\hat x^{\hat A})
437  * + \hat c^2 \bar H(\hat x^{\hat A})
438  * + \hat{\bar d} \hat c \frac{H(\hat x^{\hat A}) \bar J(\hat x^{\hat A})
439  * + J(\hat x^{\hat A}) \bar H(\hat x^{\hat A})}{K}\right)
440  * + 2 \frac{\partial_u R}{R} \partial_{\hat y} J
441  * \f}
442  *
443  * where the superscript \f$(0)\f$ denotes evaluation at \f$\mathcal I^+\f$ and
444  * the explicit \f$\hat x^{\hat A}\f$ arguments on the right-hand side imply
445  * interpolation operations, and \f$K = \sqrt{1 + J \bar J}\f$,
446  * \f$\hat K = \sqrt{1 + \hat J \hat{\bar J}}\f$.
447  */
448 template <>
450  using return_tags =
451  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiH>>;
452  using argument_tags = tmpl::list<
457  Spectral::Swsh::Tags::Derivative<Tags::GaugeOmega,
462 
463  static void apply(
465  evolution_gauge_h,
467  const Scalar<SpinWeighted<ComplexDataVector, 2>>& cauchy_gauge_du_j,
468  const Scalar<SpinWeighted<ComplexDataVector, 2>>& volume_dy_j,
470  evolution_gauge_u_at_scri,
471  const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_r,
476  const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
478  evolution_gauge_du_r_divided_by_r,
479  const Spectral::Swsh::SwshInterpolator& interpolator,
480  const size_t l_max) noexcept {
481  apply_impl(make_not_null(&get(*evolution_gauge_h)), get(volume_j),
482  get(cauchy_gauge_du_j), get(volume_dy_j),
483  get(evolution_gauge_u_at_scri), get(evolution_gauge_r),
484  get(gauge_c), get(gauge_d), get(omega), get(du_omega),
485  get(eth_omega), get(evolution_gauge_du_r_divided_by_r),
486  interpolator, l_max);
487  }
488 
489  private:
490  static void apply_impl(
492  const SpinWeighted<ComplexDataVector, 2>& volume_j,
493  const SpinWeighted<ComplexDataVector, 2>& cauchy_gauge_du_j,
494  const SpinWeighted<ComplexDataVector, 2>& volume_dy_j,
495  const SpinWeighted<ComplexDataVector, 1>& evolution_gauge_u_at_scri,
496  const SpinWeighted<ComplexDataVector, 0>& evolution_gauge_r,
497  const SpinWeighted<ComplexDataVector, 2>& gauge_c,
498  const SpinWeighted<ComplexDataVector, 0>& gauge_d,
500  const SpinWeighted<ComplexDataVector, 0>& du_omega,
501  const SpinWeighted<ComplexDataVector, 1>& eth_omega,
503  evolution_gauge_du_r_divided_by_r,
504  const Spectral::Swsh::SwshInterpolator& interpolator,
505  size_t l_max) noexcept;
506 };
507 
508 /*!
509  * \brief Update the Cauchy gauge cartesian coordinate derivative \f$\partial_u
510  * x(\hat x)\f$, as well as remaining gauge quantities \f$\mathcal U^{(0)}\f$,
511  * \f$\hat U \equiv \mathcal U - \mathcal U^{(0)}\f$, and \f$\partial_{\hat u}
512  * \hat \omega\f$ to maintain asymptotically inertial angular coordinates.
513  *
514  * \details The constraint we must satisfy to maintain the asymptotically
515  * inertial angular coordinates is
516  *
517  * \f{align*}{
518  * \partial_{\hat u} x^A = \mathcal U^{(0) \hat A} \partial_{\hat A} x^{A},
519  * \f}
520  *
521  * which we compute for a representative Cartesian coordinate set on the unit
522  * sphere, to maintain representability and ensure that angular transform and
523  * derivative operations keep the desired precision. The equation we use for the
524  * Cartesian analog is:
525  *
526  * \f{align*}{
527  * \partial_{\hat u} x^i &= \frac{1}{2} (\bar{\mathcal U}^{(0)} \hat \eth x^i +
528  * \mathcal U^{(0)} \hat{\bar \eth} x^i ) \\
529  * &= \text{Re}(\bar{\mathcal U}^{(0)} \hat \eth x^i)
530  * \f}
531  *
532  * This computation completes the unfixed degrees of freedom for the coordinate
533  * transformation at the boundary, so also computes the gauge quantities that
534  * rely on this information \f$\mathcal U^{(0)}\f$,
535  * \f$\hat U\f$, and \f$\partial_{\hat u} \hat \omega\f$.
536  *
537  * The time derivative of \f$\hat \omega\f$ is calculated from the equation
538  * \f{align*}{
539  * \partial_{\hat u} \hat \omega
540  * = \frac{\hat \omega}{4} (\hat{\bar \eth} \mathcal U^{(0)}
541  * + \hat \eth \bar{\mathcal U}^{(0)})
542  * + \frac{1}{2} (\mathcal U^{(0)} \hat{\bar \eth} \hat \omega
543  * + \bar{\mathcal U}^{(0)} \hat \eth \hat \omega)
544  * \f}
545  * \warning Before this update call the quantity stored in the tag
546  * `Cce::Tags::BondiU` represents \f$\mathcal U\f$, and after this update call,
547  * it represents \f$\hat U\f$ (the true evolution gauge quantity).
548  */
550  using return_tags =
551  tmpl::list<::Tags::dt<Tags::CauchyCartesianCoords>, Tags::BondiUAtScri,
553  using argument_tags =
555  Spectral::Swsh::Tags::Derivative<Tags::GaugeOmega,
558 
559  static void apply(
560  gsl::not_null<tnsr::i<DataVector, 3>*> cartesian_cauchy_du_x,
562  evolution_gauge_u_at_scri,
565  const tnsr::i<DataVector, 3>& cartesian_cauchy_coordinates,
567  const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
568  size_t l_max) noexcept;
569 };
570 
571 /*!
572  * \brief Update the angular coordinates stored in `AngularTag` via
573  * trigonometric operations applied to the Cartesian coordinates stored in
574  * `CartesianTag`.
575  *
576  * \details This function also normalizes the Cartesian coordinates stored in
577  * `CartesianTag`, which is the desired behavior for the CCE boundary
578  * computation.
579  */
580 template <typename AngularTag, typename CartesianTag>
582  using argument_tags = tmpl::list<>;
583  using return_tags = tmpl::list<AngularTag, CartesianTag>;
584 
585  static void apply(
586  const gsl::not_null<
588  angular_coordinates,
589  const gsl::not_null<tnsr::i<DataVector, 3>*>
590  cartesian_coordinates) noexcept {
591  // normalize the cartesian coordinates
592  const DataVector one_over_cartesian_r =
593  1.0 / sqrt(square(get<0>(*cartesian_coordinates)) +
594  square(get<1>(*cartesian_coordinates)) +
595  square(get<2>(*cartesian_coordinates)));
596 
597  get<0>(*cartesian_coordinates) *= one_over_cartesian_r;
598  get<1>(*cartesian_coordinates) *= one_over_cartesian_r;
599  get<2>(*cartesian_coordinates) *= one_over_cartesian_r;
600 
601  const auto& x = get<0>(*cartesian_coordinates);
602  const auto& y = get<1>(*cartesian_coordinates);
603  const auto& z = get<2>(*cartesian_coordinates);
604 
605  get<0>(*angular_coordinates) = atan2(sqrt(square(x) + square(y)), z);
606  get<1>(*angular_coordinates) = atan2(y, x);
607  }
608 };
609 
610 namespace detail {
611 void gauge_update_jacobian_from_coordinates_apply_impl(
613  gauge_factor_spin_2,
615  gauge_factor_spin_0,
618  angular_source_coordinates,
619  const tnsr::i<DataVector, 3>& cartesian_source_coordinates,
620  size_t l_max) noexcept;
621 } // namespace detail
622 
623 /*!
624  * \brief From the angular coordinates `AngularCoordinateTag` and the Cartesian
625  * coordinates `CartesianCoordinateTag`, determine the spin-weighted Jacobian
626  * factors `GaugeFactorSpin2` and `GaugeFactorSpin0`.
627  *
628  * \details This is most often used in the context of generating the Jacobians
629  * in the evolution-gauge coordinates from the Cauchy collocation points as a
630  * function of the evolution gauge coordinates. In this concrete case, the
631  * `GaugeFactorSpin2` is the gauge factor \f$\hat c\f$ and takes the value
632  *
633  * \f{align*}{
634  * \hat c = \hat q^{\hat A} \partial_{\hat A}(x^A) q_A,
635  * \f}
636  *
637  * and the `GaugeFactorSpin0` is the gauge factor \f$\hat d\f$ and takes the
638  * value
639  *
640  * \f{align*}{
641  * \hat d = \hat{\bar q}^{\hat A} \partial_{\hat A}(x^A) q_A.
642  * \f}
643  *
644  * The more generic template construction is employed so that the spin-weighted
645  * Jacobians can also be computed between two arbitrary gauges, including the
646  * inverse Jacobians associated with moving from the evolution gauge to the
647  * Cauchy gauge.
648  */
649 template <typename GaugeFactorSpin2, typename GaugeFactorSpin0,
650  typename AngularCoordinateTag, typename CartesianCoordinateTag>
652  using return_tags =
653  tmpl::list<GaugeFactorSpin2, GaugeFactorSpin0, AngularCoordinateTag>;
654  using argument_tags =
655  tmpl::list<CartesianCoordinateTag, Spectral::Swsh::Tags::LMax>;
656 
657  static void apply(
659  gauge_factor_spin_2,
661  gauge_factor_spin_0,
662  const gsl::not_null<
664  angular_source_coordinates,
665  const tnsr::i<DataVector, 3>& cartesian_source_coordinates,
666  const size_t l_max) noexcept {
667  detail::gauge_update_jacobian_from_coordinates_apply_impl(
668  gauge_factor_spin_2, gauge_factor_spin_0, angular_source_coordinates,
669  cartesian_source_coordinates, l_max);
670  }
671 };
672 
673 /*!
674  * \brief Update the interpolator stored in
675  * `Spectral::Swsh::Tags::SwshInterpolator<AngularCoordinates>`.
676  *
677  * \details Note that the `AngularCoordinates` associated with the interpolator
678  * should be the source coordinates. For instance, when interpolating a quantity
679  * defined on the Cauchy gauge collocation points to the evolution gauge
680  * collocation points, the interpolator input should be the Cauchy coordinates
681  * points as a function of the evolution gauge coordinates (at the evolution
682  * gauge collocation points).
683  */
684 template <typename AngularCoordinates>
686  using return_tags =
687  tmpl::list<Spectral::Swsh::Tags::SwshInterpolator<AngularCoordinates>>;
688  using argument_tags =
689  tmpl::list<AngularCoordinates, Spectral::Swsh::Tags::LMax>;
690 
691  static void apply(
693  const tnsr::i<DataVector, 2, ::Frame::Spherical<::Frame::Inertial>>&
694  angular_coordinates,
695  const size_t l_max) noexcept {
696  // throw away the old interpolator and generate a new one for the current
697  // grid points.
698  *interpolator = Spectral::Swsh::SwshInterpolator(
699  get<0>(angular_coordinates), get<1>(angular_coordinates), l_max);
700  }
701 };
702 
703 /*!
704  * \brief Update the quantity \f$\hat \omega\f$ and \f$\hat \eth \hat \omega\f$
705  * for updated spin-weighted Jacobian quantities \f$\hat c\f$ and \f$\hat d\f$.
706  *
707  * \details The conformal factor \f$\hat \omega\f$ can be determined by the
708  * angular determinant from the spin-weighted Jacobian factors as
709  *
710  * \f{align*}{
711  * \hat \omega = \frac{1}{2} \sqrt{\hat d \hat{\bar d} - \hat c \hat{\bar c}}.
712  * \f}
713  */
715  using argument_tags =
716  tmpl::list<Tags::GaugeC, Tags::GaugeD, Spectral::Swsh::Tags::LMax>;
717  using return_tags =
718  tmpl::list<Tags::GaugeOmega,
719  Spectral::Swsh::Tags::Derivative<Tags::GaugeOmega,
721 
722  static void apply(
727  size_t l_max) noexcept;
728 };
729 
730 /*!
731  * \brief Initialize to default values (identity transform) all of the angular
732  * gauge quantities for the boundary gauge transforms.
733  *
734  * \details The updated quantities are the Cauchy angular and Cartesian
735  * coordinates, as well as the spin-weighted gauge factors and the conformal
736  * factor. All quantities are initialized to the appropriate value for the
737  * identity transform of angular coordinates. Using this initialization function
738  * ensures that the evolution gauge and the Cauchy gauge angular coordinates
739  * agree on the first evaluated time.
740  * - `CauchyAngularCoords` are set to the angular collocation values for the
741  * spin-weighted spherical harmonic library
742  * - `CauchyCartesianCoords` are set to the Cartesian coordinates for the
743  * `CauchyAngularCoords` evaluated on a unit sphere.
744  * - `GaugeC` is set to 0
745  * - `GaugeD` is set to 2
746  * - `GaugeOmega` is set to 1
747  */
749  using return_tags =
752  using argument_tags = tmpl::list<Spectral::Swsh::Tags::LMax>;
753 
754  static void apply(
757  angular_cauchy_coordinates,
758  gsl::not_null<tnsr::i<DataVector, 3>*> cartesian_cauchy_coordinates,
762  size_t l_max) noexcept;
763 };
764 } // namespace Cce
Definition: GaugeTransformBoundaryData.hpp:31
Contains functionality for Cauchy Characteristic Extraction.
Definition: BoundaryComputeAndSendToEvolution.hpp:24
Bondi parameter .
Definition: Tags.hpp:43
From the angular coordinates AngularCoordinateTag and the Cartesian coordinates CartesianCoordinateTa...
Definition: GaugeTransformBoundaryData.hpp:651
The spin-weight 0 angular Jacobian factor.
Definition: Tags.hpp:134
Update the Cauchy gauge cartesian coordinate derivative , as well as remaining gauge quantities ...
Definition: GaugeTransformBoundaryData.hpp:549
Performs interpolation for spin-weighted spherical harmonics by taking advantage of the Clenshaw meth...
Definition: SwshInterpolation.hpp:229
Define prefixes for DataBox tags.
Prefix tag representing the spin-weighted derivative of a spin-weighted scalar.
Definition: SwshTags.hpp:139
Initialize to default values (identity transform) all of the angular gauge quantities for the boundar...
Definition: GaugeTransformBoundaryData.hpp:748
The spin-weight 2 angular Jacobian factor.
Definition: Tags.hpp:129
Definition: Determinant.hpp:11
Make a spin-weighted type T with spin-weight Spin. Mathematical operators are restricted to addition...
Definition: SpinWeighted.hpp:25
Update the angular coordinates stored in AngularTag via trigonometric operations applied to the Carte...
Definition: GaugeTransformBoundaryData.hpp:581
Bondi parameter .
Definition: Tags.hpp:73
The surface quantity of Bondi evaluated at the null spacetime boundary .
Definition: Tags.hpp:80
A prefix tag representing the gauge-transformed boundary data for a quantity on the extraction surfac...
Definition: Tags.hpp:199
Defines class Variables.
tmpl::list< Tags::BondiR, Tags::BondiJ, Tags::Dr< Tags::BondiJ > > gauge_adjustments_setup_tags
The set of tags that should be calculated before the initial data is computed on the first hypersurfa...
Definition: GaugeTransformBoundaryData.hpp:28
Definition: DataBoxTag.hpp:29
The conformal factor associated with an angular transformation.
Definition: Tags.hpp:139
The derivative with respect to the numerical coordinate , where is Bondi radius of the worldtube...
Definition: Tags.hpp:99
Defines classes for Tensor.
Defines a list of useful type aliases for tensors.
constexpr auto apply(F &&f, const DataBox< BoxTags > &box, Args &&... args) noexcept
Apply the invokable f with argument Tags TagsList from DataBox box
Definition: DataBox.hpp:1628
Struct for labeling the spin-weighted derivative in tags.
Definition: SwshTags.hpp:29
Tag for the maximum spin-weighted spherical harmonic l; sets angular resolution.
Definition: SwshTags.hpp:187
Stores a collection of function values.
Definition: DataVector.hpp:42
Represents a spherical-coordinate frame that is associated with a Cartesian frame, e.g. associated with the Inertial frame, as used on an apparent horizon or a wave-extraction surface.
Definition: IndexType.hpp:54
Wraps the template metaprogramming library used (brigand)
Update the quantity and for updated spin-weighted Jacobian quantities and .
Definition: GaugeTransformBoundaryData.hpp:714
Definition: Tags.hpp:149
Defines functions and classes from the GSL.
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, but it may be necessary to perform the conversion explicitly when type deduction is desired.
Definition: Gsl.hpp:879
The derivative with respect to Bondi retarded time .
Definition: Tags.hpp:120
Update the interpolator stored in Spectral::Swsh::Tags::SwshInterpolator<AngularCoordinates>.
Definition: GaugeTransformBoundaryData.hpp:685
A prefix tag representing the boundary data for a quantity on the extraction surface.
Definition: Tags.hpp:188
decltype(auto) constexpr square(const T &x)
Compute the square of x
Definition: ConstantExpressions.hpp:52
Definition: Tags.hpp:155
Tensor< T, Symmetry<>, index_list<> > Scalar
Scalar type.
Definition: TypeAliases.hpp:21
Tag for a SwshInterpolator associated with a particular set of angular coordinates.
Definition: SwshTags.hpp:209
Require a pointer to not be a nullptr
Definition: Gsl.hpp:182
Defines classes representing tensor indices.