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