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/DataBox/Prefixes.hpp"
9 : #include "Evolution/Systems/Cce/OptionTags.hpp"
10 : #include "Evolution/Systems/Cce/Tags.hpp"
11 :
12 : namespace Cce {
13 :
14 : /// The tags that are needed to be interpolated at scri+ for the available
15 : /// observation tags.
16 1 : using scri_plus_interpolation_set =
17 : tmpl::list<Tags::News, Tags::ScriPlus<Tags::Strain>,
18 : Tags::ScriPlus<Tags::Psi3>, Tags::ScriPlus<Tags::Psi2>,
19 : Tags::ScriPlus<Tags::Psi1>, Tags::ScriPlus<Tags::Psi0>,
20 : Tags::Du<Tags::TimeIntegral<Tags::ScriPlus<Tags::Psi4>>>,
21 : Tags::EthInertialRetardedTime>;
22 :
23 : template <typename Tag>
24 0 : struct CalculateScriPlusValue;
25 :
26 : /*!
27 : * \brief Compute the Bondi news from the evolution quantities.
28 : *
29 : * \details In the gauge used for regularity-preserving CCE,
30 : * the Bondi news takes the convenient form
31 : *
32 : * \f{align*}{
33 : * N = e^{-2 \beta^{(0)}} \left( (\partial_u \bar J)^{(1)}
34 : * + \bar \eth \bar \eth e^{2 \beta^{(0)}}\right),
35 : * \f}
36 : *
37 : * where \f$(0)\f$ and \f$(1)\f$ in the superscripts denote the zeroth and first
38 : * order in an expansion in \f$1/r\f$ near \f$\mathcal{I}^+\f$.
39 : */
40 : template <>
41 1 : struct CalculateScriPlusValue<Tags::News> {
42 0 : using return_tags = tmpl::list<Tags::News>;
43 : // extra typelist for more convenient testing
44 0 : using tensor_argument_tags =
45 : tmpl::list<Tags::Dy<Tags::Du<Tags::BondiJ>>, Tags::BondiBeta,
46 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
47 : Spectral::Swsh::Tags::Eth>,
48 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
49 : Spectral::Swsh::Tags::EthEth>,
50 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>>;
51 0 : using argument_tags =
52 : tmpl::append<tensor_argument_tags,
53 : tmpl::list<Tags::LMax, Tags::NumberOfRadialPoints>>;
54 :
55 0 : static void apply(
56 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -2>>*> news,
57 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_du_bondi_j,
58 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& beta,
59 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_beta,
60 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& eth_eth_beta,
61 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& boundary_r,
62 : size_t l_max, size_t number_of_radial_points);
63 : };
64 :
65 : /*!
66 : * \brief Compute the contribution to the leading \f$\Psi_4\f$ that corresponds
67 : * to a total time derivative.
68 : *
69 : * \details The value \f$\Psi_4\f$ scales asymptotically as \f$r^{-1}\f$, and
70 : * has the form
71 : *
72 : * \f{align*}{
73 : * \Psi_4^{(1)} = \partial_{u_{\text{inertial}}} B,
74 : * \f}
75 : *
76 : * where superscripts denote orders in the expansion in powers of \f$r^{-1}\f$.
77 : * This mutator computes \f$B\f$:
78 : *
79 : * \f{align*}{
80 : * B = 2 e^{-2 \beta^{(0)}} (\bar \eth \bar U^{(1)} + \partial_u \bar J^{(1)})
81 : * \f}
82 : *
83 : * and the time derivative that appears the original equation obeys,
84 : *
85 : * \f[
86 : * \partial_{u_{\text{inertial}}} = e^{-2 \beta} \partial_u
87 : * \f]
88 : */
89 : template <>
90 1 : struct CalculateScriPlusValue<Tags::TimeIntegral<Tags::ScriPlus<Tags::Psi4>>> {
91 0 : using return_tags =
92 : tmpl::list<Tags::TimeIntegral<Tags::ScriPlus<Tags::Psi4>>>;
93 : // extra typelist for more convenient testing
94 0 : using tensor_argument_tags =
95 : tmpl::list<Tags::Exp2Beta, Tags::Dy<Tags::BondiU>,
96 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::BondiU>,
97 : Spectral::Swsh::Tags::Eth>,
98 : Tags::Dy<Tags::Du<Tags::BondiJ>>,
99 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>,
100 : Tags::EthRDividedByR>;
101 0 : using argument_tags =
102 : tmpl::append<tensor_argument_tags,
103 : tmpl::list<Tags::LMax, Tags::NumberOfRadialPoints>>;
104 :
105 0 : static void apply(
106 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -2>>*>
107 : integral_of_psi_4,
108 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& exp_2_beta,
109 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& dy_bondi_u,
110 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& eth_dy_bondi_u,
111 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_du_bondi_j,
112 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& boundary_r,
113 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_r_divided_by_r,
114 : size_t l_max, size_t number_of_radial_points);
115 : };
116 :
117 :
118 : /*!
119 : * \brief Computes the leading part of \f$\Psi_3\f$ near \f$\mathcal I^+\f$.
120 : *
121 : * \details The value \f$\Psi_3\f$ scales asymptotically as \f$r^{-2}\f$, and
122 : * has the form (in the coordinates used for regularity preserving CCE)
123 : *
124 : * \f{align*}{
125 : * \Psi_3^{(2)} = 2 \bar \eth \beta^{(0)}
126 : * + 4 \bar \eth \beta^{(0)} \eth \bar \eth \beta^{(0)}
127 : * + \bar \eth \eth \bar \eth \beta^{(0)}
128 : * + \frac{e^{-2 \beta^{(0)}}}{2} \eth \partial_u \bar J^{(1)}
129 : * - e^{-2 \beta^{(0)}} \eth \beta^{(0)} \partial_u \bar J^{(1)}
130 : * \f},
131 : *
132 : * where \f$J^{(n)}\f$ is the \f$1/r^n\f$ part of \f$J\f$ evaluated at
133 : * \f$\mathcal I^+\f$, so
134 : *
135 : * \f{align*}{
136 : * J^{(1)} = (-2 R \partial_y J)|_{y = 1},
137 : * \f}
138 : *
139 : * where the expansion is determined by the conversion between Bondi and
140 : * numerical radii \f$r = 2 R / (1 - y)\f$.
141 : */
142 : template <>
143 1 : struct CalculateScriPlusValue<Tags::ScriPlus<Tags::Psi3>> {
144 0 : using return_tags = tmpl::list<Tags::ScriPlus<Tags::Psi3>>;
145 : // extra typelist for more convenient testing
146 0 : using tensor_argument_tags = tmpl::list<
147 : Tags::Exp2Beta,
148 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
149 : Spectral::Swsh::Tags::Eth>,
150 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
151 : Spectral::Swsh::Tags::EthEthbar>,
152 : Spectral::Swsh::Tags::Derivative<
153 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
154 : Spectral::Swsh::Tags::EthEthbar>,
155 : Spectral::Swsh::Tags::Ethbar>,
156 : Tags::Dy<Tags::Du<Tags::BondiJ>>,
157 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::Du<Tags::BondiJ>>,
158 : Spectral::Swsh::Tags::Ethbar>,
159 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>, Tags::EthRDividedByR>;
160 0 : using argument_tags = tmpl::push_back<tensor_argument_tags, Tags::LMax,
161 : Tags::NumberOfRadialPoints>;
162 :
163 0 : static void apply(
164 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -1>>*> psi_3,
165 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& exp_2_beta,
166 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_beta,
167 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& eth_ethbar_beta,
168 : const Scalar<SpinWeighted<ComplexDataVector, -1>>& ethbar_eth_ethbar_beta,
169 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_du_bondi_j,
170 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& ethbar_dy_du_bondi_j,
171 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& boundary_r,
172 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_r_divided_by_r,
173 : size_t l_max, size_t number_of_radial_points);
174 : };
175 :
176 : /*!
177 : * \brief Computes the leading part of \f$\Psi_2\f$ near \f$\mathcal I^+\f$.
178 : *
179 : * \details The value \f$\Psi_2\f$ scales asymptotically as \f$r^{-3}\f$, and
180 : * has the form (in the coordinates used for regularity preserving CCE)
181 : *
182 : * \f{align*}{
183 : * \Psi_2^{(3)} = -\frac{e^{-2 \beta^{(0)}}}{4}
184 : * \left(e^{2 \beta^{(0)}} \eth \bar Q^{(1)} + \eth \bar U^{(2)}
185 : * + \bar \eth U^{(2)} + J^{(1)} \bar \eth \bar U^{(1)}
186 : * + J^{(1)} \bar \partial_u J^{(1)} - 2 W^{(2)}\right)
187 : * \f},
188 : *
189 : * where \f$A^{(n)}\f$ is the \f$1/r^n\f$ part of \f$A\f$ evaluated at
190 : * \f$\mathcal I^+\f$, so for any quantity \f$A\f$,
191 : *
192 : * \f{align*}{
193 : * \eth A^{(1)} &= (-2 R \eth \partial_y A
194 : * - 2 \eth R \partial_y A)|_{y = 1} \notag\\
195 : * \eth A^{(2)} &= (2 R^2 \eth \partial_y^2 A
196 : * + 2 R \eth R \partial^2_y A)|_{y = 1}, \notag\\
197 : * A^{(1)} &= (- 2 R \partial_y A)|_{y = 1}, \notag\\
198 : * A^{(2)} &= (2 R^2 \partial_y^2 A)|_{y = 1},
199 : * \f}
200 : *
201 : * where the expansion is determined by the conversion between Bondi and
202 : * numerical radii \f$r = 2 R / (1 - y)\f$.
203 : */
204 : template <>
205 1 : struct CalculateScriPlusValue<Tags::ScriPlus<Tags::Psi2>> {
206 0 : using return_tags = tmpl::list<Tags::ScriPlus<Tags::Psi2>>;
207 : // extra typelist for more convenient testing
208 0 : using tensor_argument_tags = tmpl::list<
209 : Tags::Exp2Beta, Tags::Dy<Tags::BondiQ>,
210 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::BondiQ>,
211 : Spectral::Swsh::Tags::Ethbar>,
212 : Tags::Dy<Tags::BondiU>,
213 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::BondiU>,
214 : Spectral::Swsh::Tags::Eth>,
215 : Tags::Dy<Tags::Dy<Tags::BondiU>>,
216 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::Dy<Tags::BondiU>>,
217 : Spectral::Swsh::Tags::Ethbar>,
218 : Tags::Dy<Tags::Dy<Tags::BondiW>>, Tags::Dy<Tags::BondiJ>,
219 : Tags::Dy<Tags::Du<Tags::BondiJ>>,
220 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>, Tags::EthRDividedByR>;
221 0 : using argument_tags = tmpl::push_back<tensor_argument_tags, Tags::LMax,
222 : Tags::NumberOfRadialPoints>;
223 :
224 0 : static void apply(
225 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> psi_2,
226 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& exp_2_beta,
227 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& dy_bondi_q,
228 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& ethbar_dy_bondi_q,
229 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& dy_bondi_u,
230 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& eth_dy_bondi_u,
231 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& dy_dy_bondi_u,
232 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& ethbar_dy_dy_bondi_u,
233 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& dy_dy_bondi_w,
234 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_bondi_j,
235 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_du_bondi_j,
236 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& boundary_r,
237 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_r_divided_by_r,
238 : size_t l_max, size_t number_of_radial_points);
239 : };
240 :
241 : /*!
242 : * \brief Computes the leading part of \f$\Psi_1\f$ near \f$\mathcal I^+\f$.
243 : *
244 : * \details The value \f$\Psi_1\f$ scales asymptotically as \f$r^{-4}\f$, and
245 : * has the form (in the coordinates used for regularity preserving CCE)
246 : *
247 : * \f{align*}{
248 : * \Psi_1^{(4)} = \frac{1}{8} \left(- 12 \eth \beta^{(2)} + J^{(1)} \bar Q^{(1)}
249 : * + 2 Q^{(2)}\right)
250 : * \f}
251 : *
252 : * where \f$A^{(n)}\f$ is the \f$1/r^n\f$ part of \f$A\f$ evaluated at
253 : * \f$\mathcal I^+\f$, so for any quantity \f$A\f$,
254 : *
255 : * \f{align*}{
256 : * \eth A^{(2)} &= (2 R^2 \eth \partial_y^2 A
257 : * + 2 R \eth R \partial^2_y A)|_{y = 1}, \notag\\
258 : * A^{(1)} &= (- 2 R \partial_y A)|_{y = 1}, \notag\\
259 : * A^{(2)} &= (2 R^2 \partial_y^2 A)|_{y = 1},
260 : * \f}
261 : *
262 : * where the expansion is determined by the conversion between Bondi and
263 : * numerical radii \f$r = 2 R / (1 - y)\f$.
264 : */
265 : template <>
266 1 : struct CalculateScriPlusValue<Tags::ScriPlus<Tags::Psi1>> {
267 0 : using return_tags = tmpl::list<Tags::ScriPlus<Tags::Psi1>>;
268 : // extra typelist for more convenient testing
269 0 : using tensor_argument_tags = tmpl::list<
270 : Tags::Dy<Tags::Dy<Tags::BondiBeta>>,
271 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::Dy<Tags::BondiBeta>>,
272 : Spectral::Swsh::Tags::Eth>,
273 : Tags::Dy<Tags::BondiJ>, Tags::Dy<Tags::BondiQ>,
274 : Tags::Dy<Tags::Dy<Tags::BondiQ>>,
275 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>, Tags::EthRDividedByR>;
276 0 : using argument_tags = tmpl::push_back<tensor_argument_tags, Tags::LMax,
277 : Tags::NumberOfRadialPoints>;
278 :
279 0 : static void apply(
280 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*> psi_1,
281 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& dy_dy_bondi_beta,
282 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_dy_dy_bondi_beta,
283 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_bondi_j,
284 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& dy_bondi_q,
285 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& dy_dy_bondi_q,
286 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& boundary_r,
287 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_r_divided_by_r,
288 : size_t l_max, size_t number_of_radial_points);
289 : };
290 :
291 : /*!
292 : * \brief Computes the leading part of \f$\Psi_0\f$ near \f$\mathcal I^+\f$.
293 : *
294 : * \details The value \f$\Psi_0\f$ scales asymptotically as \f$r^{-5}\f$, and
295 : * has the form (in the coordinates used for regularity preserving CCE)
296 : *
297 : * \f{align*}{
298 : * \Psi_0^{(5)} = \frac{3}{16}\bar J^{(1)}\left(J^{(1)}\right)^2
299 : * - \frac{3}{2}J^{(3)}.
300 : * \f}
301 : *
302 : * This follows by expanding the finite-radius implementation of Eq. (91a) of
303 : * \cite Moxon2020gha, which uses the vacuum beta hypersurface equation.
304 : *
305 : * Here \f$A^{(n)}\f$ is the \f$1/r^n\f$ part of \f$A\f$ evaluated at
306 : * \f$\mathcal I^+\f$, so for any quantity \f$A\f$,
307 : *
308 : * \f{align*}{
309 : * A^{(1)} &= (- 2 R \partial_y A)|_{y = 1} \notag\\
310 : * A^{(3)} &= \left(-\frac{4}{3} R^3 \partial_y^3 A\right)|_{y = 1},
311 : * \f}
312 : *
313 : * where the expansion is determined by the conversion between Bondi and
314 : * numerical radii \f$r = 2 R / (1 - y)\f$. Consequently, with
315 : * \f$j_1=(\partial_yJ)|_{y=1}\f$ and
316 : * \f$j_3=(\partial_y^3J)|_{y=1}\f$,
317 : *
318 : * \f{align*}{
319 : * \Psi_0^{(5)}=-R^3\left(\frac{3}{2}\bar j_1j_1^2-2j_3\right).
320 : * \f}
321 : */
322 : template <>
323 1 : struct CalculateScriPlusValue<Tags::ScriPlus<Tags::Psi0>> {
324 0 : using return_tags = tmpl::list<Tags::ScriPlus<Tags::Psi0>>;
325 : // extra typelist for more convenient testing
326 0 : using tensor_argument_tags =
327 : tmpl::list<Tags::Dy<Tags::BondiJ>,
328 : Tags::Dy<Tags::Dy<Tags::Dy<Tags::BondiJ>>>,
329 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>>;
330 0 : using argument_tags = tmpl::push_back<tensor_argument_tags, Tags::LMax,
331 : Tags::NumberOfRadialPoints>;
332 :
333 0 : static void apply(
334 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*> psi_0,
335 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_bondi_j,
336 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_dy_dy_bondi_j,
337 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& boundary_r,
338 : size_t l_max, size_t number_of_radial_points);
339 : };
340 :
341 : /*!
342 : * \brief Computes the leading part of the strain \f$h\f$ near \f$\mathcal
343 : * I^+\f$.
344 : *
345 : * \details The value \f$h\f$ scales asymptotically as \f$r^{-1}\f$, and
346 : * has the form (in the coordinates used for regularity preserving CCE)
347 : *
348 : * \f{align*}{
349 : * h = \bar J^{(1)} + \bar \eth \bar \eth u^{(0)},
350 : * \f}
351 : *
352 : * where \f$u^{(0)}\f$ is the asymptotically inertial retarded time, and
353 : * \f$A^{(n)}\f$ is the \f$1/r^n\f$ part of \f$A\f$ evaluated at
354 : * \f$\mathcal I^+\f$, so for any quantity \f$A\f$,
355 : *
356 : * \f{align*}{
357 : * A^{(1)} = (- 2 R \partial_y A)|_{y = 1},
358 : * \f}
359 : *
360 : * where the expansion is determined by the conversion between Bondi and
361 : * numerical radii \f$r = 2 R / (1 - y)\f$.
362 : */
363 : template <>
364 1 : struct CalculateScriPlusValue<Tags::ScriPlus<Tags::Strain>> {
365 0 : using return_tags = tmpl::list<Tags::ScriPlus<Tags::Strain>>;
366 : // extra typelist for more convenient testing
367 0 : using tensor_argument_tags = tmpl::list<
368 : Tags::Dy<Tags::BondiJ>,
369 : Spectral::Swsh::Tags::Derivative<Tags::ComplexInertialRetardedTime,
370 : Spectral::Swsh::Tags::EthEth>,
371 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>>;
372 0 : using argument_tags = tmpl::push_back<tensor_argument_tags, Tags::LMax,
373 : Tags::NumberOfRadialPoints>;
374 :
375 0 : static void apply(
376 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -2>>*> strain,
377 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_bondi_j,
378 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& eth_eth_retarded_time,
379 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& boundary_r,
380 : size_t l_max, size_t number_of_radial_points);
381 : };
382 :
383 : /*!
384 : * \brief Assign the time derivative of the asymptotically inertial time
385 : * coordinate.
386 : *
387 : * \details The asymptotically inertial time coordinate \f$\mathring u\f$ obeys
388 : * the differential equation:
389 : *
390 : * \f{align*}{
391 : * \partial_u \mathring u = e^{2 \beta}.
392 : * \f}
393 : */
394 : template <>
395 1 : struct CalculateScriPlusValue<::Tags::dt<Tags::InertialRetardedTime>> {
396 0 : using return_tags = tmpl::list<::Tags::dt<Tags::InertialRetardedTime>>;
397 0 : using argument_tags = tmpl::list<Tags::Exp2Beta>;
398 :
399 0 : static void apply(
400 : gsl::not_null<Scalar<DataVector>*> dt_inertial_time,
401 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& exp_2_beta);
402 : };
403 :
404 : /// Determines the angular derivative of the asymptotic inertial time, useful
405 : /// for asymptotic coordinate transformations.
406 : template <>
407 1 : struct CalculateScriPlusValue<Tags::EthInertialRetardedTime> {
408 0 : using return_tags = tmpl::list<Tags::EthInertialRetardedTime>;
409 0 : using argument_tags =
410 : tmpl::list<Tags::ComplexInertialRetardedTime, Tags::LMax>;
411 :
412 0 : static void apply(
413 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*>
414 : eth_inertial_time,
415 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& inertial_time,
416 : size_t l_max);
417 : };
418 :
419 : /*!
420 : * \brief Computes the leading part of the scalar field \f$\psi\f$ near
421 : * \f$\mathcal I^+\f$.
422 : *
423 : * \details The value \f$\psi\f$ scales asymptotically as \f$r^{-1}\f$. Assuming
424 : * \f$\psi^{(n)}\f$ is the \f$1/r^n\f$ part of \f$\psi\f$ evaluated at
425 : * \f$\mathcal I^+\f$, so for any \f$\psi\f$,
426 : *
427 : * \f{align*}{
428 : * \psi^{(1)} = (- 2 R \partial_y \psi)|_{y = 1},
429 : * \f}
430 : *
431 : * where the expansion is determined by the conversion between Bondi and
432 : * numerical radii \f$r = 2 R / (1 - y)\f$.
433 : */
434 : template <>
435 1 : struct CalculateScriPlusValue<Tags::ScriPlus<Tags::KleinGordonPsi>> {
436 0 : using return_tags = tmpl::list<Tags::ScriPlus<Tags::KleinGordonPsi>>;
437 0 : using tensor_argument_tags =
438 : tmpl::list<Tags::Dy<Tags::KleinGordonPsi>,
439 : Tags::EvolutionGaugeBoundaryValue<Tags::BondiR>>;
440 0 : using argument_tags = tmpl::push_back<tensor_argument_tags, Tags::LMax,
441 : Tags::NumberOfRadialPoints>;
442 :
443 0 : static void apply(
444 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> kg_psi_scri,
445 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& dy_kg_psi,
446 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& boundary_r,
447 : size_t l_max, size_t number_of_radial_points);
448 : };
449 :
450 : /// Initialize the \f$\mathcal I^+\f$ value `Tag` for the first hypersurface.
451 : template <typename Tag>
452 1 : struct InitializeScriPlusValue;
453 :
454 : /// Initialize the inertial retarded time to the value provided in the mutator
455 : /// arguments.
456 : template <>
457 1 : struct InitializeScriPlusValue<Tags::InertialRetardedTime> {
458 0 : using argument_tags = tmpl::list<>;
459 0 : using return_tags = tmpl::list<Tags::InertialRetardedTime>;
460 :
461 0 : static void apply(const gsl::not_null<Scalar<DataVector>*> inertial_time,
462 : const double initial_time = 0.0) {
463 : // this is arbitrary, and has to do with choosing a BMS frame.
464 : get(*inertial_time) = initial_time;
465 : }
466 : };
467 : } // namespace Cce
|