Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include "DataStructures/DataBox/Tag.hpp"
7 : #include "DataStructures/SpinWeighted.hpp"
8 : #include "DataStructures/Tensor/Tensor.hpp"
9 : #include "Evolution/Systems/Cce/Tags.hpp"
10 : #include "NumericalAlgorithms/SpinWeightedSphericalHarmonics/SwshDerivatives.hpp"
11 : #include "NumericalAlgorithms/SpinWeightedSphericalHarmonics/SwshInterpolation.hpp"
12 : #include "NumericalAlgorithms/SpinWeightedSphericalHarmonics/SwshTags.hpp"
13 : #include "Utilities/Gsl.hpp"
14 : #include "Utilities/TMPL.hpp"
15 :
16 : /// \cond
17 : class ComplexDataVector;
18 : /// \endcond
19 :
20 : namespace Cce {
21 :
22 : /// \cond
23 : namespace Tags {
24 : struct LMax;
25 : } // namespace Tags
26 : template <typename Tag>
27 : struct VolumeWeyl;
28 : /// \endcond
29 :
30 : /*!
31 : * \brief Compute the (adapted) Newman-Penrose spin coefficient
32 : * $\alpha^{SW}$ in the volume, in the conventions of \cite Moxon2020gha .
33 : *
34 : * \details The definition of $\alpha$ is:
35 : *
36 : * \begin{align}
37 : * \alpha = \frac{1}{2}\left( \bar{m}^\mu \bar{m}^\nu \nabla_\nu m_\mu
38 : * - n^\mu \bar{m}^\nu \nabla_\nu l_\mu \right) .
39 : * \end{align}
40 : *
41 : * It does not have a well-defined spin weight; but by using a reference
42 : * spin-connection, the adapted spin coefficient $\alpha^{SW} \equiv \alpha -
43 : * \alpha_{ref}$ does have a well-defined spin weight of -1. In the language
44 : * of \cite Moxon2020gha, that is equivalent to setting $\Theta=0$. This
45 : * gives the expression
46 : *
47 : * \begin{align}
48 : * \alpha^{SW} = \frac{1-y}{32R} \Bigg\{
49 : * & \frac{1}{\sqrt{1+K}} \Bigg[
50 : * \frac{\bar{J}^2\eth J}{K(1+K)}
51 : * +\frac{\bar\eth(J\bar{J}) - \eth\bar{J}}{K} \\ \nonumber
52 : * & {}+ \left( 2\bar{J}(Q+2\eth\beta)-3\eth\bar{J}\right)
53 : * \Bigg]
54 : * -2\sqrt{1+K}\left(\overline{Q+2\eth\beta}\right)
55 : * \Bigg\}
56 : * \end{align}
57 : */
58 1 : void newman_penrose_alpha(
59 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -1>>*> np_alpha,
60 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j,
61 : const Scalar<SpinWeighted<ComplexDataVector, 3>>& eth_j,
62 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& ethbar_j,
63 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_k,
64 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
65 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& bondi_q,
66 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_beta,
67 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
68 :
69 : /*!
70 : * \brief Compute the (adapted) Newman-Penrose spin coefficient
71 : * $\beta_{NP}^{SW}$ in the volume, in the conventions of
72 : * \cite Moxon2020gha .
73 : *
74 : * \details The definition of $\beta_{NP}$ is:
75 : *
76 : * \begin{align}
77 : * \beta_{NP} = \frac{1}{2}\left( \bar{m}^\mu m^\nu \nabla_\nu m_\mu
78 : * - n^\mu m^\nu \nabla_\nu l_\mu \right) .
79 : * \end{align}
80 : *
81 : * It does not have a well-defined spin weight; but by using a reference
82 : * spin-connection, the adapted spin coefficient $\beta_{NP}^{SW} \equiv
83 : * \beta_{NP} - \beta_{NP,ref}$ does have a well-defined spin weight of +1. In
84 : * the language of \cite Moxon2020gha, that is equivalent to setting
85 : * $\Theta=0$. This gives the expression
86 : *
87 : * \begin{align}
88 : * \beta_{NP}^{SW} = \frac{1-y}{32R} \Bigg\{
89 : * & \frac{1}{\sqrt{1+K}} \Bigg[
90 : * -\frac{J^2\bar\eth\bar J}{K(1+K)}
91 : * +\frac{-\eth(J\bar{J}) + \bar\eth J}{K} \\ \nonumber
92 : * & {}+ \left( 2J(\overline{Q+2\eth\beta})+3\bar\eth J\right)
93 : * \Bigg]
94 : * -2\sqrt{1+K}\left(Q+2\eth\beta\right)
95 : * \Bigg\}
96 : * \end{align}
97 : */
98 1 : void newman_penrose_beta(
99 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, +1>>*> np_beta,
100 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j,
101 : const Scalar<SpinWeighted<ComplexDataVector, 3>>& eth_j,
102 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& ethbar_j,
103 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_k,
104 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
105 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& bondi_q,
106 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_beta,
107 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
108 :
109 : /*!
110 : * \brief Compute the (adapted) Newman-Penrose spin coefficient
111 : * $\gamma^{SW}$ in the volume, in the conventions of
112 : * \cite Moxon2020gha .
113 : *
114 : * \details The definition of $\gamma$ is:
115 : *
116 : * \begin{align}
117 : * \gamma = \frac{1}{2}\left( \bar{m}^\mu n^\nu \nabla_\nu m_\mu
118 : * - n^\mu n^\nu \nabla_\nu l_\mu \right) .
119 : * \end{align}
120 : *
121 : * It does not have a well-defined spin weight; but by using a reference
122 : * spin-connection, the adapted spin coefficient $\gamma^{SW} \equiv
123 : * \gamma - \gamma_{ref}$ does have a well-defined spin weight of 0. In
124 : * the language of \cite Moxon2020gha, that is equivalent to setting
125 : * $\Theta=0$. This gives the expression
126 : *
127 : * \begin{align}
128 : * \gamma^{SW} = \frac{e^{-2\beta}}{4\sqrt{2}} \Bigg\{
129 : * & \frac{1}{2(1+K)} \Bigg[
130 : * (1-y)\left(\frac{1-y}{2R}+W\right) (\bar{J}\partial_y J
131 : * - J\partial_y\bar{J}) \\ \nonumber
132 : * & + \left( 2\bar{H} J - 2H\bar{J} + U J \overline{\eth J}
133 : * - U \bar{J} \bar{\eth}J
134 : * + \bar{U} J \eth \bar{J} - \bar{U} \bar{J}\eth J \right)
135 : * \Bigg] \\ \nonumber
136 : * & + 2(1-y) \partial_y W \\ \nonumber
137 : * & + \left(2W+J\overline{\eth U}-\bar{J}\eth U
138 : * -K\eth\bar{U}+K\bar{\eth}U\right)
139 : * \Bigg\}
140 : * \end{align}
141 : */
142 1 : void newman_penrose_gamma(
143 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> np_gamma,
144 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j,
145 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_j,
146 : const Scalar<SpinWeighted<ComplexDataVector, 3>>& eth_j,
147 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& ethbar_j,
148 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_k,
149 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_h,
150 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
151 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& bondi_u,
152 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& eth_u,
153 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& ethbar_u,
154 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_w,
155 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& dy_w,
156 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& exp_2_beta,
157 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
158 :
159 : /*!
160 : * \brief Compute the (adapted) Newman-Penrose spin coefficient
161 : * $\epsilon^{SW}$ in the volume, in the conventions of
162 : * \cite Moxon2020gha .
163 : *
164 : * \details The definition of $\epsilon$ is:
165 : *
166 : * \begin{align}
167 : * \epsilon = \frac{1}{2}\left( \bar{m}^\mu l^\nu \nabla_\nu m_\mu
168 : * - n^\mu l^\nu \nabla_\nu l_\mu \right) .
169 : * \end{align}
170 : *
171 : * It does not have a well-defined spin weight; but by using a reference
172 : * spin-connection, the adapted spin coefficient $\epsilon^{SW} \equiv
173 : * \epsilon - \epsilon_{ref}$ does have a well-defined spin weight of 0. In
174 : * the language of \cite Moxon2020gha, that is equivalent to setting
175 : * $\Theta=0$. This gives the expression
176 : *
177 : * \begin{align}
178 : * \epsilon^{SW} = \frac{(1-y)^2}{2\sqrt{2} R} \left(
179 : * \partial_y \beta + \frac{J\partial_y \bar{J}
180 : * - \bar{J}\partial_y J}{8(1+K)}
181 : * \right)
182 : * \end{align}
183 : */
184 1 : void newman_penrose_epsilon(
185 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> np_epsilon,
186 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j,
187 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_j,
188 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_k,
189 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
190 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& dy_beta,
191 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
192 :
193 : // We do not define newman_penrose_kappa since in our choice of tetrad, it's 0
194 :
195 : /*!
196 : * \brief Compute the Newman-Penrose spin coefficient
197 : * $\tau$ in the volume, in the conventions of
198 : * \cite Moxon2020gha .
199 : *
200 : * \details The definition of $\tau$ is:
201 : *
202 : * \begin{align}
203 : * \tau = - m^\mu n^\nu \nabla_\nu l_\mu .
204 : * \end{align}
205 : *
206 : * It has a spin weight of +1. This gives the expression
207 : *
208 : * \begin{align}
209 : * \tau = \frac{1-y}{8 R} \left(
210 : * \sqrt{1+K} (2\eth\beta - Q)
211 : * - \frac{J (\overline{2\eth\beta-Q})}{\sqrt{1+K}}
212 : * \right)
213 : * \end{align}
214 : */
215 1 : void newman_penrose_tau(
216 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, +1>>*> np_tau,
217 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j,
218 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_k,
219 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
220 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& bondi_q,
221 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_beta,
222 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
223 :
224 : /*!
225 : * \brief Compute the Newman-Penrose spin coefficient
226 : * $\sigma$ in the volume, in the conventions of
227 : * \cite Moxon2020gha .
228 : *
229 : * \details The definition of $\sigma$ is:
230 : *
231 : * \begin{align}
232 : * \sigma = - m^\mu m^\nu \nabla_\nu l_\mu .
233 : * \end{align}
234 : *
235 : * It has a spin weight of +2. This gives the expression
236 : *
237 : * \begin{align}
238 : * \sigma = \frac{(1-y)^2}{8 \sqrt{2} K R} \left(
239 : * \frac{J^2 \partial_y \bar{J}}{1+K}
240 : * - (1+K)\partial_y J
241 : * \right)
242 : * \end{align}
243 : */
244 1 : void newman_penrose_sigma(
245 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, +2>>*> np_sigma,
246 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j,
247 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_j,
248 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_k,
249 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
250 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
251 :
252 : /*!
253 : * \brief Compute the Newman-Penrose spin coefficient
254 : * $\rho$ in the volume, in the conventions of
255 : * \cite Moxon2020gha .
256 : *
257 : * \details The definition of $\rho$ is:
258 : *
259 : * \begin{align}
260 : * \rho = - m^\mu \bar{m}^\nu \nabla_\nu l_\mu .
261 : * \end{align}
262 : *
263 : * It has a spin weight of 0. This gives the expression
264 : *
265 : * \begin{align}
266 : * \rho = - \frac{(1-y)}{2 \sqrt{2} R}
267 : * \end{align}
268 : */
269 1 : void newman_penrose_rho(
270 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> np_rho,
271 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
272 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
273 :
274 : /*!
275 : * \brief Compute the Newman-Penrose spin coefficient
276 : * $\pi$ in the volume, in the conventions of
277 : * \cite Moxon2020gha .
278 : *
279 : * \details The definition of $\pi$ is:
280 : *
281 : * \begin{align}
282 : * \pi = \bar{m}^\mu l^\nu \nabla_\nu n_\mu .
283 : * \end{align}
284 : *
285 : * It has a spin weight of -1. This gives the expression
286 : *
287 : * \begin{align}
288 : * \pi = \frac{(1-y)}{8 R} \left[
289 : * \frac{\bar{J}(Q+2\eth\beta)}{\sqrt{1+K}}
290 : * - \sqrt{1+K} (\overline{Q+2\eth\beta})
291 : * \right]
292 : * \end{align}
293 : */
294 1 : void newman_penrose_pi(
295 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -1>>*> np_pi,
296 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j,
297 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_k,
298 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
299 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& bondi_q,
300 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_beta,
301 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
302 :
303 : /*!
304 : * \brief Compute the Newman-Penrose spin coefficient
305 : * $\nu$ in the volume, in the conventions of
306 : * \cite Moxon2020gha .
307 : *
308 : * \details The definition of $\nu$ is:
309 : *
310 : * \begin{align}
311 : * \nu = \bar{m}^\mu n^\nu \nabla_\nu n_\mu .
312 : * \end{align}
313 : *
314 : * It has a spin weight of -1. This gives the expression
315 : *
316 : * \begin{align}
317 : * \nu = \frac{e^{-2\beta}}{2} \left[
318 : * \frac{\bar{J}\eth W}{\sqrt{1+K}}
319 : * - \sqrt{1+K} \bar{\eth}W
320 : * \right]
321 : * \end{align}
322 : */
323 1 : void newman_penrose_nu(
324 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -1>>*> np_nu,
325 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j,
326 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_k,
327 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_w,
328 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& exp_2_beta);
329 :
330 : /*!
331 : * \brief Compute the Newman-Penrose spin coefficient
332 : * $\mu$ in the volume, in the conventions of
333 : * \cite Moxon2020gha .
334 : *
335 : * \details The definition of $\mu$ is:
336 : *
337 : * \begin{align}
338 : * \mu = \bar{m}^\mu m^\nu \nabla_\nu n_\mu .
339 : * \end{align}
340 : *
341 : * It has a spin weight of 0. This gives the expression
342 : *
343 : * \begin{align}
344 : * \mu = \frac{e^{-2\beta}}{2\sqrt{2}} \left[
345 : * \eth\bar{U} + \bar{\eth}U - \frac{1-y}{R} - 2W
346 : * \right]
347 : * \end{align}
348 : */
349 1 : void newman_penrose_mu(
350 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> np_mu,
351 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
352 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_w,
353 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& ethbar_u,
354 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& exp_2_beta,
355 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
356 :
357 : /*!
358 : * \brief Compute the Newman-Penrose spin coefficient
359 : * $\lambda$ in the volume, in the conventions of
360 : * \cite Moxon2020gha .
361 : *
362 : * \details The definition of $\lambda$ is:
363 : *
364 : * \begin{align}
365 : * \lambda = \bar{m}^\mu \bar{m}^\nu \nabla_\nu n_\mu .
366 : * \end{align}
367 : *
368 : * It has a spin weight of -2. This gives the expression
369 : *
370 : * \begin{align}
371 : * \lambda = \frac{e^{-2\beta}}{4\sqrt{2}} \Bigg\{ &
372 : * \left[\frac{1-y}{R}+2W\right] \frac{1-y}{2(1+K)}
373 : * \left[ \frac{\bar{J}^2\partial_y J - \partial_y \bar{J}}{K} -
374 : * (2+K) \partial_y\bar{J} \right] \\ \nonumber
375 : * &{}+ 2(1+K)\bar{\eth}\bar{U} + \frac{\bar{I}}{K}
376 : * +\left[ \bar{I} +2\bar{J}(\bar\eth U - \eth\bar U) \right]
377 : * - \frac{\bar{J}^2}{K(1+K)}(I + 2K\eth U)
378 : * \Bigg\}
379 : * \end{align}
380 : *
381 : * where we have defined the temporary quantity
382 : *
383 : * \begin{align}
384 : * I = 2H+U\bar\eth{J}+\bar{U}\eth J
385 : * \end{align}
386 : *
387 : */
388 1 : void newman_penrose_lambda(
389 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -2>>*> np_lambda,
390 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j,
391 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_j,
392 : const Scalar<SpinWeighted<ComplexDataVector, 3>>& eth_j,
393 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& ethbar_j,
394 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_k,
395 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_h,
396 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
397 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& bondi_u,
398 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& eth_u,
399 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& ethbar_u,
400 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_w,
401 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& exp_2_beta,
402 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
403 :
404 : namespace Tags {
405 : /*!
406 : * \brief Compute tag for $\alpha^{SW}$ in the volume.
407 : *
408 : * \details See documentation of `newman_penrose_alpha()` for definition.
409 : */
410 1 : struct NewmanPenroseAlphaCompute : Tags::NewmanPenroseAlpha, db::ComputeTag {
411 0 : using base = Tags::NewmanPenroseAlpha;
412 0 : using return_type = typename base::type;
413 0 : using argument_tags =
414 : tmpl::list<Tags::BondiJ,
415 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
416 : Spectral::Swsh::Tags::Eth>,
417 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
418 : Spectral::Swsh::Tags::Ethbar>,
419 : Tags::BondiK, Tags::BondiR, Tags::BondiQ,
420 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
421 : Spectral::Swsh::Tags::Eth>,
422 : Tags::OneMinusY>;
423 :
424 0 : static constexpr auto function = static_cast<void (*)(
425 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -1>>*>,
426 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
427 : const Scalar<SpinWeighted<ComplexDataVector, 3>>&,
428 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
429 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
430 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
431 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
432 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
433 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
434 : &newman_penrose_alpha);
435 : };
436 :
437 : /*!
438 : * \brief Compute tag for $\beta_{NP}^{SW}$ in the volume.
439 : *
440 : * \details See documentation of `newman_penrose_beta()` for definition.
441 : */
442 1 : struct NewmanPenroseBetaCompute : Tags::NewmanPenroseBeta, db::ComputeTag {
443 0 : using base = Tags::NewmanPenroseBeta;
444 0 : using return_type = typename base::type;
445 0 : using argument_tags =
446 : tmpl::list<Tags::BondiJ,
447 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
448 : Spectral::Swsh::Tags::Eth>,
449 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
450 : Spectral::Swsh::Tags::Ethbar>,
451 : Tags::BondiK, Tags::BondiR, Tags::BondiQ,
452 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
453 : Spectral::Swsh::Tags::Eth>,
454 : Tags::OneMinusY>;
455 :
456 0 : static constexpr auto function = static_cast<void (*)(
457 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, +1>>*>,
458 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
459 : const Scalar<SpinWeighted<ComplexDataVector, 3>>&,
460 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
461 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
462 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
463 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
464 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
465 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
466 : &newman_penrose_beta);
467 : };
468 :
469 : /*!
470 : * \brief Compute tag for $\gamma^{SW}$ in the volume.
471 : *
472 : * \details See documentation of `newman_penrose_gamma()` for definition.
473 : */
474 1 : struct NewmanPenroseGammaCompute : Tags::NewmanPenroseGamma, db::ComputeTag {
475 0 : using base = Tags::NewmanPenroseGamma;
476 0 : using return_type = typename base::type;
477 0 : using argument_tags =
478 : tmpl::list<Tags::BondiJ, Tags::Dy<Tags::BondiJ>,
479 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
480 : Spectral::Swsh::Tags::Eth>,
481 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
482 : Spectral::Swsh::Tags::Ethbar>,
483 : Tags::BondiK, Tags::BondiH, Tags::BondiR,
484 : Tags::BondiU,
485 : Spectral::Swsh::Tags::Derivative<Tags::BondiU,
486 : Spectral::Swsh::Tags::Eth>,
487 : Spectral::Swsh::Tags::Derivative<Tags::BondiU,
488 : Spectral::Swsh::Tags::Ethbar>,
489 : Tags::BondiW, Tags::Dy<Tags::BondiW>,
490 : Tags::Exp2Beta, Tags::OneMinusY>;
491 :
492 0 : static constexpr auto function = static_cast<void (*)(
493 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>,
494 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
495 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
496 : const Scalar<SpinWeighted<ComplexDataVector, 3>>&,
497 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
498 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
499 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
500 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
501 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
502 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
503 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
504 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
505 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
506 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
507 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
508 : &newman_penrose_gamma);
509 : };
510 :
511 : /*!
512 : * \brief Compute tag for $\epsilon^{SW}$ in the volume.
513 : *
514 : * \details See documentation of `newman_penrose_epsilon()` for definition.
515 : */
516 1 : struct NewmanPenroseEpsilonCompute :
517 : Tags::NewmanPenroseEpsilon, db::ComputeTag {
518 0 : using base = Tags::NewmanPenroseEpsilon;
519 0 : using return_type = typename base::type;
520 0 : using argument_tags =
521 : tmpl::list<Tags::BondiJ, Tags::Dy<Tags::BondiJ>,
522 : Tags::BondiK, Tags::BondiR,
523 : Tags::Dy<Tags::BondiBeta>, Tags::OneMinusY>;
524 :
525 0 : static constexpr auto function = static_cast<void (*)(
526 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>,
527 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
528 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
529 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
530 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
531 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
532 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
533 : &newman_penrose_epsilon);
534 : };
535 :
536 : // We do not implement a compute tag for NewmanPenroseKappa, since it vanishes
537 :
538 : /*!
539 : * \brief Compute tag for $\tau$ in the volume.
540 : *
541 : * \details See documentation of `newman_penrose_tau()` for definition.
542 : */
543 1 : struct NewmanPenroseTauCompute : Tags::NewmanPenroseTau, db::ComputeTag {
544 0 : using base = Tags::NewmanPenroseTau;
545 0 : using return_type = typename base::type;
546 0 : using argument_tags =
547 : tmpl::list<Tags::BondiJ, Tags::BondiK,
548 : Tags::BondiR, Tags::BondiQ,
549 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
550 : Spectral::Swsh::Tags::Eth>,
551 : Tags::OneMinusY>;
552 :
553 0 : static constexpr auto function = static_cast<void (*)(
554 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, +1>>*>,
555 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
556 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
557 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
558 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
559 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
560 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
561 : &newman_penrose_tau);
562 : };
563 :
564 : /*!
565 : * \brief Compute tag for $\sigma$ in the volume.
566 : *
567 : * \details See documentation of `newman_penrose_sigma()` for definition.
568 : */
569 1 : struct NewmanPenroseSigmaCompute : Tags::NewmanPenroseSigma, db::ComputeTag {
570 0 : using base = Tags::NewmanPenroseSigma;
571 0 : using return_type = typename base::type;
572 0 : using argument_tags =
573 : tmpl::list<Tags::BondiJ, Tags::Dy<Tags::BondiJ>,
574 : Tags::BondiK, Tags::BondiR, Tags::OneMinusY>;
575 :
576 0 : static constexpr auto function = static_cast<void (*)(
577 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, +2>>*>,
578 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
579 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
580 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
581 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
582 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
583 : &newman_penrose_sigma);
584 : };
585 :
586 : /*!
587 : * \brief Compute tag for $\rho$ in the volume.
588 : *
589 : * \details See documentation of `newman_penrose_rho()` for definition.
590 : */
591 1 : struct NewmanPenroseRhoCompute : Tags::NewmanPenroseRho, db::ComputeTag {
592 0 : using base = Tags::NewmanPenroseRho;
593 0 : using return_type = typename base::type;
594 0 : using argument_tags = tmpl::list<Tags::BondiR, Tags::OneMinusY>;
595 :
596 0 : static constexpr auto function = static_cast<void (*)(
597 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>,
598 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
599 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
600 : &newman_penrose_rho);
601 : };
602 :
603 : /*!
604 : * \brief Compute tag for $\pi$ in the volume.
605 : *
606 : * \details See documentation of `newman_penrose_pi()` for definition.
607 : */
608 1 : struct NewmanPenrosePiCompute : Tags::NewmanPenrosePi, db::ComputeTag {
609 0 : using base = Tags::NewmanPenrosePi;
610 0 : using return_type = typename base::type;
611 0 : using argument_tags =
612 : tmpl::list<Tags::BondiJ, Tags::BondiK,
613 : Tags::BondiR, Tags::BondiQ,
614 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
615 : Spectral::Swsh::Tags::Eth>,
616 : Tags::OneMinusY>;
617 :
618 0 : static constexpr auto function = static_cast<void (*)(
619 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -1>>*>,
620 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
621 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
622 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
623 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
624 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
625 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
626 : &newman_penrose_pi);
627 : };
628 :
629 : /*!
630 : * \brief Compute tag for $\nu$ in the volume.
631 : *
632 : * \details See documentation of `newman_penrose_nu()` for definition.
633 : */
634 1 : struct NewmanPenroseNuCompute : Tags::NewmanPenroseNu, db::ComputeTag {
635 0 : using base = Tags::NewmanPenroseNu;
636 0 : using return_type = typename base::type;
637 0 : using argument_tags =
638 : tmpl::list<Tags::BondiJ, Tags::BondiK,
639 : Spectral::Swsh::Tags::Derivative<Tags::BondiW,
640 : Spectral::Swsh::Tags::Eth>,
641 : Tags::Exp2Beta>;
642 :
643 0 : static constexpr auto function = static_cast<void (*)(
644 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -1>>*>,
645 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
646 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
647 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
648 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
649 : &newman_penrose_nu);
650 : };
651 :
652 : /*!
653 : * \brief Compute tag for $\mu$ in the volume.
654 : *
655 : * \details See documentation of `newman_penrose_mu()` for definition.
656 : */
657 1 : struct NewmanPenroseMuCompute : Tags::NewmanPenroseMu, db::ComputeTag {
658 0 : using base = Tags::NewmanPenroseMu;
659 0 : using return_type = typename base::type;
660 0 : using argument_tags =
661 : tmpl::list<Tags::BondiR, Tags::BondiW,
662 : Spectral::Swsh::Tags::Derivative<Tags::BondiU,
663 : Spectral::Swsh::Tags::Ethbar>,
664 : Tags::Exp2Beta, Tags::OneMinusY>;
665 :
666 0 : static constexpr auto function = static_cast<void (*)(
667 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>,
668 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
669 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
670 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
671 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
672 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
673 : &newman_penrose_mu);
674 : };
675 :
676 : /*!
677 : * \brief Compute tag for $\lambda$ in the volume.
678 : *
679 : * \details See documentation of `newman_penrose_lambda()` for definition.
680 : */
681 1 : struct NewmanPenroseLambdaCompute : Tags::NewmanPenroseLambda, db::ComputeTag {
682 0 : using base = Tags::NewmanPenroseLambda;
683 0 : using return_type = typename base::type;
684 0 : using argument_tags =
685 : tmpl::list<Tags::BondiJ, Tags::Dy<Tags::BondiJ>,
686 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
687 : Spectral::Swsh::Tags::Eth>,
688 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
689 : Spectral::Swsh::Tags::Ethbar>,
690 : Tags::BondiK, Tags::BondiH,
691 : Tags::BondiR, Tags::BondiU,
692 : Spectral::Swsh::Tags::Derivative<Tags::BondiU,
693 : Spectral::Swsh::Tags::Eth>,
694 : Spectral::Swsh::Tags::Derivative<Tags::BondiU,
695 : Spectral::Swsh::Tags::Ethbar>,
696 : Tags::BondiW,
697 : Tags::Exp2Beta, Tags::OneMinusY>;
698 :
699 0 : static constexpr auto function = static_cast<void (*)(
700 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -2>>*>,
701 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
702 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
703 : const Scalar<SpinWeighted<ComplexDataVector, 3>>&,
704 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
705 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
706 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
707 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
708 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
709 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
710 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
711 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
712 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
713 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
714 : &newman_penrose_lambda);
715 : };
716 :
717 : } // namespace Tags
718 :
719 : /*!
720 : * \brief Compute the Weyl scalar \f$\Psi_0\f$ in the volume according to a
721 : * standard set of Newman-Penrose vectors.
722 : *
723 : * \details The Bondi forms of the Newman-Penrose vectors that are needed for
724 : * \f$\Psi_0\f$ are:
725 : *
726 : * \f{align}{
727 : * \mathbf{l} &= \partial_r / \sqrt{2}\\
728 : * \mathbf{m} &= \frac{-1}{2 r} \left(\sqrt{1 + K} q^A \partial_A -
729 : * \frac{J}{\sqrt{1 + K}}\bar{q}^A \partial_A \right)
730 : * \f}
731 : *
732 : * Then, we may compute \f$\Psi_0 = l^\alpha m^\beta l^\mu m^\nu C_{\alpha
733 : * \beta \mu \nu}\f$ from the Bondi system, giving
734 : *
735 : * \f{align*}{
736 : * \Psi_0 = \frac{(1 - y)^4}{16 r^2 K}
737 : * \bigg[& \partial_y \beta \left((1 + K) (\partial_y J)
738 : * - \frac{J^2 \partial_y \bar J}{1 + K}\right)
739 : * - \frac{1}{2} (1 + K) (\partial_y^2 J)
740 : * + \frac{J^2 \partial_y^2 \bar J}{2(K + 1)}\\
741 : * & + \frac{1}{K^2} \left(- \frac{1}{4} J \left(\bar{J}^2 \left(\partial_y
742 : * J\right)^2 + J^2 \left(\partial_y \bar J\right)^2\right)
743 : * + \frac{1 + K^2}{2} J (\partial_y J) (\partial_y \bar J)
744 : * \right)\bigg].
745 : * \f}
746 : */
747 : template <>
748 1 : struct VolumeWeyl<Tags::Psi0> {
749 0 : using return_tags = tmpl::list<Tags::Psi0>;
750 0 : using argument_tags = tmpl::list<Tags::BondiJ, Tags::Dy<Tags::BondiJ>,
751 : Tags::Dy<Tags::Dy<Tags::BondiJ>>,
752 : Tags::BondiK, Tags::BondiR, Tags::OneMinusY>;
753 0 : static void apply(
754 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*> psi_0,
755 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j,
756 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_j,
757 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_dy_j,
758 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_k,
759 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
760 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
761 : };
762 :
763 : namespace Tags {
764 : /*!
765 : * \brief Compute tag for $\Psi_0$ in the volume.
766 : *
767 : * \details Uses `apply` function from `VolumeWeyl<Tags::Psi0>` for the
768 : * computation.
769 : */
770 1 : struct Psi0Compute : Tags::Psi0, db::ComputeTag {
771 0 : using base = Tags::Psi0;
772 0 : using return_type = typename base::type;
773 0 : using argument_tags = typename VolumeWeyl<Tags::Psi0>::argument_tags;
774 :
775 0 : static constexpr auto function = static_cast<void (*)(
776 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>,
777 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
778 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
779 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
780 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
781 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
782 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
783 : &VolumeWeyl<Tags::Psi0>::apply);
784 : };
785 : } // namespace Tags
786 :
787 : /*!
788 : * \brief Compute the Weyl scalar \f$\Psi_1\f$ in the volume according to the
789 : * standard set of Newman-Penrose vectors.
790 : *
791 : * \details Our convention is \f$\Psi_1 =
792 : * l^\alpha n^\beta l^\mu m^\nu C_{\alpha
793 : * \beta \mu \nu}\f$.
794 : *
795 : * \f{align*}{
796 : * \Psi_1 =
797 : * &\frac{(1-y)^2}{\sqrt{128} \sqrt{1 + K} R^2}\Bigg\{
798 : * J(\bar{\eth }\beta + \tfrac{1}{2} \bar{Q})
799 : * - (1 + K) (\eth \beta + \tfrac{1}{2} Q) \\
800 : * &+(1-y)\Bigg[
801 : * (1 + K)\eth\partial_{y}\beta - J\bar{\eth }\partial_{y}\beta
802 : * + \left(- J \frac{\bar{\eth} R}{R} + (1 + K) \frac{\eth R}{R}\right)
803 : * \partial_{y}\beta \\
804 : * &\quad + \frac{1}{4K}\Bigg(
805 : * J\left\{
806 : * -2 \partial_{y}\bar{Q} + \partial_{y}\bar{J} [2 (\eth\beta + \tfrac{1}{2}Q) +
807 : * J(\bar{\eth}\beta + \tfrac{1}{2} \bar{Q})]
808 : * \right\}\\
809 : * &\qquad +(1+K)\Big\{
810 : * 2 (\partial_{y}Q + J \partial_{y}\bar{Q}) + (\bar{J} \partial_{y}J - J
811 : * \partial_{y}\bar{J}) (\eth\beta + \tfrac{1}{2} Q) \\
812 : * &\qquad\quad - (1+K)
813 : * [2 \partial_{y}Q + \partial _{y}J (\bar{\eth }\beta + \tfrac{1}{2} \bar{Q})]
814 : * \Big\}\Bigg)\Bigg]\Bigg\}
815 : * \f}
816 : */
817 : template <>
818 1 : struct VolumeWeyl<Tags::Psi1> {
819 0 : using return_tags = tmpl::list<Tags::Psi1>;
820 0 : using argument_tags =
821 : tmpl::list<Tags::BondiJ, Tags::Dy<Tags::BondiJ>,
822 : Tags::BondiK, Tags::BondiQ,
823 : Tags::Dy<Tags::BondiQ>, Tags::BondiR, Tags::EthRDividedByR,
824 : Tags::Dy<Tags::BondiBeta>,
825 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
826 : Spectral::Swsh::Tags::Eth>,
827 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::BondiBeta>,
828 : Spectral::Swsh::Tags::Eth>,
829 : Tags::OneMinusY>;
830 0 : static void apply(
831 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*> psi_1,
832 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j,
833 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_j,
834 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_k,
835 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& bondi_q,
836 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& dy_q,
837 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
838 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_r_divided_by_r,
839 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& dy_beta,
840 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_beta,
841 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_dy_beta,
842 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
843 : };
844 :
845 : namespace Tags {
846 : /*!
847 : * \brief Compute tag for $\Psi_1$ in the volume.
848 : *
849 : * \details Uses `apply` function from `VolumeWeyl<Tags::Psi1>` for the
850 : * computation.
851 : */
852 1 : struct Psi1Compute : Tags::Psi1, db::ComputeTag {
853 0 : using base = Tags::Psi1;
854 0 : using return_type = typename base::type;
855 0 : using argument_tags = typename VolumeWeyl<Tags::Psi1>::argument_tags;
856 :
857 0 : static constexpr auto function = static_cast<void (*)(
858 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*>,
859 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
860 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
861 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
862 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
863 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
864 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
865 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
866 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
867 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
868 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
869 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
870 : &VolumeWeyl<Tags::Psi1>::apply);
871 : };
872 : } // namespace Tags
873 :
874 : /*!
875 : * \brief Compute the Weyl scalar $\Psi_2$ in the volume according to the
876 : * standard set of Newman-Penrose vectors.
877 : *
878 : * \details Our convention is $\Psi_2 =
879 : * l^\alpha m^\beta \bar{m}^\mu n^\nu
880 : * C_{\alpha \beta \mu \nu}$.
881 : *
882 : * \begin{align}
883 : * \Psi_2 = {}&\frac{1-y}{4 R} \left[ \sqrt{2}(1-y)\partial_y \mu +
884 : * \sqrt{1+K}\eth\pi - \frac{J}{\sqrt{1+K}}\bar{\eth}\pi\right]
885 : * \nonumber \\
886 : * & {}+ (\epsilon^{SW}+\bar{\epsilon}^{SW}-\bar{\rho})\mu +
887 : * (\bar{\alpha}^{SW}-\beta^{SW}_{NP}-\bar{\pi})\pi
888 : * - \sigma\lambda + \nu\kappa
889 : * \end{align}
890 : *
891 : * In our choice of tetrad, $\kappa=0$, so the final term is omitted.
892 : */
893 : template <>
894 1 : struct VolumeWeyl<Tags::Psi2> {
895 0 : using return_tags = tmpl::list<Tags::Psi2>;
896 0 : using argument_tags =
897 : tmpl::list<Tags::BondiJ,
898 : Tags::BondiK,
899 : Tags::BondiR,
900 : Tags::Dy<Tags::NewmanPenroseMu>,
901 : Spectral::Swsh::Tags::Derivative<Tags::NewmanPenrosePi,
902 : Spectral::Swsh::Tags::Eth>,
903 : Spectral::Swsh::Tags::Derivative<Tags::NewmanPenrosePi,
904 : Spectral::Swsh::Tags::Ethbar>,
905 : Tags::NewmanPenroseAlpha,
906 : Tags::NewmanPenroseBeta,
907 : Tags::NewmanPenroseEpsilon,
908 : Tags::NewmanPenroseSigma,
909 : Tags::NewmanPenroseRho,
910 : Tags::NewmanPenrosePi,
911 : Tags::NewmanPenroseMu,
912 : Tags::NewmanPenroseLambda,
913 : Tags::OneMinusY>;
914 0 : static void apply(
915 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> psi_2,
916 : const Scalar<SpinWeighted<ComplexDataVector, +2>>& bondi_j,
917 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_k,
918 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
919 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& dy_mu,
920 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& eth_pi,
921 : const Scalar<SpinWeighted<ComplexDataVector, -2>>& ethbar_pi,
922 : const Scalar<SpinWeighted<ComplexDataVector, -1>>& np_alpha,
923 : const Scalar<SpinWeighted<ComplexDataVector, +1>>& np_beta,
924 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& np_epsilon,
925 : const Scalar<SpinWeighted<ComplexDataVector, +2>>& np_sigma,
926 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& np_rho,
927 : const Scalar<SpinWeighted<ComplexDataVector, -1>>& np_pi,
928 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& np_mu,
929 : const Scalar<SpinWeighted<ComplexDataVector, -2>>& np_lambda,
930 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
931 : };
932 :
933 : namespace Tags {
934 : /*!
935 : * \brief Compute tag for $\Psi_2$ in the volume.
936 : *
937 : * \details Uses `VolumeWeyl<Tags::Psi2>::apply()` for the
938 : * computation.
939 : */
940 1 : struct Psi2Compute : Tags::Psi2, db::ComputeTag {
941 0 : using base = Tags::Psi2;
942 0 : using return_type = typename base::type;
943 0 : using argument_tags = typename VolumeWeyl<Tags::Psi2>::argument_tags;
944 :
945 0 : static constexpr auto function = static_cast<void (*)(
946 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>,
947 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
948 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
949 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
950 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
951 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
952 : const Scalar<SpinWeighted<ComplexDataVector, -2>>&,
953 : const Scalar<SpinWeighted<ComplexDataVector, -1>>&,
954 : const Scalar<SpinWeighted<ComplexDataVector, +1>>&,
955 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
956 : const Scalar<SpinWeighted<ComplexDataVector, +2>>&,
957 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
958 : const Scalar<SpinWeighted<ComplexDataVector, -1>>&,
959 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
960 : const Scalar<SpinWeighted<ComplexDataVector, -2>>&,
961 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
962 : &VolumeWeyl<Tags::Psi2>::apply);
963 : };
964 : } // namespace Tags
965 :
966 : /*!
967 : * \brief Transform `Tags::BondiJ` from the partially flat coordinates
968 : * to the Cauchy coordinates.
969 : *
970 : * \details The spin-2 quantity \f$\hat J\f$ transforms as
971 : * \f{align*}{
972 : * J = \frac{1}{4 \omega^2} (\bar d^2 \hat J + c^2 \bar{\hat J}
973 : * + 2 c \bar d \hat K )
974 : * \f}
975 : *
976 : * with
977 : * \f{align*}{
978 : * \hat K = \sqrt{1+\hat J \bar{\hat J}}
979 : * \f}
980 : */
981 1 : struct TransformBondiJToCauchyCoords {
982 0 : using return_tags = tmpl::list<Tags::BondiJCauchyView>;
983 0 : using argument_tags = tmpl::list<
984 : Tags::CauchyGaugeC, Tags::BondiJ, Tags::CauchyGaugeD,
985 : Tags::CauchyGaugeOmega,
986 : Spectral::Swsh::Tags::SwshInterpolator<Tags::PartiallyFlatAngularCoords>,
987 : Tags::LMax>;
988 0 : static void apply(
989 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>
990 : cauchy_view_volume_j,
991 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& gauge_cauchy_c,
992 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& volume_j,
993 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& gauge_cauchy_d,
994 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega_cauchy,
995 : const Spectral::Swsh::SwshInterpolator& interpolator,
996 : const size_t l_max);
997 : };
998 :
999 : /*!
1000 : * \brief Compute the Weyl scalar \f$\Psi_0\f$ in the volume for the purpose
1001 : * of CCM, the quantity is in the Cauchy coordinates.
1002 : *
1003 : * \details The Weyl scalar \f$\Psi_0\f$ is given by:
1004 : *
1005 : * \f{align*}{
1006 : * \Psi_0 = \frac{(1 - y)^4}{16 r^2 K}
1007 : * \bigg[& \partial_y \beta \left((1 + K) (\partial_y J)
1008 : * - \frac{J^2 \partial_y \bar J}{1 + K}\right)
1009 : * - \frac{1}{2} (1 + K) (\partial_y^2 J)
1010 : * + \frac{J^2 \partial_y^2 \bar J}{2(K + 1)}\\
1011 : * & + \frac{1}{K^2} \left(- \frac{1}{4} J \left(\bar{J}^2 \left(\partial_y
1012 : * J\right)^2 + J^2 \left(\partial_y \bar J\right)^2\right)
1013 : * + \frac{1 + K^2}{2} J (\partial_y J) (\partial_y \bar J)
1014 : * \right)\bigg].
1015 : * \f}
1016 : *
1017 : * The quantities above are all in the Cauchy coordinates, where \f$K\f$ is
1018 : * updated from \f$J\f$ and \f$\bar J\f$, \f$(1-y)\f$ is invariant under
1019 : * the coordinate transformation. \f$r\f$ transforms as
1020 : *
1021 : * \f{align*}{
1022 : * r = \omega \hat r
1023 : * \f}
1024 : */
1025 : template <>
1026 1 : struct VolumeWeyl<Tags::Psi0Match> {
1027 0 : using return_tags = tmpl::list<Tags::Psi0Match>;
1028 0 : using argument_tags =
1029 : tmpl::list<Tags::BondiJCauchyView, Tags::Dy<Tags::BondiJCauchyView>,
1030 : Tags::Dy<Tags::Dy<Tags::BondiJCauchyView>>,
1031 : Tags::BoundaryValue<Tags::BondiR>, Tags::OneMinusY,
1032 : Tags::LMax>;
1033 0 : static void apply(
1034 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*> psi_0,
1035 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j_cauchy,
1036 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_j_cauchy,
1037 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_dy_j_cauchy,
1038 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r_cauchy,
1039 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y,
1040 : const size_t l_max);
1041 : };
1042 :
1043 : /*!
1044 : * \brief Compute the Weyl scalar \f$\Psi_0\f$ and its radial derivative
1045 : * \f$\partial_\lambda \Psi_0\f$ on the inner boundary of CCE domain.
1046 : * The quantities are in the Cauchy coordinates.
1047 : *
1048 : * \details The radial derivative of the Weyl scalar \f$\partial_\lambda
1049 : * \Psi_0\f$ is given by
1050 : *
1051 : * \f{align*}{
1052 : * \partial_\lambda \Psi_0 = \frac{(1-y)^2}{2r}e^{-2\beta}
1053 : * \partial_y \Psi_0
1054 : * \f}
1055 : *
1056 : * Note that \f$(1-y)\f$, \f$r\f$, and \f$\beta\f$ are in the Cauchy
1057 : * coordinates, where \f$(1-y)\f$ is invariant under the coordinate
1058 : * transformation, while \f$r\f$ and \f$\beta\f$ transform as
1059 : *
1060 : * \f{align*}{
1061 : * &r = \omega \hat r
1062 : * & \beta = \hat \beta - \frac{1}{2} \log \omega
1063 : * \f}
1064 : */
1065 1 : struct InnerBoundaryWeyl {
1066 0 : using return_tags =
1067 : tmpl::list<Tags::BoundaryValue<Tags::Psi0Match>,
1068 : Tags::BoundaryValue<Tags::Dlambda<Tags::Psi0Match>>>;
1069 0 : using argument_tags =
1070 : tmpl::list<Tags::Psi0Match, Tags::Dy<Tags::Psi0Match>, Tags::OneMinusY,
1071 : Tags::BoundaryValue<Tags::BondiR>,
1072 : Tags::BoundaryValue<Tags::BondiBeta>, Tags::LMax>;
1073 0 : static void apply(
1074 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*> psi_0_boundary,
1075 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>
1076 : dlambda_psi_0_boundary,
1077 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& psi_0,
1078 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_psi_0,
1079 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y,
1080 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r_cauchy,
1081 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_beta_cauchy,
1082 : const size_t l_max);
1083 : };
1084 : } // namespace Cce
|