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 namespace Tags {
26 /// \cond
27 struct LMax;
28 struct NumberOfRadialPoints;
29 /// \endcond
30 } // namespace Tags
31 
32 /// The set of tags that should be calculated before the initial data is
33 /// computed on the first hypersurface.
35  tmpl::list<Tags::BondiR, Tags::BondiJ, Tags::Dr<Tags::BondiJ>>;
36 
37 /*!
38  * \brief Computes the gauge-transformed
39  * `Tags::EvolutionGaugeBoundaryValue<Tag>` for any of the boundary tags needed
40  * in the evolution.
41  *
42  * \details Most of these computations involve first interpolating via a
43  * `Spectral::Swsh::SwshInterpolator` to the new angular grid, followed by
44  * manipulations associated with the tensor transformation of the metric and its
45  * derivatives. Individual template specializations contain detailed
46  * explanations about the respective gauge transformations.
47  */
48 template <typename Tag>
50 
51 /*!
52  * \brief Computes the evolution gauge Bondi \f$\hat R\f$ on the worldtube from
53  * Cauchy gauge quantities
54  *
55  * \details The evolution gauge Bondi \f$\hat R\f$ obeys:
56  *
57  * \f{align*}{
58  * \hat R = \hat \omega R(\hat x^{\hat A}),
59  * \f}
60  *
61  * where the evaluation of \f$R\f$ at \f$\hat x^{\hat A}\f$ requires an
62  * interpolation to the evolution coordinates, and \f$\hat \omega\f$ is the
63  * conformal factor associated with the angular part of the gauge
64  * transformation.
65  */
66 template <>
68  using return_tags =
69  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>>;
70  using argument_tags = tmpl::list<
73 
74  static void apply(
76  evolution_gauge_r,
77  const Scalar<SpinWeighted<ComplexDataVector, 0>>& cauchy_gauge_r,
79  const Spectral::Swsh::SwshInterpolator& interpolator) noexcept;
80 };
81 
82 /*!
83  * \brief Computes the evolution gauge \f$\partial_{\hat u} \hat R / \hat R\f$
84  * on the worldtube.
85  *
86  * \details The evolution gauge quantity \f$ \partial_{\hat u} \hat R / \hat
87  * R\f$ obeys
88  *
89  * \f{align*}{
90  * \frac{\partial_{\hat u} \hat R}{ \hat R}
91  * = \frac{\partial_u R (\hat x^{\hat A})}{R(\hat x^{\hat A})}
92  * + \frac{\partial_{\hat u} \hat \omega}{\hat \omega}
93  * + \frac{\mathcal U^{(0)} \bar \eth R(\hat x^{\hat A})
94  * + \bar{\mathcal U}^{(0)} \eth R(\hat x^{\hat A}) }{2 R(\hat x^{\hat A})}
95  * \f}
96  *
97  * note that the terms proportional to \f$\eth R\f$ or its conjugate arise from
98  * the conversion between \f$\partial_u\f$ and \f$\partial_{\hat u}f\f$. The
99  * right-hand side quantities with explicit \f$\hat x\f$ require interpolation.
100  * \f$\mathcal U^{(0)}\f$ is the asymptotic quantity determined by
101  * `GaugeUpdateTimeDerivatives`.
102  */
103 template <>
104 struct GaugeAdjustedBoundaryValue<Tags::DuRDividedByR> {
105  using return_tags =
106  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::DuRDividedByR>>;
107  using argument_tags = tmpl::list<
112  Tags::LMax>;
113 
114  static void apply(
116  evolution_gauge_du_r_divided_by_r,
118  cauchy_gauge_du_r_divided_by_r,
119  const Scalar<SpinWeighted<ComplexDataVector, 1>>& bondi_u_at_scri,
120  const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_r,
123  const Spectral::Swsh::SwshInterpolator& interpolator,
124  size_t l_max) noexcept;
125 };
126 
127 /*!
128  * \brief Computes the evolution gauge quantity \f$\hat J\f$ on the worldtube
129  *
130  * \details The evolution gauge quantity \f$\hat J\f$ obeys
131  *
132  * \f{align*}{
133  * \hat J = \frac{1}{4 \hat{\omega}^2} \left( \bar{\hat d}^2 J(\hat x^{\hat A})
134  * + \hat c^2 \bar J(\hat x^{\hat A})
135  * + 2 \hat c \bar{\hat d} K(\hat x^{\hat A}) \right)
136  * \f}
137  *
138  * Where \f$\hat c\f$ and \f$\hat d\f$ are the spin-weighted angular Jacobian
139  * factors computed by `GaugeUpdateJacobianFromCoords`, and \f$\hat \omega\f$ is
140  * the conformal factor associated with the angular coordinate transformation.
141  * Note that the right-hand sides with explicit \f$\hat x^{\hat A}\f$ dependence
142  * must be interpolated and that \f$K = \sqrt{1 + J \bar J}\f$.
143  */
144 template <>
146  using return_tags =
147  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiJ>>;
148  using argument_tags = tmpl::list<
152 
153  static void apply(
155  evolution_gauge_j,
156  const Scalar<SpinWeighted<ComplexDataVector, 2>>& cauchy_gauge_j,
160  const Spectral::Swsh::SwshInterpolator& interpolator) noexcept;
161 };
162 
163 /*!
164  * \brief Computes the evolution gauge quantity \f$\partial_{\hat r} \hat J\f$
165  * on the worldtube
166  *
167  * \details The evolution gauge quantity \f$\partial_{\hat r} \hat J\f$ is
168  * determined from \f$\partial_{\hat r} = \frac{\partial_r}{\hat \omega}\f$ and
169  * the expression for \f$\hat J\f$ given in the documentation for
170  * `GaugeAdjustedBoundaryValue<Tags::BondiJ>`
171  */
172 template <>
173 struct GaugeAdjustedBoundaryValue<Tags::Dr<Tags::BondiJ>> {
174  using return_tags =
175  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::Dr<Tags::BondiJ>>>;
176  using argument_tags = tmpl::list<
181  Tags::LMax>;
182 
183  static void apply(
185  evolution_gauge_dr_j,
186  const Scalar<SpinWeighted<ComplexDataVector, 2>>& cauchy_gauge_dr_j,
187  const Scalar<SpinWeighted<ComplexDataVector, 2>>& cauchy_gauge_j,
191  const Spectral::Swsh::SwshInterpolator& interpolator,
192  size_t l_max) noexcept;
193 };
194 
195 /*!
196  * \brief Computes the evolution gauge quantity \f$\hat \beta\f$ on the
197  * worldtube
198  *
199  * \details The evolution gauge quantity \f$\hat \beta\f$ obeys
200  *
201  * \f{align*}{
202  * e^{2 \hat \beta} = e^{2 \beta(\hat x^{\hat A})} / \hat \omega.
203  * \f}
204  *
205  * The explicit evaluation at \f$\hat x^{\hat A}\f$ on the right-hand side
206  * indicates the requirement of an interpolation step, and \f$\hat \omega\f$ is
207  * the conformal factor associated with the angular transformation.
208  */
209 template <>
210 struct GaugeAdjustedBoundaryValue<Tags::BondiBeta> {
211  using return_tags =
212  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiBeta>>;
213  using argument_tags = tmpl::list<
216 
217  static void apply(
219  evolution_gauge_beta,
220  const Scalar<SpinWeighted<ComplexDataVector, 0>>& cauchy_gauge_beta,
222  const Spectral::Swsh::SwshInterpolator& interpolator) noexcept;
223 };
224 
225 /*!
226  * \brief Computes the evolution gauge quantity \f$\hat Q\f$ on the worldtube.
227  *
228  * \details The evolution gauge quantity \f$\hat Q\f$ obeys
229  *
230  * \f{align*}{
231  * \hat Q =& \hat r^2 e^{-2 \hat \beta} (\hat K \partial_{\hat r} \hat U
232  * + \hat J \partial_{\hat r} \hat{\bar U}),\\
233  * \partial_{\hat r} \hat U
234  * =& \frac{1}{2 \hat \omega^3}\left(\hat{\bar d} \partial_r U(\hat x^{\hat A})
235  * - \hat c \partial_r \bar U(\hat x^{\hat A})\right)
236  * + \frac{e^{2\hat \beta}}{\hat r^2 \hat \omega}
237  * \left(\hat J \hat{\bar{\eth}} \hat \omega
238  * - \hat K \hat \eth \hat \omega\right)
239  * \left(-1 + \partial_{\hat y} \hat{\bar{J}} \partial_{\hat y} \hat J
240  * - \left[\frac{\partial_{\hat y}(\hat J \hat{\bar{J}})}
241  * {2 \hat K}\right]^2\right) \notag \\
242  * & + 2 \frac{e^{2 \hat \beta}}{\hat \omega \hat r^2}
243  * \left[ \hat{\bar{\eth}} \hat \omega \partial_{\hat y} \hat J
244  * + \hat{\eth} \hat \omega \left(-\frac{\hat J \partial_{\hat y}
245  * \hat{\bar J}
246  * + \hat{\bar J} \partial_{\hat y} \hat J}{2 \hat K}\right) \right].
247  * \f}
248  *
249  * where the explicit argument \f$\hat x^{\hat A}\f$ on the right-hand side
250  * implies the need for an interpolation operation, and
251  * \f$K = \sqrt{1 + J \bar J}\f$.
252  */
253 template <>
255  using return_tags =
256  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiQ>>;
257 
258  using argument_tags = tmpl::list<
263  Spectral::Swsh::Tags::Derivative<Tags::GaugeOmega,
266  Tags::LMax>;
267 
268  static void apply(
270  evolution_gauge_q,
271  const Scalar<SpinWeighted<ComplexDataVector, 1>>& cauchy_gauge_dr_u,
273  const Scalar<SpinWeighted<ComplexDataVector, 2>>& volume_dy_j,
274  const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_r,
275  const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_beta,
279  const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
280  const Spectral::Swsh::SwshInterpolator& interpolator,
281  const size_t l_max) noexcept {
282  apply_impl(make_not_null(&get(*evolution_gauge_q)), get(cauchy_gauge_dr_u),
283  get(volume_j), get(volume_dy_j), get(evolution_gauge_r),
284  get(evolution_gauge_beta), get(gauge_c), get(gauge_d),
285  get(omega), get(eth_omega), interpolator, l_max);
286  }
287 
288  private:
289  static void apply_impl(
291  const SpinWeighted<ComplexDataVector, 1>& cauchy_gauge_dr_u,
292  const SpinWeighted<ComplexDataVector, 2>& volume_j,
293  const SpinWeighted<ComplexDataVector, 2>& volume_dy_j,
294  const SpinWeighted<ComplexDataVector, 0>& evolution_gauge_r,
295  const SpinWeighted<ComplexDataVector, 0>& evolution_gauge_beta,
296  const SpinWeighted<ComplexDataVector, 2>& gauge_c,
297  const SpinWeighted<ComplexDataVector, 0>& gauge_d,
299  const SpinWeighted<ComplexDataVector, 1>& eth_omega,
300  const Spectral::Swsh::SwshInterpolator& interpolator,
301  size_t l_max) noexcept;
302 };
303 
304 /*!
305  * \brief Computes the evolution gauge quantity \f$\mathcal U\f$ on the
306  * worldtube.
307  *
308  * \details Note that the boundary quantity computed by this function is, by
309  * necessity, NOT the evolution gauge bondi \f$\hat U\f$, because there is
310  * insufficient information at the point in the computation this will be
311  * evaluated to completely determine \f$\hat{U}\f$. Instead, this determines
312  * the boundary value of \f$\mathcal U\f$, which satisfies,
313  *
314  * \f{align*}{
315  * \mathcal{U} - \mathcal{U}^{(0)} = \hat U,
316  * \f}
317  *
318  * where the superscript \f$(0)\f$ denotes evaluation at \f$\mathcal I^+\f$. In
319  * particular, the result of this computation may be used with the same
320  * hypersurface equations as the full evolution gauge \f$\hat U\f$, because they
321  * satisfy the same radial differential equation.
322  *
323  * \f$\mathcal U\f$ is computed by,
324  *
325  * \f{align*}{
326  * \mathcal U = \frac{1}{2\hat \omega^2} \left(\hat{\bar d} U(\hat x^{\hat A})
327  * - \hat c \bar U(\hat x^{\hat A}) \right)
328  * - \frac{e^{2 \hat \beta}}{\hat r \hat \omega}
329  * \left(\hat K \hat \eth \hat \omega
330  * - \hat J\hat{\bar{\eth}} \hat \omega\right),
331  * \f}
332  *
333  * where the explicit argument \f$\hat x^{\hat A}\f$ on the right-hand side
334  * implies the need for an interpolation operation, and
335  * \f$K = \sqrt{1 + J \bar J}\f$.
336  */
337 template <>
339  using return_tags =
340  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiU>>;
341  using argument_tags = tmpl::list<
346  Spectral::Swsh::Tags::Derivative<Tags::GaugeOmega,
349  Tags::LMax>;
350 
351  static void apply(
353  evolution_gauge_u,
354  const Scalar<SpinWeighted<ComplexDataVector, 1>>& cauchy_gauge_u,
356  const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_r,
357  const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_beta,
361  const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
362  const Spectral::Swsh::SwshInterpolator& interpolator,
363  size_t l_max) noexcept;
364 };
365 
366 /*!
367  * \brief Computes the evolution gauge quantity \f$\hat W\f$ on the worldtube.
368  *
369  * \details The evolution gauge value \f$\hat W\f$ obeys
370  *
371  * \f{align*}{
372  * \hat W =& W(\hat x^{\hat A}) + (\hat \omega - 1) / \hat r
373  * + \frac{e^{2 \hat \beta}}{2 \hat \omega^2 \hat r}
374  * \left(\hat J \left(\hat{\bar \eth} \hat \omega\right)^2
375  * + \hat{\bar{J}} \left(\hat \eth \hat \omega\right) ^2
376  * - 2 K \left( \hat \eth \hat \omega\right) \left(\hat{\bar \eth} \hat
377  * \omega\right) \right)
378  * - \frac{2 \partial_{u} \hat \omega}{\hat \omega}
379  * - \frac{ \hat U \bar \eth \hat \omega + \hat{\bar U} \eth \hat \omega }
380  * {\hat \omega},
381  * \f}
382  *
383  * where the explicit argument \f$\hat x^{\hat A}\f$ on the right-hand side
384  * implies the need for an interpolation operation and
385  * \f$K = \sqrt{1 + J \bar J}\f$.
386  */
387 template <>
389  using return_tags =
390  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiW>>;
391  using argument_tags = tmpl::list<
397  Spectral::Swsh::Tags::Derivative<Tags::GaugeOmega,
400  Tags::LMax>;
401 
402  static void apply(
404  evolution_gauge_w,
405  const Scalar<SpinWeighted<ComplexDataVector, 0>>& cauchy_gauge_w,
407  const Scalar<SpinWeighted<ComplexDataVector, 1>>& evolution_gauge_u,
408  const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_beta,
410  evolution_gauge_u_at_scri,
411  const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_r,
414  const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
415  const Spectral::Swsh::SwshInterpolator& interpolator,
416  const size_t l_max) noexcept {
417  apply_impl(make_not_null(&get(*evolution_gauge_w)), get(cauchy_gauge_w),
418  get(volume_j), get(evolution_gauge_u), get(evolution_gauge_beta),
419  get(evolution_gauge_u_at_scri), get(evolution_gauge_r),
420  get(omega), get(du_omega), get(eth_omega), interpolator, l_max);
421  }
422 
423  private:
424  static void apply_impl(
426  const SpinWeighted<ComplexDataVector, 0>& cauchy_gauge_w,
427  const SpinWeighted<ComplexDataVector, 2>& volume_j,
428  const SpinWeighted<ComplexDataVector, 1>& evolution_gauge_u,
429  const SpinWeighted<ComplexDataVector, 0>& evolution_gauge_beta,
430  const SpinWeighted<ComplexDataVector, 1>& evolution_gauge_u_at_scri,
431  const SpinWeighted<ComplexDataVector, 0>& evolution_gauge_r,
433  const SpinWeighted<ComplexDataVector, 0>& du_omega,
434  const SpinWeighted<ComplexDataVector, 1>& eth_omega,
435  const Spectral::Swsh::SwshInterpolator& interpolator,
436  size_t l_max) noexcept;
437 };
438 
439 /*!
440  * \brief Computes the evolution gauge quantity \f$\hat H\f$ on the worldtube.
441  *
442  * \details The evolution gauge \f$\hat H\f$ obeys
443  *
444  * \f{align*}{
445  * \hat H =&
446  * \frac{1}{2} \left(\mathcal{U}^{(0)} \hat{\bar \eth} \hat J
447  * + \bar{\mathcal{U}}^{(0)} \hat{\eth} \hat J\right)
448  * + \frac{\partial_{\hat u} \hat \omega
449  * - \tfrac{1}{2} \left(\mathcal{U}^{(0)} \bar{\hat \eth}\hat \omega
450  * + \bar{\mathcal{U}}^{(0)} \hat \eth \hat \omega \right) }{\hat \omega}
451  * \left(2 \hat J - 2 \partial_{\hat y} \hat J\right)
452  * - \hat J\hat{\bar \eth} \mathcal{U}^{(0)}
453  * + \hat K \hat \eth \bar{\mathcal{U}}^{(0)} \notag\\
454  * &+ \frac{1}{4 \hat \omega^2} \left(\hat{\bar d}^2 H(\hat x^{\hat A})
455  * + \hat c^2 \bar H(\hat x^{\hat A})
456  * + \hat{\bar d} \hat c \frac{H(\hat x^{\hat A}) \bar J(\hat x^{\hat A})
457  * + J(\hat x^{\hat A}) \bar H(\hat x^{\hat A})}{K}\right)
458  * + 2 \frac{\partial_u R}{R} \partial_{\hat y} J
459  * \f}
460  *
461  * where the superscript \f$(0)\f$ denotes evaluation at \f$\mathcal I^+\f$ and
462  * the explicit \f$\hat x^{\hat A}\f$ arguments on the right-hand side imply
463  * interpolation operations, and \f$K = \sqrt{1 + J \bar J}\f$,
464  * \f$\hat K = \sqrt{1 + \hat J \hat{\bar J}}\f$.
465  */
466 template <>
468  using return_tags =
469  tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiH>>;
470  using argument_tags = tmpl::list<
475  Spectral::Swsh::Tags::Derivative<Tags::GaugeOmega,
479  Tags::LMax>;
480 
481  static void apply(
483  evolution_gauge_h,
485  const Scalar<SpinWeighted<ComplexDataVector, 2>>& cauchy_gauge_du_j,
486  const Scalar<SpinWeighted<ComplexDataVector, 2>>& volume_dy_j,
488  evolution_gauge_u_at_scri,
489  const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_r,
494  const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
496  evolution_gauge_du_r_divided_by_r,
497  const Spectral::Swsh::SwshInterpolator& interpolator,
498  const size_t l_max) noexcept {
499  apply_impl(make_not_null(&get(*evolution_gauge_h)), get(volume_j),
500  get(cauchy_gauge_du_j), get(volume_dy_j),
501  get(evolution_gauge_u_at_scri), get(evolution_gauge_r),
502  get(gauge_c), get(gauge_d), get(omega), get(du_omega),
503  get(eth_omega), get(evolution_gauge_du_r_divided_by_r),
504  interpolator, l_max);
505  }
506 
507  private:
508  static void apply_impl(
510  const SpinWeighted<ComplexDataVector, 2>& volume_j,
511  const SpinWeighted<ComplexDataVector, 2>& cauchy_gauge_du_j,
512  const SpinWeighted<ComplexDataVector, 2>& volume_dy_j,
513  const SpinWeighted<ComplexDataVector, 1>& evolution_gauge_u_at_scri,
514  const SpinWeighted<ComplexDataVector, 0>& evolution_gauge_r,
515  const SpinWeighted<ComplexDataVector, 2>& gauge_c,
516  const SpinWeighted<ComplexDataVector, 0>& gauge_d,
518  const SpinWeighted<ComplexDataVector, 0>& du_omega,
519  const SpinWeighted<ComplexDataVector, 1>& eth_omega,
521  evolution_gauge_du_r_divided_by_r,
522  const Spectral::Swsh::SwshInterpolator& interpolator,
523  size_t l_max) noexcept;
524 };
525 
526 /*!
527  * \brief Update the Cauchy gauge cartesian coordinate derivative \f$\partial_u
528  * x(\hat x)\f$, as well as remaining gauge quantities \f$\mathcal U^{(0)}\f$,
529  * \f$\hat U \equiv \mathcal U - \mathcal U^{(0)}\f$, and \f$\partial_{\hat u}
530  * \hat \omega\f$ to maintain asymptotically inertial angular coordinates.
531  *
532  * \details The constraint we must satisfy to maintain the asymptotically
533  * inertial angular coordinates is
534  *
535  * \f{align*}{
536  * \partial_{\hat u} x^A = \mathcal U^{(0) \hat A} \partial_{\hat A} x^{A},
537  * \f}
538  *
539  * which we compute for a representative Cartesian coordinate set on the unit
540  * sphere, to maintain representability and ensure that angular transform and
541  * derivative operations keep the desired precision. The equation we use for the
542  * Cartesian analog is:
543  *
544  * \f{align*}{
545  * \partial_{\hat u} x^i &= \frac{1}{2} (\bar{\mathcal U}^{(0)} \hat \eth x^i +
546  * \mathcal U^{(0)} \hat{\bar \eth} x^i ) \\
547  * &= \text{Re}(\bar{\mathcal U}^{(0)} \hat \eth x^i)
548  * \f}
549  *
550  * This computation completes the unfixed degrees of freedom for the coordinate
551  * transformation at the boundary, so also computes the gauge quantities that
552  * rely on this information \f$\mathcal U^{(0)}\f$,
553  * \f$\hat U\f$, and \f$\partial_{\hat u} \hat \omega\f$.
554  *
555  * The time derivative of \f$\hat \omega\f$ is calculated from the equation
556  * \f{align*}{
557  * \partial_{\hat u} \hat \omega
558  * = \frac{\hat \omega}{4} (\hat{\bar \eth} \mathcal U^{(0)}
559  * + \hat \eth \bar{\mathcal U}^{(0)})
560  * + \frac{1}{2} (\mathcal U^{(0)} \hat{\bar \eth} \hat \omega
561  * + \bar{\mathcal U}^{(0)} \hat \eth \hat \omega)
562  * \f}
563  * \warning Before this update call the quantity stored in the tag
564  * `Cce::Tags::BondiU` represents \f$\mathcal U\f$, and after this update call,
565  * it represents \f$\hat U\f$ (the true evolution gauge quantity).
566  */
568  using return_tags =
569  tmpl::list<::Tags::dt<Tags::CauchyCartesianCoords>, Tags::BondiUAtScri,
571  using argument_tags =
573  Spectral::Swsh::Tags::Derivative<Tags::GaugeOmega,
575  Tags::LMax>;
576 
577  static void apply(
578  gsl::not_null<tnsr::i<DataVector, 3>*> cartesian_cauchy_du_x,
580  evolution_gauge_u_at_scri,
583  const tnsr::i<DataVector, 3>& cartesian_cauchy_coordinates,
585  const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
586  size_t l_max) noexcept;
587 };
588 
589 /*!
590  * \brief Update the angular coordinates stored in `AngularTag` via
591  * trigonometric operations applied to the Cartesian coordinates stored in
592  * `CartesianTag`.
593  *
594  * \details This function also normalizes the Cartesian coordinates stored in
595  * `CartesianTag`, which is the desired behavior for the CCE boundary
596  * computation.
597  */
598 template <typename AngularTag, typename CartesianTag>
600  using argument_tags = tmpl::list<>;
601  using return_tags = tmpl::list<AngularTag, CartesianTag>;
602 
603  static void apply(
604  const gsl::not_null<
606  angular_coordinates,
607  const gsl::not_null<tnsr::i<DataVector, 3>*>
608  cartesian_coordinates) noexcept {
609  // normalize the cartesian coordinates
610  const DataVector one_over_cartesian_r =
611  1.0 / sqrt(square(get<0>(*cartesian_coordinates)) +
612  square(get<1>(*cartesian_coordinates)) +
613  square(get<2>(*cartesian_coordinates)));
614 
615  get<0>(*cartesian_coordinates) *= one_over_cartesian_r;
616  get<1>(*cartesian_coordinates) *= one_over_cartesian_r;
617  get<2>(*cartesian_coordinates) *= one_over_cartesian_r;
618 
619  const auto& x = get<0>(*cartesian_coordinates);
620  const auto& y = get<1>(*cartesian_coordinates);
621  const auto& z = get<2>(*cartesian_coordinates);
622 
623  get<0>(*angular_coordinates) = atan2(sqrt(square(x) + square(y)), z);
624  get<1>(*angular_coordinates) = atan2(y, x);
625  }
626 };
627 
628 namespace detail {
629 void gauge_update_jacobian_from_coordinates_apply_impl(
631  gauge_factor_spin_2,
633  gauge_factor_spin_0,
636  angular_source_coordinates,
637  const tnsr::i<DataVector, 3>& cartesian_source_coordinates,
638  size_t l_max) noexcept;
639 } // namespace detail
640 
641 /*!
642  * \brief From the angular coordinates `AngularCoordinateTag` and the Cartesian
643  * coordinates `CartesianCoordinateTag`, determine the spin-weighted Jacobian
644  * factors `GaugeFactorSpin2` and `GaugeFactorSpin0`.
645  *
646  * \details This is most often used in the context of generating the Jacobians
647  * in the evolution-gauge coordinates from the Cauchy collocation points as a
648  * function of the evolution gauge coordinates. In this concrete case, the
649  * `GaugeFactorSpin2` is the gauge factor \f$\hat c\f$ and takes the value
650  *
651  * \f{align*}{
652  * \hat c = \hat q^{\hat A} \partial_{\hat A}(x^A) q_A,
653  * \f}
654  *
655  * and the `GaugeFactorSpin0` is the gauge factor \f$\hat d\f$ and takes the
656  * value
657  *
658  * \f{align*}{
659  * \hat d = \hat{\bar q}^{\hat A} \partial_{\hat A}(x^A) q_A.
660  * \f}
661  *
662  * The more generic template construction is employed so that the spin-weighted
663  * Jacobians can also be computed between two arbitrary gauges, including the
664  * inverse Jacobians associated with moving from the evolution gauge to the
665  * Cauchy gauge.
666  */
667 template <typename GaugeFactorSpin2, typename GaugeFactorSpin0,
668  typename AngularCoordinateTag, typename CartesianCoordinateTag>
670  using return_tags =
671  tmpl::list<GaugeFactorSpin2, GaugeFactorSpin0, AngularCoordinateTag>;
672  using argument_tags = tmpl::list<CartesianCoordinateTag, Tags::LMax>;
673 
674  static void apply(
676  gauge_factor_spin_2,
678  gauge_factor_spin_0,
679  const gsl::not_null<
681  angular_source_coordinates,
682  const tnsr::i<DataVector, 3>& cartesian_source_coordinates,
683  const size_t l_max) noexcept {
684  detail::gauge_update_jacobian_from_coordinates_apply_impl(
685  gauge_factor_spin_2, gauge_factor_spin_0, angular_source_coordinates,
686  cartesian_source_coordinates, l_max);
687  }
688 };
689 
690 /*!
691  * \brief Update the interpolator stored in
692  * `Spectral::Swsh::Tags::SwshInterpolator<AngularCoordinates>`.
693  *
694  * \details Note that the `AngularCoordinates` associated with the interpolator
695  * should be the source coordinates. For instance, when interpolating a quantity
696  * defined on the Cauchy gauge collocation points to the evolution gauge
697  * collocation points, the interpolator input should be the Cauchy coordinates
698  * points as a function of the evolution gauge coordinates (at the evolution
699  * gauge collocation points).
700  */
701 template <typename AngularCoordinates>
703  using return_tags =
704  tmpl::list<Spectral::Swsh::Tags::SwshInterpolator<AngularCoordinates>>;
705  using argument_tags = tmpl::list<AngularCoordinates, Tags::LMax>;
706 
707  static void apply(
709  const tnsr::i<DataVector, 2, ::Frame::Spherical<::Frame::Inertial>>&
710  angular_coordinates,
711  const size_t l_max) noexcept {
712  // throw away the old interpolator and generate a new one for the current
713  // grid points.
714  *interpolator = Spectral::Swsh::SwshInterpolator(
715  get<0>(angular_coordinates), get<1>(angular_coordinates), l_max);
716  }
717 };
718 
719 /*!
720  * \brief Update the quantity \f$\hat \omega\f$ and \f$\hat \eth \hat \omega\f$
721  * for updated spin-weighted Jacobian quantities \f$\hat c\f$ and \f$\hat d\f$.
722  *
723  * \details The conformal factor \f$\hat \omega\f$ can be determined by the
724  * angular determinant from the spin-weighted Jacobian factors as
725  *
726  * \f{align*}{
727  * \hat \omega = \frac{1}{2} \sqrt{\hat d \hat{\bar d} - \hat c \hat{\bar c}}.
728  * \f}
729  */
731  using argument_tags = tmpl::list<Tags::GaugeC, Tags::GaugeD, Tags::LMax>;
732  using return_tags =
733  tmpl::list<Tags::GaugeOmega,
734  Spectral::Swsh::Tags::Derivative<Tags::GaugeOmega,
736 
737  static void apply(
742  size_t l_max) noexcept;
743 };
744 
745 /*!
746  * \brief Initialize to default values (identity transform) all of the angular
747  * gauge quantities for the boundary gauge transforms.
748  *
749  * \details The updated quantities are the Cauchy angular and Cartesian
750  * coordinates, as well as the spin-weighted gauge factors and the conformal
751  * factor. All quantities are initialized to the appropriate value for the
752  * identity transform of angular coordinates. Using this initialization function
753  * ensures that the evolution gauge and the Cauchy gauge angular coordinates
754  * agree on the first evaluated time.
755  * - `CauchyAngularCoords` are set to the angular collocation values for the
756  * spin-weighted spherical harmonic library
757  * - `CauchyCartesianCoords` are set to the Cartesian coordinates for the
758  * `CauchyAngularCoords` evaluated on a unit sphere.
759  * - `GaugeC` is set to 0
760  * - `GaugeD` is set to 2
761  * - `GaugeOmega` is set to 1
762  */
764  using return_tags =
767  using argument_tags = tmpl::list<Tags::LMax>;
768 
769  static void apply(
772  angular_cauchy_coordinates,
773  gsl::not_null<tnsr::i<DataVector, 3>*> cartesian_cauchy_coordinates,
777  size_t l_max) noexcept;
778 };
779 } // namespace Cce
Computes the gauge-transformed Tags::EvolutionGaugeBoundaryValue<Tag> for any of the boundary tags ne...
Definition: GaugeTransformBoundaryData.hpp:49
The set of utilities for performing Cauchy characteristic evolution and Cauchy characteristic matchin...
Definition: BoundaryComputeAndSendToEvolution.hpp:28
Bondi parameter .
Definition: Tags.hpp:34
From the angular coordinates AngularCoordinateTag and the Cartesian coordinates CartesianCoordinateTa...
Definition: GaugeTransformBoundaryData.hpp:669
The spin-weight 0 angular Jacobian factor.
Definition: Tags.hpp:150
Update the Cauchy gauge cartesian coordinate derivative , as well as remaining gauge quantities ...
Definition: GaugeTransformBoundaryData.hpp:567
Performs interpolation for spin-weighted spherical harmonics by taking advantage of the Clenshaw meth...
Definition: SwshInterpolation.hpp:229
Define prefixes for DataBox tags.
Definition: OptionTags.hpp:221
Prefix tag representing the spin-weighted derivative of a spin-weighted scalar.
Definition: SwshTags.hpp:152
Initialize to default values (identity transform) all of the angular gauge quantities for the boundar...
Definition: GaugeTransformBoundaryData.hpp:763
The spin-weight 2 angular Jacobian factor.
Definition: Tags.hpp:145
Definition: Determinant.hpp:11
Make a spin-weighted type T with spin-weight Spin. Mathematical operators are restricted to addition...
Definition: SpinWeighted.hpp:24
Update the angular coordinates stored in AngularTag via trigonometric operations applied to the Carte...
Definition: GaugeTransformBoundaryData.hpp:599
Bondi parameter .
Definition: Tags.hpp:89
The surface quantity of Bondi evaluated at the null spacetime boundary .
Definition: Tags.hpp:96
A prefix tag representing the gauge-transformed boundary data for a quantity on the extraction surfac...
Definition: Tags.hpp:215
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:35
Definition: DataBoxTag.hpp:27
The conformal factor associated with an angular transformation.
Definition: Tags.hpp:155
The derivative with respect to the numerical coordinate , where is Bondi radius of the worldtube...
Definition: Tags.hpp:115
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:1444
Struct for labeling the spin-weighted derivative in tags.
Definition: SwshTags.hpp:30
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
::Tags::dt< BondiJ > BondiH
Bondi parameter .
Definition: Tags.hpp:62
Wraps the template metaprogramming library used (brigand)
Update the quantity and for updated spin-weighted Jacobian quantities and .
Definition: GaugeTransformBoundaryData.hpp:730
Definition: Tags.hpp:165
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:136
Update the interpolator stored in Spectral::Swsh::Tags::SwshInterpolator<AngularCoordinates>.
Definition: GaugeTransformBoundaryData.hpp:702
A prefix tag representing the boundary data for a quantity on the extraction surface.
Definition: Tags.hpp:204
decltype(auto) constexpr square(const T &x)
Compute the square of x
Definition: ConstantExpressions.hpp:54
Definition: Tags.hpp:171
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:230
Require a pointer to not be a nullptr
Definition: Gsl.hpp:182
Defines classes representing tensor indices.