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