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 : template <>
456 1 : struct GaugeAdjustedBoundaryValue<Tags::BondiH> {
457 0 : using return_tags =
458 : tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::BondiH>>;
459 0 : using argument_tags = tmpl::list<
460 : Tags::BondiJ, Tags::BoundaryValue<Tags::Du<Tags::BondiJ>>,
461 : Tags::Dy<Tags::BondiJ>, Tags::BondiUAtScri,
462 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>,
463 : Tags::PartiallyFlatGaugeC, Tags::PartiallyFlatGaugeD,
464 : Tags::PartiallyFlatGaugeOmega, Tags::Du<Tags::PartiallyFlatGaugeOmega>,
465 : Spectral::Swsh::Tags::Derivative<Tags::PartiallyFlatGaugeOmega,
466 : Spectral::Swsh::Tags::Eth>,
467 : Tags::EvolutionGaugeBoundaryValue<Tags::DuRDividedByR>,
468 : Spectral::Swsh::Tags::SwshInterpolator<Tags::CauchyAngularCoords>,
469 : Tags::LMax>;
470 :
471 0 : static void apply(
472 : const gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>
473 : evolution_gauge_h,
474 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& volume_j,
475 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& cauchy_gauge_du_j,
476 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& volume_dy_j,
477 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&
478 : evolution_gauge_u_at_scri,
479 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& evolution_gauge_r,
480 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& gauge_c,
481 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& gauge_d,
482 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega,
483 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& du_omega,
484 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
485 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&
486 : evolution_gauge_du_r_divided_by_r,
487 : const Spectral::Swsh::SwshInterpolator& interpolator,
488 : const size_t l_max) {
489 : apply_impl(make_not_null(&get(*evolution_gauge_h)), get(volume_j),
490 : get(cauchy_gauge_du_j), get(volume_dy_j),
491 : get(evolution_gauge_u_at_scri), get(evolution_gauge_r),
492 : get(gauge_c), get(gauge_d), get(omega), get(du_omega),
493 : get(eth_omega), get(evolution_gauge_du_r_divided_by_r),
494 : interpolator, l_max);
495 : }
496 :
497 : private:
498 0 : static void apply_impl(
499 : gsl::not_null<SpinWeighted<ComplexDataVector, 2>*> evolution_gauge_h,
500 : const SpinWeighted<ComplexDataVector, 2>& volume_j,
501 : const SpinWeighted<ComplexDataVector, 2>& cauchy_gauge_du_j,
502 : const SpinWeighted<ComplexDataVector, 2>& volume_dy_j,
503 : const SpinWeighted<ComplexDataVector, 1>& evolution_gauge_u_at_scri,
504 : const SpinWeighted<ComplexDataVector, 0>& evolution_gauge_r,
505 : const SpinWeighted<ComplexDataVector, 2>& gauge_c,
506 : const SpinWeighted<ComplexDataVector, 0>& gauge_d,
507 : const SpinWeighted<ComplexDataVector, 0>& omega,
508 : const SpinWeighted<ComplexDataVector, 0>& du_omega,
509 : const SpinWeighted<ComplexDataVector, 1>& eth_omega,
510 : const SpinWeighted<ComplexDataVector, 0>&
511 : evolution_gauge_du_r_divided_by_r,
512 : const Spectral::Swsh::SwshInterpolator& interpolator, size_t l_max);
513 : };
514 :
515 : /*!
516 : * \brief Computes the evolution gauge quantity \f$\hat \Pi\f$ for the scalar
517 : * field on the worldtube.
518 : *
519 : * \details The evolution gauge \f$\hat \Pi\f$ obeys
520 : * \f{align*}{
521 : * \hat \Pi = \partial_{t^\prime} \psi + \Re
522 : * \left(\mathcal{U}^{(0)}\bar{\eth}\psi\right)
523 : * \f}
524 : *
525 : * where \f$\partial_{t^\prime} \psi\f$ comes from the Cauchy evolution.
526 : */
527 : template <>
528 1 : struct GaugeAdjustedBoundaryValue<Tags::KleinGordonPi> {
529 0 : using return_tags =
530 : tmpl::list<Tags::EvolutionGaugeBoundaryValue<Tags::KleinGordonPi>>;
531 0 : using argument_tags = tmpl::list<
532 : Tags::BoundaryValue<Tags::KleinGordonPi>, Tags::BondiUAtScri,
533 : Spectral::Swsh::Tags::SwshInterpolator<Tags::CauchyAngularCoords>,
534 : Tags::LMax, Tags::KleinGordonPsi>;
535 :
536 0 : static void apply(
537 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>
538 : evolution_kg_pi,
539 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& cauchy_kg_pi,
540 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&
541 : evolution_gauge_u_at_scri,
542 : const Spectral::Swsh::SwshInterpolator& interpolator, size_t l_max,
543 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& volume_psi);
544 : };
545 :
546 : /*!
547 : * \brief Update the Cauchy gauge cartesian coordinate derivative \f$\partial_u
548 : * x(\hat x)\f$, as well as remaining gauge quantities \f$\mathcal U^{(0)}\f$,
549 : * \f$\hat U \equiv \mathcal U - \mathcal U^{(0)}\f$, and \f$\partial_{\hat u}
550 : * \hat \omega\f$ to maintain asymptotically inertial angular coordinates.
551 : *
552 : * \details The constraint we must satisfy to maintain the asymptotically
553 : * inertial angular coordinates is
554 : *
555 : * \f{align*}{
556 : * \partial_{\hat u} x^A = \mathcal U^{(0) \hat A} \partial_{\hat A} x^{A},
557 : * \f}
558 : *
559 : * which we compute for a representative Cartesian coordinate set on the unit
560 : * sphere, to maintain representability and ensure that angular transform and
561 : * derivative operations keep the desired precision. The equation we use for the
562 : * Cartesian analog is:
563 : *
564 : * \f{align*}{
565 : * \partial_{\hat u} x^i &= \frac{1}{2} (\bar{\mathcal U}^{(0)} \hat \eth x^i +
566 : * \mathcal U^{(0)} \hat{\bar \eth} x^i ) \\
567 : * &= \text{Re}(\bar{\mathcal U}^{(0)} \hat \eth x^i)
568 : * \f}
569 : *
570 : * This computation completes the unfixed degrees of freedom for the coordinate
571 : * transformation at the boundary, so also computes the gauge quantities that
572 : * rely on this information \f$\mathcal U^{(0)}\f$,
573 : * \f$\hat U\f$, and \f$\partial_{\hat u} \hat \omega\f$.
574 : *
575 : * The time derivative of \f$\hat \omega\f$ is calculated from the equation
576 : * \f{align*}{
577 : * \partial_{\hat u} \hat \omega
578 : * = \frac{\hat \omega}{4} (\hat{\bar \eth} \mathcal U^{(0)}
579 : * + \hat \eth \bar{\mathcal U}^{(0)})
580 : * + \frac{1}{2} (\mathcal U^{(0)} \hat{\bar \eth} \hat \omega
581 : * + \bar{\mathcal U}^{(0)} \hat \eth \hat \omega)
582 : * \f}
583 : * \warning Before this update call the quantity stored in the tag
584 : * `Cce::Tags::BondiU` represents \f$\mathcal U\f$, and after this update call,
585 : * it represents \f$\hat U\f$ (the true evolution gauge quantity).
586 : */
587 1 : struct GaugeUpdateTimeDerivatives {
588 0 : using return_tags =
589 : tmpl::list<::Tags::dt<Tags::CauchyCartesianCoords>, Tags::BondiUAtScri,
590 : Tags::BondiU, Tags::Du<Tags::PartiallyFlatGaugeOmega>>;
591 0 : using argument_tags =
592 : tmpl::list<Tags::CauchyCartesianCoords, Tags::PartiallyFlatGaugeOmega,
593 : Spectral::Swsh::Tags::Derivative<Tags::PartiallyFlatGaugeOmega,
594 : Spectral::Swsh::Tags::Eth>,
595 : Tags::LMax>;
596 :
597 0 : static void apply(
598 : gsl::not_null<tnsr::i<DataVector, 3>*> cartesian_cauchy_du_x,
599 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*>
600 : evolution_gauge_u_at_scri,
601 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*> volume_u,
602 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> du_omega,
603 : const tnsr::i<DataVector, 3>& cartesian_cauchy_coordinates,
604 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega,
605 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_omega,
606 : size_t l_max);
607 : };
608 :
609 : /*!
610 : * \brief Update the inertial gauge cartesian coordinate derivative
611 : * \f$\partial_u \hat x(x)\f$.
612 : *
613 : * \details For the asymptotically inertial angular coordinates
614 : * \f$\hat{x}^{\hat{A}}\f$, we have:
615 : *
616 : * \f{align*}{
617 : * \partial_u \hat{x}^{\hat{A}} = -U^{(0)B}\partial_B \hat{x}^{\hat{A}}
618 : * \f}
619 : *
620 : * and the Cartesian version reads
621 : *
622 : * \f{align*}{
623 : * \partial_u \hat{x}^{\hat{i}}= - \text{Re}(\bar{U}^{(0)}
624 : * \eth \hat{x}^{\hat{i}})
625 : * \f}
626 : *
627 : * Note that \f$U^{0}\f$ and \f$\mathcal U^{(0)}\f$ are related by
628 : *
629 : * \f{align*}{
630 : * U^{(0)} &= \frac{1}{2\omega^2} \left( \bar{d} \mathcal U^{(0)} -
631 : * c \bar{\mathcal U}^{(0)} \right) \\
632 : * &= \frac{\hat \omega^2}{2} \left( \bar{d} \mathcal U^{(0)} -
633 : * c \bar{\mathcal U}^{(0)} \right)
634 : * \f}
635 : *
636 : * see Eq. (79) of \cite Moxon2020gha.
637 : */
638 1 : struct GaugeUpdateInertialTimeDerivatives {
639 0 : using return_tags = tmpl::list<::Tags::dt<Tags::PartiallyFlatCartesianCoords>,
640 : Tags::BondiUAtScri>;
641 0 : using argument_tags = tmpl::list<
642 : Tags::PartiallyFlatCartesianCoords, Tags::CauchyGaugeC,
643 : Tags::PartiallyFlatGaugeOmega, Tags::CauchyGaugeD, Tags::LMax,
644 : Spectral::Swsh::Tags::SwshInterpolator<Tags::PartiallyFlatAngularCoords>>;
645 0 : static void apply(
646 : gsl::not_null<tnsr::i<DataVector, 3>*> cartesian_inertial_du_x,
647 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*>
648 : evolution_gauge_u_at_scri,
649 : const tnsr::i<DataVector, 3>& cartesian_inertial_coordinates,
650 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& gauge_cauchy_c,
651 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega,
652 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& gauge_cauchy_d,
653 : size_t l_max, const Spectral::Swsh::SwshInterpolator& interpolator);
654 : };
655 :
656 : /*!
657 : * \brief Update the angular coordinates stored in `AngularTag` via
658 : * trigonometric operations applied to the Cartesian coordinates stored in
659 : * `CartesianTag`.
660 : *
661 : * \details This function also normalizes the Cartesian coordinates stored in
662 : * `CartesianTag`, which is the desired behavior for the CCE boundary
663 : * computation.
664 : */
665 : template <typename AngularTag, typename CartesianTag>
666 1 : struct GaugeUpdateAngularFromCartesian {
667 0 : using argument_tags = tmpl::list<>;
668 0 : using return_tags = tmpl::list<AngularTag, CartesianTag>;
669 :
670 0 : static void apply(
671 : const gsl::not_null<
672 : tnsr::i<DataVector, 2, ::Frame::Spherical<::Frame::Inertial>>*>
673 : angular_coordinates,
674 : const gsl::not_null<tnsr::i<DataVector, 3>*> cartesian_coordinates) {
675 : // normalize the cartesian coordinates
676 : const DataVector one_over_cartesian_r =
677 : 1.0 / sqrt(square(get<0>(*cartesian_coordinates)) +
678 : square(get<1>(*cartesian_coordinates)) +
679 : square(get<2>(*cartesian_coordinates)));
680 :
681 : get<0>(*cartesian_coordinates) *= one_over_cartesian_r;
682 : get<1>(*cartesian_coordinates) *= one_over_cartesian_r;
683 : get<2>(*cartesian_coordinates) *= one_over_cartesian_r;
684 :
685 : const auto& x = get<0>(*cartesian_coordinates);
686 : const auto& y = get<1>(*cartesian_coordinates);
687 : const auto& z = get<2>(*cartesian_coordinates);
688 :
689 : get<0>(*angular_coordinates) = atan2(sqrt(square(x) + square(y)), z);
690 : get<1>(*angular_coordinates) = atan2(y, x);
691 : }
692 : };
693 :
694 : namespace detail {
695 : void gauge_update_jacobian_from_coordinates_apply_impl(
696 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>
697 : gauge_factor_spin_2,
698 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>
699 : gauge_factor_spin_0,
700 : gsl::not_null<
701 : tnsr::i<DataVector, 2, ::Frame::Spherical<::Frame::Inertial>>*>
702 : angular_source_coordinates,
703 : const tnsr::i<DataVector, 3>& cartesian_source_coordinates, size_t l_max);
704 : } // namespace detail
705 :
706 : /*!
707 : * \brief From the angular coordinates `AngularCoordinateTag` and the Cartesian
708 : * coordinates `CartesianCoordinateTag`, determine the spin-weighted Jacobian
709 : * factors `GaugeFactorSpin2` and `GaugeFactorSpin0`.
710 : *
711 : * \details This is most often used in the context of generating the Jacobians
712 : * in the evolution-gauge coordinates from the Cauchy collocation points as a
713 : * function of the evolution gauge coordinates. In this concrete case, the
714 : * `GaugeFactorSpin2` is the gauge factor \f$\hat c\f$ and takes the value
715 : *
716 : * \f{align*}{
717 : * \hat c = \hat q^{\hat A} \partial_{\hat A}(x^A) q_A,
718 : * \f}
719 : *
720 : * and the `GaugeFactorSpin0` is the gauge factor \f$\hat d\f$ and takes the
721 : * value
722 : *
723 : * \f{align*}{
724 : * \hat d = \hat{\bar q}^{\hat A} \partial_{\hat A}(x^A) q_A.
725 : * \f}
726 : *
727 : * The more generic template construction is employed so that the spin-weighted
728 : * Jacobians can also be computed between two arbitrary gauges, including the
729 : * inverse Jacobians associated with moving from the evolution gauge to the
730 : * Cauchy gauge.
731 : */
732 : template <typename GaugeFactorSpin2, typename GaugeFactorSpin0,
733 : typename AngularCoordinateTag, typename CartesianCoordinateTag>
734 1 : struct GaugeUpdateJacobianFromCoordinates {
735 0 : using return_tags =
736 : tmpl::list<GaugeFactorSpin2, GaugeFactorSpin0, AngularCoordinateTag>;
737 0 : using argument_tags = tmpl::list<CartesianCoordinateTag, Tags::LMax>;
738 :
739 0 : static void apply(
740 : const gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>
741 : gauge_factor_spin_2,
742 : const gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>
743 : gauge_factor_spin_0,
744 : const gsl::not_null<
745 : tnsr::i<DataVector, 2, ::Frame::Spherical<::Frame::Inertial>>*>
746 : angular_source_coordinates,
747 : const tnsr::i<DataVector, 3>& cartesian_source_coordinates,
748 : const size_t l_max) {
749 : detail::gauge_update_jacobian_from_coordinates_apply_impl(
750 : gauge_factor_spin_2, gauge_factor_spin_0, angular_source_coordinates,
751 : cartesian_source_coordinates, l_max);
752 : }
753 : };
754 :
755 : /*!
756 : * \brief Update the interpolator stored in
757 : * `Spectral::Swsh::Tags::SwshInterpolator<AngularCoordinates>`.
758 : *
759 : * \details Note that the `AngularCoordinates` associated with the interpolator
760 : * should be the source coordinates. For instance, when interpolating a quantity
761 : * defined on the Cauchy gauge collocation points to the evolution gauge
762 : * collocation points, the interpolator input should be the Cauchy coordinates
763 : * points as a function of the evolution gauge coordinates (at the evolution
764 : * gauge collocation points).
765 : */
766 : template <typename AngularCoordinates>
767 1 : struct GaugeUpdateInterpolator {
768 0 : using return_tags =
769 : tmpl::list<Spectral::Swsh::Tags::SwshInterpolator<AngularCoordinates>>;
770 0 : using argument_tags = tmpl::list<AngularCoordinates, Tags::LMax>;
771 :
772 0 : static void apply(
773 : const gsl::not_null<Spectral::Swsh::SwshInterpolator*> interpolator,
774 : const tnsr::i<DataVector, 2, ::Frame::Spherical<::Frame::Inertial>>&
775 : angular_coordinates,
776 : const size_t l_max) {
777 : // throw away the old interpolator and generate a new one for the current
778 : // grid points.
779 : *interpolator = Spectral::Swsh::SwshInterpolator(
780 : get<0>(angular_coordinates), get<1>(angular_coordinates), l_max);
781 : }
782 : };
783 :
784 : /*!
785 : * \brief Update the quantity \f$\hat \omega\f$ and \f$\hat \eth \hat \omega\f$
786 : * for updated spin-weighted Jacobian quantities \f$\hat c\f$ and \f$\hat d\f$.
787 : *
788 : * \details The conformal factor \f$\hat \omega\f$ can be determined by the
789 : * angular determinant from the spin-weighted Jacobian factors as
790 : *
791 : * \f{align*}{
792 : * \hat \omega = \frac{1}{2} \sqrt{\hat d \hat{\bar d} - \hat c \hat{\bar c}}.
793 : * \f}
794 : */
795 : template <typename GaugeC, typename GaugeD, typename GaugeOmega>
796 1 : struct GaugeUpdateOmega {
797 0 : using argument_tags = tmpl::list<GaugeC, GaugeD, Tags::LMax>;
798 0 : using return_tags = tmpl::list<
799 : GaugeOmega,
800 : Spectral::Swsh::Tags::Derivative<GaugeOmega, Spectral::Swsh::Tags::Eth>>;
801 :
802 0 : static void apply(
803 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> omega,
804 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*> eth_omega,
805 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& gauge_c,
806 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& gauge_d, size_t l_max);
807 : };
808 :
809 : /*!
810 : * \brief Initialize to default values (identity transform) all of the angular
811 : * gauge quantities for the boundary gauge transforms.
812 : *
813 : * \details The updated quantities are the Cauchy angular and Cartesian
814 : * coordinates, as well as the spin-weighted gauge factors and the conformal
815 : * factor. All quantities are initialized to the appropriate value for the
816 : * identity transform of angular coordinates. Using this initialization function
817 : * ensures that the evolution gauge and the Cauchy gauge angular coordinates
818 : * agree on the first evaluated time.
819 : * - `CauchyAngularCoords` are set to the angular collocation values for the
820 : * spin-weighted spherical harmonic library
821 : * - `CauchyCartesianCoords` are set to the Cartesian coordinates for the
822 : * `CauchyAngularCoords` evaluated on a unit sphere.
823 : * - `GaugeC` is set to 0
824 : * - `GaugeD` is set to 2
825 : * - `GaugeOmega` is set to 1
826 : */
827 1 : struct InitializeGauge {
828 0 : using return_tags =
829 : tmpl::list<Tags::CauchyAngularCoords, Tags::CauchyCartesianCoords,
830 : Tags::PartiallyFlatGaugeC, Tags::PartiallyFlatGaugeD,
831 : Tags::PartiallyFlatGaugeOmega>;
832 0 : using argument_tags = tmpl::list<Tags::LMax>;
833 :
834 0 : static void apply(
835 : gsl::not_null<
836 : tnsr::i<DataVector, 2, ::Frame::Spherical<::Frame::Inertial>>*>
837 : angular_cauchy_coordinates,
838 : gsl::not_null<tnsr::i<DataVector, 3>*> cartesian_cauchy_coordinates,
839 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*> gauge_c,
840 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> gauge_d,
841 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> omega,
842 : size_t l_max);
843 : };
844 : } // namespace Cce
|