Line data Source code
1 0 : // 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"
9 : #include "DataStructures/DataBox/Prefixes.hpp"
10 : #include "DataStructures/SpinWeighted.hpp"
11 : #include "DataStructures/Tags.hpp"
12 : #include "DataStructures/Tensor/IndexType.hpp"
13 : #include "DataStructures/Tensor/Tensor.hpp"
14 : #include "DataStructures/Tensor/TypeAliases.hpp"
15 : #include "DataStructures/Variables.hpp"
16 : #include "Evolution/Systems/Cce/Tags.hpp"
17 : #include "NumericalAlgorithms/SpinWeightedSphericalHarmonics/SwshCollocation.hpp"
18 : #include "NumericalAlgorithms/SpinWeightedSphericalHarmonics/SwshDerivatives.hpp"
19 : #include "NumericalAlgorithms/SpinWeightedSphericalHarmonics/SwshInterpolation.hpp"
20 : #include "Utilities/Gsl.hpp"
21 : #include "Utilities/TMPL.hpp"
22 :
23 : namespace Cce {
24 : /// The set of tags that should be calculated before the initial data is
25 : /// computed on the first hypersurface.
26 1 : using gauge_adjustments_setup_tags =
27 : tmpl::list<Tags::BondiR, Tags::BondiJ, Tags::Dr<Tags::BondiJ>>;
28 :
29 : /*!
30 : * \brief Computes the gauge-transformed
31 : * `Tags::EvolutionGaugeBoundaryValue<Tag>` for any of the boundary tags needed
32 : * in the evolution.
33 : *
34 : * \details Most of these computations involve first interpolating via a
35 : * `Spectral::Swsh::SwshInterpolator` to the new angular grid, followed by
36 : * manipulations associated with the tensor transformation of the metric and its
37 : * derivatives. Individual template specializations contain detailed
38 : * explanations about the respective gauge transformations.
39 : */
40 : template <typename Tag>
41 1 : struct GaugeAdjustedBoundaryValue;
42 :
43 : /*!
44 : * \brief Computes the evolution gauge Bondi \f$\hat R\f$ on the worldtube from
45 : * Cauchy gauge quantities
46 : *
47 : * \details The evolution gauge Bondi \f$\hat R\f$ obeys:
48 : *
49 : * \f{align*}{
50 : * \hat R = \hat \omega R(\hat x^{\hat A}),
51 : * \f}
52 : *
53 : * where the evaluation of \f$R\f$ at \f$\hat x^{\hat A}\f$ requires an
54 : * interpolation to the evolution coordinates, and \f$\hat \omega\f$ is the
55 : * conformal factor associated with the angular part of the gauge
56 : * transformation.
57 : */
58 : template <>
59 1 : struct GaugeAdjustedBoundaryValue<Tags::BondiR> {
60 0 : using return_tags =
61 : tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>>;
62 0 : using argument_tags = tmpl::list<
63 : Tags::BoundaryValue<Tags::BondiR>, Tags::PartiallyFlatGaugeOmega,
64 : Spectral::Swsh::Tags::SwshInterpolator<Tags::CauchyAngularCoords>>;
65 :
66 0 : static void apply(
67 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>
68 : evolution_gauge_r,
69 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& cauchy_gauge_r,
70 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega,
71 : const Spectral::Swsh::SwshInterpolator& interpolator);
72 : };
73 :
74 : /*!
75 : * \brief Computes the evolution gauge \f$\partial_{\hat u} \hat R / \hat R\f$
76 : * on the worldtube.
77 : *
78 : * \details The evolution gauge quantity \f$ \partial_{\hat u} \hat R / \hat
79 : * R\f$ obeys
80 : *
81 : * \f{align*}{
82 : * \frac{\partial_{\hat u} \hat R}{ \hat R}
83 : * = \frac{\partial_u R (\hat x^{\hat A})}{R(\hat x^{\hat A})}
84 : * + \frac{\partial_{\hat u} \hat \omega}{\hat \omega}
85 : * + \frac{\mathcal U^{(0)} \bar \eth R(\hat x^{\hat A})
86 : * + \bar{\mathcal U}^{(0)} \eth R(\hat x^{\hat A}) }{2 R(\hat x^{\hat A})}
87 : * \f}
88 : *
89 : * note that the terms proportional to \f$\eth R\f$ or its conjugate arise from
90 : * the conversion between \f$\partial_u\f$ and \f$\partial_{\hat u}f\f$. The
91 : * right-hand side quantities with explicit \f$\hat x\f$ require interpolation.
92 : * \f$\mathcal U^{(0)}\f$ is the asymptotic quantity determined by
93 : * `GaugeUpdateTimeDerivatives`.
94 : */
95 : template <>
96 1 : struct GaugeAdjustedBoundaryValue<Tags::DuRDividedByR> {
97 0 : using return_tags =
98 : tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::DuRDividedByR>>;
99 0 : using argument_tags = tmpl::list<
100 : Tags::BoundaryValue<Tags::DuRDividedByR>, Tags::BondiUAtScri,
101 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>,
102 : Tags::PartiallyFlatGaugeOmega, Tags::Du<Tags::PartiallyFlatGaugeOmega>,
103 : Spectral::Swsh::Tags::SwshInterpolator<Tags::CauchyAngularCoords>,
104 : Tags::LMax>;
105 :
106 0 : static void apply(
107 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>
108 : evolution_gauge_du_r_divided_by_r,
109 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&
110 : cauchy_gauge_du_r_divided_by_r,
111 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& bondi_u_at_scri,
112 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_r,
113 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega,
114 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& du_omega,
115 : const Spectral::Swsh::SwshInterpolator& interpolator, size_t l_max);
116 : };
117 :
118 : /*!
119 : * \brief Computes the evolution gauge quantity \f$\hat J\f$ on the worldtube
120 : *
121 : * \details The evolution gauge quantity \f$\hat J\f$ obeys
122 : *
123 : * \f{align*}{
124 : * \hat J = \frac{1}{4 \hat{\omega}^2} \left( \bar{\hat d}^2 J(\hat x^{\hat A})
125 : * + \hat c^2 \bar J(\hat x^{\hat A})
126 : * + 2 \hat c \bar{\hat d} K(\hat x^{\hat A}) \right)
127 : * \f}
128 : *
129 : * Where \f$\hat c\f$ and \f$\hat d\f$ are the spin-weighted angular Jacobian
130 : * factors computed by `GaugeUpdateJacobianFromCoords`, and \f$\hat \omega\f$ is
131 : * the conformal factor associated with the angular coordinate transformation.
132 : * Note that the right-hand sides with explicit \f$\hat x^{\hat A}\f$ dependence
133 : * must be interpolated and that \f$K = \sqrt{1 + J \bar J}\f$.
134 : */
135 : template <>
136 1 : struct GaugeAdjustedBoundaryValue<Tags::BondiJ> {
137 0 : using return_tags =
138 : tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiJ>>;
139 0 : using argument_tags = tmpl::list<
140 : Tags::BoundaryValue<Tags::BondiJ>, Tags::PartiallyFlatGaugeC,
141 : Tags::PartiallyFlatGaugeD, Tags::PartiallyFlatGaugeOmega,
142 : Spectral::Swsh::Tags::SwshInterpolator<Tags::CauchyAngularCoords>>;
143 :
144 0 : static void apply(
145 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>
146 : evolution_gauge_j,
147 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& cauchy_gauge_j,
148 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& gauge_c,
149 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& gauge_d,
150 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega,
151 : const Spectral::Swsh::SwshInterpolator& interpolator);
152 : };
153 :
154 : /*!
155 : * \brief Computes the evolution gauge quantity \f$\partial_{\hat r} \hat J\f$
156 : * on the worldtube
157 : *
158 : * \details The evolution gauge quantity \f$\partial_{\hat r} \hat J\f$ is
159 : * determined from \f$\partial_{\hat r} = \frac{\partial_r}{\hat \omega}\f$ and
160 : * the expression for \f$\hat J\f$ given in the documentation for
161 : * `GaugeAdjustedBoundaryValue<Tags::BondiJ>`
162 : */
163 : template <>
164 1 : struct GaugeAdjustedBoundaryValue<Tags::Dr<Tags::BondiJ>> {
165 0 : using return_tags =
166 : tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::Dr<Tags::BondiJ>>>;
167 0 : using argument_tags = tmpl::list<
168 : Tags::BoundaryValue<Tags::Dr<Tags::BondiJ>>,
169 : Tags::BoundaryValue<Tags::BondiJ>, Tags::PartiallyFlatGaugeC,
170 : Tags::PartiallyFlatGaugeD, Tags::PartiallyFlatGaugeOmega,
171 : Spectral::Swsh::Tags::SwshInterpolator<Tags::CauchyAngularCoords>,
172 : Tags::LMax>;
173 :
174 0 : static void apply(
175 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>
176 : evolution_gauge_dr_j,
177 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& cauchy_gauge_dr_j,
178 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& cauchy_gauge_j,
179 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& gauge_c,
180 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& gauge_d,
181 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega,
182 : const Spectral::Swsh::SwshInterpolator& interpolator, size_t l_max);
183 : };
184 :
185 : /*!
186 : * \brief Computes the evolution gauge quantity \f$\hat \beta\f$ on the
187 : * worldtube
188 : *
189 : * \details The evolution gauge quantity \f$\hat \beta\f$ obeys
190 : *
191 : * \f{align*}{
192 : * e^{2 \hat \beta} = e^{2 \beta(\hat x^{\hat A})} / \hat \omega.
193 : * \f}
194 : *
195 : * The explicit evaluation at \f$\hat x^{\hat A}\f$ on the right-hand side
196 : * indicates the requirement of an interpolation step, and \f$\hat \omega\f$ is
197 : * the conformal factor associated with the angular transformation.
198 : */
199 : template <>
200 1 : struct GaugeAdjustedBoundaryValue<Tags::BondiBeta> {
201 0 : using return_tags =
202 : tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiBeta>>;
203 0 : using argument_tags = tmpl::list<
204 : Tags::BoundaryValue<Tags::BondiBeta>, Tags::PartiallyFlatGaugeOmega,
205 : Spectral::Swsh::Tags::SwshInterpolator<Tags::CauchyAngularCoords>>;
206 :
207 0 : static void apply(
208 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>
209 : evolution_gauge_beta,
210 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& cauchy_gauge_beta,
211 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega,
212 : const Spectral::Swsh::SwshInterpolator& interpolator);
213 : };
214 :
215 : /*!
216 : * \brief Computes the evolution gauge quantity \f$\hat Q\f$ on the worldtube.
217 : *
218 : * \details The evolution gauge quantity \f$\hat Q\f$ obeys
219 : *
220 : * \f{align*}{
221 : * \hat Q =& \hat r^2 e^{-2 \hat \beta} (\hat K \partial_{\hat r} \hat U
222 : * + \hat J \partial_{\hat r} \hat{\bar U}),\\
223 : * \partial_{\hat r} \hat U
224 : * =& \frac{1}{2 \hat \omega^3}\left(\hat{\bar d} \partial_r U(\hat x^{\hat A})
225 : * - \hat c \partial_r \bar U(\hat x^{\hat A})\right)
226 : * + \frac{e^{2\hat \beta}}{\hat r^2 \hat \omega}
227 : * \left(\hat J \hat{\bar{\eth}} \hat \omega
228 : * - \hat K \hat \eth \hat \omega\right)
229 : * \left(-1 + \partial_{\hat y} \hat{\bar{J}} \partial_{\hat y} \hat J
230 : * - \left[\frac{\partial_{\hat y}(\hat J \hat{\bar{J}})}
231 : * {2 \hat K}\right]^2\right) \notag \\
232 : * & + 2 \frac{e^{2 \hat \beta}}{\hat \omega \hat r^2}
233 : * \left[ \hat{\bar{\eth}} \hat \omega \partial_{\hat y} \hat J
234 : * + \hat{\eth} \hat \omega \left(-\frac{\hat J \partial_{\hat y}
235 : * \hat{\bar J}
236 : * + \hat{\bar J} \partial_{\hat y} \hat J}{2 \hat K}\right) \right].
237 : * \f}
238 : *
239 : * where the explicit argument \f$\hat x^{\hat A}\f$ on the right-hand side
240 : * implies the need for an interpolation operation, and
241 : * \f$K = \sqrt{1 + J \bar J}\f$.
242 : */
243 : template <>
244 1 : struct GaugeAdjustedBoundaryValue<Tags::BondiQ> {
245 0 : using return_tags =
246 : tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiQ>>;
247 :
248 0 : using argument_tags = tmpl::list<
249 : Tags::BoundaryValue<Tags::Dr<Tags::BondiU>>, Tags::BondiJ,
250 : Tags::Dy<Tags::BondiJ>, Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>,
251 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiBeta>,
252 : Tags::PartiallyFlatGaugeC, Tags::PartiallyFlatGaugeD,
253 : Tags::PartiallyFlatGaugeOmega,
254 : Spectral::Swsh::Tags::Derivative<Tags::PartiallyFlatGaugeOmega,
255 : Spectral::Swsh::Tags::Eth>,
256 : Spectral::Swsh::Tags::SwshInterpolator<Tags::CauchyAngularCoords>,
257 : Tags::LMax>;
258 :
259 0 : static void apply(
260 : const gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*>
261 : evolution_gauge_q,
262 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& cauchy_gauge_dr_u,
263 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& volume_j,
264 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& volume_dy_j,
265 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_r,
266 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_beta,
267 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& gauge_c,
268 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& gauge_d,
269 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega,
270 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
271 : const Spectral::Swsh::SwshInterpolator& interpolator,
272 : const size_t l_max) {
273 : apply_impl(make_not_null(&get(*evolution_gauge_q)), get(cauchy_gauge_dr_u),
274 : get(volume_j), get(volume_dy_j), get(evolution_gauge_r),
275 : get(evolution_gauge_beta), get(gauge_c), get(gauge_d),
276 : get(omega), get(eth_omega), interpolator, l_max);
277 : }
278 :
279 : private:
280 0 : static void apply_impl(
281 : gsl::not_null<SpinWeighted<ComplexDataVector, 1>*> evolution_gauge_q,
282 : const SpinWeighted<ComplexDataVector, 1>& cauchy_gauge_dr_u,
283 : const SpinWeighted<ComplexDataVector, 2>& volume_j,
284 : const SpinWeighted<ComplexDataVector, 2>& volume_dy_j,
285 : const SpinWeighted<ComplexDataVector, 0>& evolution_gauge_r,
286 : const SpinWeighted<ComplexDataVector, 0>& evolution_gauge_beta,
287 : const SpinWeighted<ComplexDataVector, 2>& gauge_c,
288 : const SpinWeighted<ComplexDataVector, 0>& gauge_d,
289 : const SpinWeighted<ComplexDataVector, 0>& omega,
290 : const SpinWeighted<ComplexDataVector, 1>& eth_omega,
291 : const Spectral::Swsh::SwshInterpolator& interpolator, size_t l_max);
292 : };
293 :
294 : /*!
295 : * \brief Computes the evolution gauge quantity \f$\mathcal U\f$ on the
296 : * worldtube.
297 : *
298 : * \details Note that the boundary quantity computed by this function is, by
299 : * necessity, NOT the evolution gauge bondi \f$\hat U\f$, because there is
300 : * insufficient information at the point in the computation this will be
301 : * evaluated to completely determine \f$\hat{U}\f$. Instead, this determines
302 : * the boundary value of \f$\mathcal U\f$, which satisfies,
303 : *
304 : * \f{align*}{
305 : * \mathcal{U} - \mathcal{U}^{(0)} = \hat U,
306 : * \f}
307 : *
308 : * where the superscript \f$(0)\f$ denotes evaluation at \f$\mathcal I^+\f$. In
309 : * particular, the result of this computation may be used with the same
310 : * hypersurface equations as the full evolution gauge \f$\hat U\f$, because they
311 : * satisfy the same radial differential equation.
312 : *
313 : * \f$\mathcal U\f$ is computed by,
314 : *
315 : * \f{align*}{
316 : * \mathcal U = \frac{1}{2\hat \omega^2} \left(\hat{\bar d} U(\hat x^{\hat A})
317 : * - \hat c \bar U(\hat x^{\hat A}) \right)
318 : * - \frac{e^{2 \hat \beta}}{\hat r \hat \omega}
319 : * \left(\hat K \hat \eth \hat \omega
320 : * - \hat J\hat{\bar{\eth}} \hat \omega\right),
321 : * \f}
322 : *
323 : * where the explicit argument \f$\hat x^{\hat A}\f$ on the right-hand side
324 : * implies the need for an interpolation operation, and
325 : * \f$K = \sqrt{1 + J \bar J}\f$.
326 : */
327 : template <>
328 1 : struct GaugeAdjustedBoundaryValue<Tags::BondiU> {
329 0 : using return_tags =
330 : tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiU>>;
331 0 : using argument_tags = tmpl::list<
332 : Tags::BoundaryValue<Tags::BondiU>, Tags::BondiJ,
333 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>,
334 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiBeta>,
335 : Tags::PartiallyFlatGaugeC, Tags::PartiallyFlatGaugeD,
336 : Tags::PartiallyFlatGaugeOmega,
337 : Spectral::Swsh::Tags::Derivative<Tags::PartiallyFlatGaugeOmega,
338 : Spectral::Swsh::Tags::Eth>,
339 : Spectral::Swsh::Tags::SwshInterpolator<Tags::CauchyAngularCoords>,
340 : Tags::LMax>;
341 :
342 0 : static void apply(
343 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*>
344 : evolution_gauge_u,
345 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& cauchy_gauge_u,
346 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& volume_j,
347 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_r,
348 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_beta,
349 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& gauge_c,
350 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& gauge_d,
351 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega,
352 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
353 : const Spectral::Swsh::SwshInterpolator& interpolator, size_t l_max);
354 : };
355 :
356 : /*!
357 : * \brief Computes the evolution gauge quantity \f$\hat W\f$ on the worldtube.
358 : *
359 : * \details The evolution gauge value \f$\hat W\f$ obeys
360 : *
361 : * \f{align*}{
362 : * \hat W =& W(\hat x^{\hat A}) + (\hat \omega - 1) / \hat r
363 : * + \frac{e^{2 \hat \beta}}{2 \hat \omega^2 \hat r}
364 : * \left(\hat J \left(\hat{\bar \eth} \hat \omega\right)^2
365 : * + \hat{\bar{J}} \left(\hat \eth \hat \omega\right) ^2
366 : * - 2 K \left( \hat \eth \hat \omega\right) \left(\hat{\bar \eth} \hat
367 : * \omega\right) \right)
368 : * - \frac{2 \partial_{u} \hat \omega}{\hat \omega}
369 : * - \frac{ \hat U \bar \eth \hat \omega + \hat{\bar U} \eth \hat \omega }
370 : * {\hat \omega},
371 : * \f}
372 : *
373 : * where the explicit argument \f$\hat x^{\hat A}\f$ on the right-hand side
374 : * implies the need for an interpolation operation and
375 : * \f$K = \sqrt{1 + J \bar J}\f$.
376 : */
377 : template <>
378 1 : struct GaugeAdjustedBoundaryValue<Tags::BondiW> {
379 0 : using return_tags =
380 : tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiW>>;
381 0 : using argument_tags = tmpl::list<
382 : Tags::BoundaryValue<Tags::BondiW>, Tags::BondiJ,
383 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiU>,
384 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiBeta>, Tags::BondiUAtScri,
385 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>,
386 : Tags::PartiallyFlatGaugeOmega, Tags::Du<Tags::PartiallyFlatGaugeOmega>,
387 : Spectral::Swsh::Tags::Derivative<Tags::PartiallyFlatGaugeOmega,
388 : Spectral::Swsh::Tags::Eth>,
389 : Spectral::Swsh::Tags::SwshInterpolator<Tags::CauchyAngularCoords>,
390 : Tags::LMax>;
391 :
392 0 : static void apply(
393 : const gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>
394 : evolution_gauge_w,
395 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& cauchy_gauge_w,
396 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& volume_j,
397 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& evolution_gauge_u,
398 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_beta,
399 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&
400 : evolution_gauge_u_at_scri,
401 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_r,
402 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega,
403 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& du_omega,
404 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
405 : const Spectral::Swsh::SwshInterpolator& interpolator,
406 : const size_t l_max) {
407 : apply_impl(make_not_null(&get(*evolution_gauge_w)), get(cauchy_gauge_w),
408 : get(volume_j), get(evolution_gauge_u), get(evolution_gauge_beta),
409 : get(evolution_gauge_u_at_scri), get(evolution_gauge_r),
410 : get(omega), get(du_omega), get(eth_omega), interpolator, l_max);
411 : }
412 :
413 : private:
414 0 : static void apply_impl(
415 : gsl::not_null<SpinWeighted<ComplexDataVector, 0>*> evolution_gauge_w,
416 : const SpinWeighted<ComplexDataVector, 0>& cauchy_gauge_w,
417 : const SpinWeighted<ComplexDataVector, 2>& volume_j,
418 : const SpinWeighted<ComplexDataVector, 1>& evolution_gauge_u,
419 : const SpinWeighted<ComplexDataVector, 0>& evolution_gauge_beta,
420 : const SpinWeighted<ComplexDataVector, 1>& evolution_gauge_u_at_scri,
421 : const SpinWeighted<ComplexDataVector, 0>& evolution_gauge_r,
422 : const SpinWeighted<ComplexDataVector, 0>& omega,
423 : const SpinWeighted<ComplexDataVector, 0>& du_omega,
424 : const SpinWeighted<ComplexDataVector, 1>& eth_omega,
425 : const Spectral::Swsh::SwshInterpolator& interpolator, size_t l_max);
426 : };
427 :
428 : /*!
429 : * \brief Computes the evolution gauge quantity \f$\hat H\f$ on the worldtube.
430 : *
431 : * \details The evolution gauge \f$\hat H\f$ obeys
432 : *
433 : * \f{align*}{
434 : * \hat H =&
435 : * \frac{1}{2} \left(\mathcal{U}^{(0)} \hat{\bar \eth} \hat J
436 : * + \bar{\mathcal{U}}^{(0)} \hat{\eth} \hat J\right)
437 : * + \frac{\partial_{\hat u} \hat \omega
438 : * - \tfrac{1}{2} \left(\mathcal{U}^{(0)} \bar{\hat \eth}\hat \omega
439 : * + \bar{\mathcal{U}}^{(0)} \hat \eth \hat \omega \right) }{\hat \omega}
440 : * \left(2 \hat J - 2 \partial_{\hat y} \hat J\right)
441 : * - \hat J\hat{\bar \eth} \mathcal{U}^{(0)}
442 : * + \hat K \hat \eth \bar{\mathcal{U}}^{(0)} \notag\\
443 : * &+ \frac{1}{4 \hat \omega^2} \left(\hat{\bar d}^2 H(\hat x^{\hat A})
444 : * + \hat c^2 \bar H(\hat x^{\hat A})
445 : * + \hat{\bar d} \hat c \frac{H(\hat x^{\hat A}) \bar J(\hat x^{\hat A})
446 : * + J(\hat x^{\hat A}) \bar H(\hat x^{\hat A})}{K}\right)
447 : * + 2 \frac{\partial_u R}{R} \partial_{\hat y} J
448 : * \f}
449 : *
450 : * where the superscript \f$(0)\f$ denotes evaluation at \f$\mathcal I^+\f$ and
451 : * the explicit \f$\hat x^{\hat A}\f$ arguments on the right-hand side imply
452 : * interpolation operations, and \f$K = \sqrt{1 + J \bar J}\f$,
453 : * \f$\hat K = \sqrt{1 + \hat J \hat{\bar J}}\f$.
454 : *
455 : * The interpolated source-gauge angular metric is
456 : *
457 : * \f{align*}{
458 : * J(\hat x^{\hat A}) &=
459 : * \frac{\hat d^2\hat J+\hat c^2\hat{\bar J}
460 : * -2\hat c\hat d\hat K}{4\hat\omega^2}, &
461 : * K(\hat x^{\hat A}) &=
462 : * \sqrt{1+J(\hat x^{\hat A})\bar J(\hat x^{\hat A})}.
463 : * \f}
464 : *
465 : * These expressions follow by inverting Eqs. (32) and (33b) of
466 : * \cite Moxon2020gha.
467 : */
468 : template <>
469 1 : struct GaugeAdjustedBoundaryValue<Tags::BondiH> {
470 0 : using return_tags =
471 : tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiH>>;
472 0 : using argument_tags = tmpl::list<
473 : Tags::BondiJ, Tags::BoundaryValue<Tags::Du<Tags::BondiJ>>,
474 : Tags::Dy<Tags::BondiJ>, Tags::BondiUAtScri,
475 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>,
476 : Tags::PartiallyFlatGaugeC, Tags::PartiallyFlatGaugeD,
477 : Tags::PartiallyFlatGaugeOmega, Tags::Du<Tags::PartiallyFlatGaugeOmega>,
478 : Spectral::Swsh::Tags::Derivative<Tags::PartiallyFlatGaugeOmega,
479 : Spectral::Swsh::Tags::Eth>,
480 : Tags::EvolutionGaugeBoundaryValue<Tags::DuRDividedByR>,
481 : Spectral::Swsh::Tags::SwshInterpolator<Tags::CauchyAngularCoords>,
482 : Tags::LMax>;
483 :
484 0 : static void apply(
485 : const gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>
486 : evolution_gauge_h,
487 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& volume_j,
488 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& cauchy_gauge_du_j,
489 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& volume_dy_j,
490 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&
491 : evolution_gauge_u_at_scri,
492 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_r,
493 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& gauge_c,
494 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& gauge_d,
495 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega,
496 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& du_omega,
497 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
498 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&
499 : evolution_gauge_du_r_divided_by_r,
500 : const Spectral::Swsh::SwshInterpolator& interpolator,
501 : const size_t l_max) {
502 : apply_impl(make_not_null(&get(*evolution_gauge_h)), get(volume_j),
503 : get(cauchy_gauge_du_j), get(volume_dy_j),
504 : get(evolution_gauge_u_at_scri), get(evolution_gauge_r),
505 : get(gauge_c), get(gauge_d), get(omega), get(du_omega),
506 : get(eth_omega), get(evolution_gauge_du_r_divided_by_r),
507 : interpolator, l_max);
508 : }
509 :
510 : private:
511 0 : static void apply_impl(
512 : gsl::not_null<SpinWeighted<ComplexDataVector, 2>*> evolution_gauge_h,
513 : const SpinWeighted<ComplexDataVector, 2>& volume_j,
514 : const SpinWeighted<ComplexDataVector, 2>& cauchy_gauge_du_j,
515 : const SpinWeighted<ComplexDataVector, 2>& volume_dy_j,
516 : const SpinWeighted<ComplexDataVector, 1>& evolution_gauge_u_at_scri,
517 : const SpinWeighted<ComplexDataVector, 0>& evolution_gauge_r,
518 : const SpinWeighted<ComplexDataVector, 2>& gauge_c,
519 : const SpinWeighted<ComplexDataVector, 0>& gauge_d,
520 : const SpinWeighted<ComplexDataVector, 0>& omega,
521 : const SpinWeighted<ComplexDataVector, 0>& du_omega,
522 : const SpinWeighted<ComplexDataVector, 1>& eth_omega,
523 : const SpinWeighted<ComplexDataVector, 0>&
524 : evolution_gauge_du_r_divided_by_r,
525 : const Spectral::Swsh::SwshInterpolator& interpolator, size_t l_max);
526 : };
527 :
528 : /*!
529 : * \brief Computes the evolution gauge quantity \f$\hat \Pi\f$ for the scalar
530 : * field on the worldtube.
531 : *
532 : * \details The evolution gauge \f$\hat \Pi\f$ obeys
533 : * \f{align*}{
534 : * \hat \Pi = \partial_{t^\prime} \psi + \Re
535 : * \left(\mathcal{U}^{(0)}\bar{\eth}\psi\right)
536 : * \f}
537 : *
538 : * where \f$\partial_{t^\prime} \psi\f$ comes from the Cauchy evolution.
539 : */
540 : template <>
541 1 : struct GaugeAdjustedBoundaryValue<Tags::KleinGordonPi> {
542 0 : using return_tags =
543 : tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::KleinGordonPi>>;
544 0 : using argument_tags = tmpl::list<
545 : Tags::BoundaryValue<Tags::KleinGordonPi>, Tags::BondiUAtScri,
546 : Spectral::Swsh::Tags::SwshInterpolator<Tags::CauchyAngularCoords>,
547 : Tags::LMax, Tags::KleinGordonPsi>;
548 :
549 0 : static void apply(
550 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>
551 : evolution_kg_pi,
552 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& cauchy_kg_pi,
553 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&
554 : evolution_gauge_u_at_scri,
555 : const Spectral::Swsh::SwshInterpolator& interpolator, size_t l_max,
556 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& volume_psi);
557 : };
558 :
559 : /*!
560 : * \brief Update the Cauchy gauge cartesian coordinate derivative \f$\partial_u
561 : * x(\hat x)\f$, as well as remaining gauge quantities \f$\mathcal U^{(0)}\f$,
562 : * \f$\hat U \equiv \mathcal U - \mathcal U^{(0)}\f$, and \f$\partial_{\hat u}
563 : * \hat \omega\f$ to maintain asymptotically inertial angular coordinates.
564 : *
565 : * \details The constraint we must satisfy to maintain the asymptotically
566 : * inertial angular coordinates is
567 : *
568 : * \f{align*}{
569 : * \partial_{\hat u} x^A = \mathcal U^{(0) \hat A} \partial_{\hat A} x^{A},
570 : * \f}
571 : *
572 : * which we compute for a representative Cartesian coordinate set on the unit
573 : * sphere, to maintain representability and ensure that angular transform and
574 : * derivative operations keep the desired precision. The equation we use for the
575 : * Cartesian analog is:
576 : *
577 : * \f{align*}{
578 : * \partial_{\hat u} x^i &= \frac{1}{2} (\bar{\mathcal U}^{(0)} \hat \eth x^i +
579 : * \mathcal U^{(0)} \hat{\bar \eth} x^i ) \\
580 : * &= \text{Re}(\bar{\mathcal U}^{(0)} \hat \eth x^i)
581 : * \f}
582 : *
583 : * This computation completes the unfixed degrees of freedom for the coordinate
584 : * transformation at the boundary, so also computes the gauge quantities that
585 : * rely on this information \f$\mathcal U^{(0)}\f$,
586 : * \f$\hat U\f$, and \f$\partial_{\hat u} \hat \omega\f$.
587 : *
588 : * The time derivative of \f$\hat \omega\f$ is calculated from the equation
589 : * \f{align*}{
590 : * \partial_{\hat u} \hat \omega
591 : * = \frac{\hat \omega}{4} (\hat{\bar \eth} \mathcal U^{(0)}
592 : * + \hat \eth \bar{\mathcal U}^{(0)})
593 : * + \frac{1}{2} (\mathcal U^{(0)} \hat{\bar \eth} \hat \omega
594 : * + \bar{\mathcal U}^{(0)} \hat \eth \hat \omega)
595 : * \f}
596 : * \warning Before this update call the quantity stored in the tag
597 : * `Cce::Tags::BondiU` represents \f$\mathcal U\f$, and after this update call,
598 : * it represents \f$\hat U\f$ (the true evolution gauge quantity).
599 : */
600 1 : struct GaugeUpdateTimeDerivatives {
601 0 : using return_tags =
602 : tmpl::list<::Tags::dt<Tags::CauchyCartesianCoords>, Tags::BondiUAtScri,
603 : Tags::BondiU, Tags::Du<Tags::PartiallyFlatGaugeOmega>>;
604 0 : using argument_tags =
605 : tmpl::list<Tags::CauchyCartesianCoords, Tags::PartiallyFlatGaugeOmega,
606 : Spectral::Swsh::Tags::Derivative<Tags::PartiallyFlatGaugeOmega,
607 : Spectral::Swsh::Tags::Eth>,
608 : Tags::LMax>;
609 :
610 0 : static void apply(
611 : gsl::not_null<tnsr::i<DataVector, 3>*> cartesian_cauchy_du_x,
612 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*>
613 : evolution_gauge_u_at_scri,
614 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*> volume_u,
615 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> du_omega,
616 : const tnsr::i<DataVector, 3>& cartesian_cauchy_coordinates,
617 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega,
618 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
619 : size_t l_max);
620 : };
621 :
622 : /*!
623 : * \brief Update the inertial gauge cartesian coordinate derivative
624 : * \f$\partial_u \hat x(x)\f$.
625 : *
626 : * \details For the asymptotically inertial angular coordinates
627 : * \f$\hat{x}^{\hat{A}}\f$, we have:
628 : *
629 : * \f{align*}{
630 : * \partial_u \hat{x}^{\hat{A}} = -U^{(0)B}\partial_B \hat{x}^{\hat{A}}
631 : * \f}
632 : *
633 : * and the Cartesian version reads
634 : *
635 : * \f{align*}{
636 : * \partial_u \hat{x}^{\hat{i}}= - \text{Re}(\bar{U}^{(0)}
637 : * \eth \hat{x}^{\hat{i}})
638 : * \f}
639 : *
640 : * Note that \f$U^{0}\f$ and \f$\mathcal U^{(0)}\f$ are related by
641 : *
642 : * \f{align*}{
643 : * U^{(0)} &= \frac{1}{2\omega^2} \left( \bar{d} \mathcal U^{(0)} -
644 : * c \bar{\mathcal U}^{(0)} \right) \\
645 : * &= \frac{\hat \omega^2}{2} \left( \bar{d} \mathcal U^{(0)} -
646 : * c \bar{\mathcal U}^{(0)} \right)
647 : * \f}
648 : *
649 : * see Eq. (79) of \cite Moxon2020gha.
650 : */
651 1 : struct GaugeUpdateInertialTimeDerivatives {
652 0 : using return_tags = tmpl::list<::Tags::dt<Tags::PartiallyFlatCartesianCoords>,
653 : Tags::BondiUAtScri>;
654 0 : using argument_tags = tmpl::list<
655 : Tags::PartiallyFlatCartesianCoords, Tags::CauchyGaugeC,
656 : Tags::PartiallyFlatGaugeOmega, Tags::CauchyGaugeD, Tags::LMax,
657 : Spectral::Swsh::Tags::SwshInterpolator<Tags::PartiallyFlatAngularCoords>>;
658 0 : static void apply(
659 : gsl::not_null<tnsr::i<DataVector, 3>*> cartesian_inertial_du_x,
660 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*>
661 : evolution_gauge_u_at_scri,
662 : const tnsr::i<DataVector, 3>& cartesian_inertial_coordinates,
663 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& gauge_cauchy_c,
664 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega,
665 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& gauge_cauchy_d,
666 : size_t l_max, const Spectral::Swsh::SwshInterpolator& interpolator);
667 : };
668 :
669 : /*!
670 : * \brief Update the angular coordinates stored in `AngularTag` via
671 : * trigonometric operations applied to the Cartesian coordinates stored in
672 : * `CartesianTag`.
673 : *
674 : * \details This function also normalizes the Cartesian coordinates stored in
675 : * `CartesianTag`, which is the desired behavior for the CCE boundary
676 : * computation.
677 : */
678 : template <typename AngularTag, typename CartesianTag>
679 1 : struct GaugeUpdateAngularFromCartesian {
680 0 : using argument_tags = tmpl::list<>;
681 0 : using return_tags = tmpl::list<AngularTag, CartesianTag>;
682 :
683 0 : static void apply(
684 : const gsl::not_null<
685 : tnsr::i<DataVector, 2, ::Frame::Spherical<::Frame::Inertial>>*>
686 : angular_coordinates,
687 : const gsl::not_null<tnsr::i<DataVector, 3>*> cartesian_coordinates) {
688 : // normalize the cartesian coordinates
689 : const DataVector one_over_cartesian_r =
690 : 1.0 / sqrt(square(get<0>(*cartesian_coordinates)) +
691 : square(get<1>(*cartesian_coordinates)) +
692 : square(get<2>(*cartesian_coordinates)));
693 :
694 : get<0>(*cartesian_coordinates) *= one_over_cartesian_r;
695 : get<1>(*cartesian_coordinates) *= one_over_cartesian_r;
696 : get<2>(*cartesian_coordinates) *= one_over_cartesian_r;
697 :
698 : const auto& x = get<0>(*cartesian_coordinates);
699 : const auto& y = get<1>(*cartesian_coordinates);
700 : const auto& z = get<2>(*cartesian_coordinates);
701 :
702 : get<0>(*angular_coordinates) = atan2(sqrt(square(x) + square(y)), z);
703 : get<1>(*angular_coordinates) = atan2(y, x);
704 : }
705 : };
706 :
707 : namespace detail {
708 : void gauge_update_jacobian_from_coordinates_apply_impl(
709 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>
710 : gauge_factor_spin_2,
711 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>
712 : gauge_factor_spin_0,
713 : const tnsr::i<DataVector, 2, ::Frame::Spherical<::Frame::Inertial>>&
714 : angular_source_coordinates,
715 : const tnsr::i<DataVector, 3>& cartesian_source_coordinates, size_t l_max);
716 : } // namespace detail
717 :
718 : /*!
719 : * \brief From the angular coordinates `AngularCoordinateTag` and the Cartesian
720 : * coordinates `CartesianCoordinateTag`, determine the spin-weighted Jacobian
721 : * factors `GaugeFactorSpin2` and `GaugeFactorSpin0`.
722 : *
723 : * \details This is most often used in the context of generating the Jacobians
724 : * in the evolution-gauge coordinates from the Cauchy collocation points as a
725 : * function of the evolution gauge coordinates. In this concrete case, the
726 : * `GaugeFactorSpin2` is the gauge factor \f$\hat c\f$ and takes the value
727 : *
728 : * \f{align*}{
729 : * \hat c = \hat q^{\hat A} \partial_{\hat A}(x^A) q_A,
730 : * \f}
731 : *
732 : * and the `GaugeFactorSpin0` is the gauge factor \f$\hat d\f$ and takes the
733 : * value
734 : *
735 : * \f{align*}{
736 : * \hat d = \hat{\bar q}^{\hat A} \partial_{\hat A}(x^A) q_A.
737 : * \f}
738 : *
739 : * The more generic template construction is employed so that the spin-weighted
740 : * Jacobians can also be computed between two arbitrary gauges, including the
741 : * inverse Jacobians associated with moving from the evolution gauge to the
742 : * Cauchy gauge.
743 : */
744 : template <typename GaugeFactorSpin2, typename GaugeFactorSpin0,
745 : typename AngularCoordinateTag, typename CartesianCoordinateTag>
746 1 : struct GaugeUpdateJacobianFromCoordinates {
747 0 : using return_tags = tmpl::list<GaugeFactorSpin2, GaugeFactorSpin0>;
748 0 : using argument_tags =
749 : tmpl::list<AngularCoordinateTag, CartesianCoordinateTag, Tags::LMax>;
750 :
751 0 : static void apply(
752 : const gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>
753 : gauge_factor_spin_2,
754 : const gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>
755 : gauge_factor_spin_0,
756 : const tnsr::i<DataVector, 2, ::Frame::Spherical<::Frame::Inertial>>&
757 : angular_source_coordinates,
758 : const tnsr::i<DataVector, 3>& cartesian_source_coordinates,
759 : const size_t l_max) {
760 : detail::gauge_update_jacobian_from_coordinates_apply_impl(
761 : gauge_factor_spin_2, gauge_factor_spin_0, angular_source_coordinates,
762 : cartesian_source_coordinates, l_max);
763 : }
764 : };
765 :
766 : /*!
767 : * \brief Update the interpolator stored in
768 : * `Spectral::Swsh::Tags::SwshInterpolator<AngularCoordinates>`.
769 : *
770 : * \details Note that the `AngularCoordinates` associated with the interpolator
771 : * should be the source coordinates. For instance, when interpolating a quantity
772 : * defined on the Cauchy gauge collocation points to the evolution gauge
773 : * collocation points, the interpolator input should be the Cauchy coordinates
774 : * points as a function of the evolution gauge coordinates (at the evolution
775 : * gauge collocation points).
776 : */
777 : template <typename AngularCoordinates>
778 1 : struct GaugeUpdateInterpolator {
779 0 : using return_tags =
780 : tmpl::list<Spectral::Swsh::Tags::SwshInterpolator<AngularCoordinates>>;
781 0 : using argument_tags = tmpl::list<AngularCoordinates, Tags::LMax>;
782 :
783 0 : static void apply(
784 : const gsl::not_null<Spectral::Swsh::SwshInterpolator*> interpolator,
785 : const tnsr::i<DataVector, 2, ::Frame::Spherical<::Frame::Inertial>>&
786 : angular_coordinates,
787 : const size_t l_max) {
788 : // throw away the old interpolator and generate a new one for the current
789 : // grid points.
790 : *interpolator = Spectral::Swsh::SwshInterpolator(
791 : get<0>(angular_coordinates), get<1>(angular_coordinates), l_max);
792 : }
793 : };
794 :
795 : /*!
796 : * \brief Update the quantity \f$\hat \omega\f$ and \f$\hat \eth \hat \omega\f$
797 : * for updated spin-weighted Jacobian quantities \f$\hat c\f$ and \f$\hat d\f$.
798 : *
799 : * \details The conformal factor \f$\hat \omega\f$ can be determined by the
800 : * angular determinant from the spin-weighted Jacobian factors as
801 : *
802 : * \f{align*}{
803 : * \hat \omega = \frac{1}{2} \sqrt{\hat d \hat{\bar d} - \hat c \hat{\bar c}}.
804 : * \f}
805 : */
806 : template <typename GaugeC, typename GaugeD, typename GaugeOmega>
807 1 : struct GaugeUpdateOmega {
808 0 : using argument_tags = tmpl::list<GaugeC, GaugeD, Tags::LMax>;
809 0 : using return_tags = tmpl::list<
810 : GaugeOmega,
811 : Spectral::Swsh::Tags::Derivative<GaugeOmega, Spectral::Swsh::Tags::Eth>>;
812 :
813 0 : static void apply(
814 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> omega,
815 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*> eth_omega,
816 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& gauge_c,
817 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& gauge_d, size_t l_max);
818 : };
819 :
820 : /*!
821 : * \brief Initialize to default values (identity transform) all of the angular
822 : * gauge quantities for the boundary gauge transforms.
823 : *
824 : * \details The updated quantities are the Cauchy angular and Cartesian
825 : * coordinates, as well as the spin-weighted gauge factors and the conformal
826 : * factor. All quantities are initialized to the appropriate value for the
827 : * identity transform of angular coordinates. Using this initialization function
828 : * ensures that the evolution gauge and the Cauchy gauge angular coordinates
829 : * agree on the first evaluated time.
830 : * - `CauchyAngularCoords` are set to the angular collocation values for the
831 : * spin-weighted spherical harmonic library
832 : * - `CauchyCartesianCoords` are set to the Cartesian coordinates for the
833 : * `CauchyAngularCoords` evaluated on a unit sphere.
834 : * - `GaugeC` is set to 0
835 : * - `GaugeD` is set to 2
836 : * - `GaugeOmega` is set to 1
837 : */
838 1 : struct InitializeGauge {
839 0 : using return_tags =
840 : tmpl::list<Tags::CauchyAngularCoords, Tags::CauchyCartesianCoords,
841 : Tags::PartiallyFlatGaugeC, Tags::PartiallyFlatGaugeD,
842 : Tags::PartiallyFlatGaugeOmega>;
843 0 : using argument_tags = tmpl::list<Tags::LMax>;
844 :
845 0 : static void apply(
846 : gsl::not_null<
847 : tnsr::i<DataVector, 2, ::Frame::Spherical<::Frame::Inertial>>*>
848 : angular_cauchy_coordinates,
849 : gsl::not_null<tnsr::i<DataVector, 3>*> cartesian_cauchy_coordinates,
850 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*> gauge_c,
851 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> gauge_d,
852 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> omega,
853 : size_t l_max);
854 : };
855 : } // namespace Cce
|