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 : namespace Tags {
402 : /*!
403 : * \brief Compute tag for $\alpha^{SW}$ in the volume.
404 : *
405 : * \details See documentation of `newman_penrose_alpha()` for definition.
406 : */
407 1 : struct NewmanPenroseAlphaCompute : Tags::NewmanPenroseAlpha, db::ComputeTag {
408 0 : using base = Tags::NewmanPenroseAlpha;
409 0 : using return_type = typename base::type;
410 0 : using argument_tags =
411 : tmpl::list<Tags::BondiJ,
412 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
413 : Spectral::Swsh::Tags::Eth>,
414 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
415 : Spectral::Swsh::Tags::Ethbar>,
416 : Tags::BondiK, Tags::BondiR, Tags::BondiQ,
417 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
418 : Spectral::Swsh::Tags::Eth>,
419 : Tags::OneMinusY>;
420 :
421 0 : static constexpr auto function = static_cast<void (*)(
422 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -1>>*>,
423 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
424 : const Scalar<SpinWeighted<ComplexDataVector, 3>>&,
425 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
426 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
427 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
428 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
429 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
430 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
431 : &newman_penrose_alpha);
432 : };
433 :
434 : /*!
435 : * \brief Compute tag for $\beta_{NP}^{SW}$ in the volume.
436 : *
437 : * \details See documentation of `newman_penrose_beta()` for definition.
438 : */
439 1 : struct NewmanPenroseBetaCompute : Tags::NewmanPenroseBeta, db::ComputeTag {
440 0 : using base = Tags::NewmanPenroseBeta;
441 0 : using return_type = typename base::type;
442 0 : using argument_tags =
443 : tmpl::list<Tags::BondiJ,
444 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
445 : Spectral::Swsh::Tags::Eth>,
446 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
447 : Spectral::Swsh::Tags::Ethbar>,
448 : Tags::BondiK, Tags::BondiR, Tags::BondiQ,
449 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
450 : Spectral::Swsh::Tags::Eth>,
451 : Tags::OneMinusY>;
452 :
453 0 : static constexpr auto function = static_cast<void (*)(
454 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, +1>>*>,
455 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
456 : const Scalar<SpinWeighted<ComplexDataVector, 3>>&,
457 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
458 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
459 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
460 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
461 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
462 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
463 : &newman_penrose_beta);
464 : };
465 :
466 : /*!
467 : * \brief Compute tag for $\gamma^{SW}$ in the volume.
468 : *
469 : * \details See documentation of `newman_penrose_gamma()` for definition.
470 : */
471 1 : struct NewmanPenroseGammaCompute : Tags::NewmanPenroseGamma, db::ComputeTag {
472 0 : using base = Tags::NewmanPenroseGamma;
473 0 : using return_type = typename base::type;
474 0 : using argument_tags =
475 : tmpl::list<Tags::BondiJ, Tags::Dy<Tags::BondiJ>,
476 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
477 : Spectral::Swsh::Tags::Eth>,
478 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
479 : Spectral::Swsh::Tags::Ethbar>,
480 : Tags::BondiK, Tags::BondiH, Tags::BondiR,
481 : Tags::BondiU,
482 : Spectral::Swsh::Tags::Derivative<Tags::BondiU,
483 : Spectral::Swsh::Tags::Eth>,
484 : Spectral::Swsh::Tags::Derivative<Tags::BondiU,
485 : Spectral::Swsh::Tags::Ethbar>,
486 : Tags::BondiW, Tags::Dy<Tags::BondiW>,
487 : Tags::Exp2Beta, Tags::OneMinusY>;
488 :
489 0 : static constexpr auto function = static_cast<void (*)(
490 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>,
491 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
492 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
493 : const Scalar<SpinWeighted<ComplexDataVector, 3>>&,
494 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
495 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
496 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
497 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
498 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
499 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
500 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
501 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
502 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
503 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
504 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
505 : &newman_penrose_gamma);
506 : };
507 :
508 : /*!
509 : * \brief Compute tag for $\epsilon^{SW}$ in the volume.
510 : *
511 : * \details See documentation of `newman_penrose_epsilon()` for definition.
512 : */
513 1 : struct NewmanPenroseEpsilonCompute :
514 : Tags::NewmanPenroseEpsilon, db::ComputeTag {
515 0 : using base = Tags::NewmanPenroseEpsilon;
516 0 : using return_type = typename base::type;
517 0 : using argument_tags =
518 : tmpl::list<Tags::BondiJ, Tags::Dy<Tags::BondiJ>,
519 : Tags::BondiK, Tags::BondiR,
520 : Tags::Dy<Tags::BondiBeta>, Tags::OneMinusY>;
521 :
522 0 : static constexpr auto function = static_cast<void (*)(
523 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>,
524 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
525 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
526 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
527 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
528 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
529 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
530 : &newman_penrose_epsilon);
531 : };
532 :
533 : // We do not implement a compute tag for NewmanPenroseKappa, since it vanishes
534 :
535 : /*!
536 : * \brief Compute tag for $\tau$ in the volume.
537 : *
538 : * \details See documentation of `newman_penrose_tau()` for definition.
539 : */
540 1 : struct NewmanPenroseTauCompute : Tags::NewmanPenroseTau, db::ComputeTag {
541 0 : using base = Tags::NewmanPenroseTau;
542 0 : using return_type = typename base::type;
543 0 : using argument_tags =
544 : tmpl::list<Tags::BondiJ, Tags::BondiK,
545 : Tags::BondiR, Tags::BondiQ,
546 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
547 : Spectral::Swsh::Tags::Eth>,
548 : Tags::OneMinusY>;
549 :
550 0 : static constexpr auto function = static_cast<void (*)(
551 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, +1>>*>,
552 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
553 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
554 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
555 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
556 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
557 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
558 : &newman_penrose_tau);
559 : };
560 :
561 : /*!
562 : * \brief Compute tag for $\sigma$ in the volume.
563 : *
564 : * \details See documentation of `newman_penrose_sigma()` for definition.
565 : */
566 1 : struct NewmanPenroseSigmaCompute : Tags::NewmanPenroseSigma, db::ComputeTag {
567 0 : using base = Tags::NewmanPenroseSigma;
568 0 : using return_type = typename base::type;
569 0 : using argument_tags =
570 : tmpl::list<Tags::BondiJ, Tags::Dy<Tags::BondiJ>,
571 : Tags::BondiK, Tags::BondiR, Tags::OneMinusY>;
572 :
573 0 : static constexpr auto function = static_cast<void (*)(
574 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, +2>>*>,
575 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
576 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
577 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
578 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
579 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
580 : &newman_penrose_sigma);
581 : };
582 :
583 : /*!
584 : * \brief Compute tag for $\rho$ in the volume.
585 : *
586 : * \details See documentation of `newman_penrose_rho()` for definition.
587 : */
588 1 : struct NewmanPenroseRhoCompute : Tags::NewmanPenroseRho, db::ComputeTag {
589 0 : using base = Tags::NewmanPenroseRho;
590 0 : using return_type = typename base::type;
591 0 : using argument_tags = tmpl::list<Tags::BondiR, Tags::OneMinusY>;
592 :
593 0 : static constexpr auto function = static_cast<void (*)(
594 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>,
595 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
596 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
597 : &newman_penrose_rho);
598 : };
599 :
600 : /*!
601 : * \brief Compute tag for $\pi$ in the volume.
602 : *
603 : * \details See documentation of `newman_penrose_pi()` for definition.
604 : */
605 1 : struct NewmanPenrosePiCompute : Tags::NewmanPenrosePi, db::ComputeTag {
606 0 : using base = Tags::NewmanPenrosePi;
607 0 : using return_type = typename base::type;
608 0 : using argument_tags =
609 : tmpl::list<Tags::BondiJ, Tags::BondiK,
610 : Tags::BondiR, Tags::BondiQ,
611 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
612 : Spectral::Swsh::Tags::Eth>,
613 : Tags::OneMinusY>;
614 :
615 0 : static constexpr auto function = static_cast<void (*)(
616 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -1>>*>,
617 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
618 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
619 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
620 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
621 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
622 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
623 : &newman_penrose_pi);
624 : };
625 :
626 : /*!
627 : * \brief Compute tag for $\nu$ in the volume.
628 : *
629 : * \details See documentation of `newman_penrose_nu()` for definition.
630 : */
631 1 : struct NewmanPenroseNuCompute : Tags::NewmanPenroseNu, db::ComputeTag {
632 0 : using base = Tags::NewmanPenroseNu;
633 0 : using return_type = typename base::type;
634 0 : using argument_tags =
635 : tmpl::list<Tags::BondiJ, Tags::BondiK,
636 : Spectral::Swsh::Tags::Derivative<Tags::BondiW,
637 : Spectral::Swsh::Tags::Eth>,
638 : Tags::Exp2Beta>;
639 :
640 0 : static constexpr auto function = static_cast<void (*)(
641 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -1>>*>,
642 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
643 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
644 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
645 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
646 : &newman_penrose_nu);
647 : };
648 :
649 : /*!
650 : * \brief Compute tag for $\mu$ in the volume.
651 : *
652 : * \details See documentation of `newman_penrose_mu()` for definition.
653 : */
654 1 : struct NewmanPenroseMuCompute : Tags::NewmanPenroseMu, db::ComputeTag {
655 0 : using base = Tags::NewmanPenroseMu;
656 0 : using return_type = typename base::type;
657 0 : using argument_tags =
658 : tmpl::list<Tags::BondiR, Tags::BondiW,
659 : Spectral::Swsh::Tags::Derivative<Tags::BondiU,
660 : Spectral::Swsh::Tags::Ethbar>,
661 : Tags::Exp2Beta, Tags::OneMinusY>;
662 :
663 0 : static constexpr auto function = static_cast<void (*)(
664 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>,
665 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
666 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
667 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
668 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
669 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
670 : &newman_penrose_mu);
671 : };
672 :
673 : /*!
674 : * \brief Compute tag for $\lambda$ in the volume.
675 : *
676 : * \details See documentation of `newman_penrose_lambda()` for definition.
677 : */
678 1 : struct NewmanPenroseLambdaCompute : Tags::NewmanPenroseLambda, db::ComputeTag {
679 0 : using base = Tags::NewmanPenroseLambda;
680 0 : using return_type = typename base::type;
681 0 : using argument_tags =
682 : tmpl::list<Tags::BondiJ, Tags::Dy<Tags::BondiJ>,
683 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
684 : Spectral::Swsh::Tags::Eth>,
685 : Spectral::Swsh::Tags::Derivative<Tags::BondiJ,
686 : Spectral::Swsh::Tags::Ethbar>,
687 : Tags::BondiK, Tags::BondiH,
688 : Tags::BondiR, Tags::BondiU,
689 : Spectral::Swsh::Tags::Derivative<Tags::BondiU,
690 : Spectral::Swsh::Tags::Eth>,
691 : Spectral::Swsh::Tags::Derivative<Tags::BondiU,
692 : Spectral::Swsh::Tags::Ethbar>,
693 : Tags::BondiW,
694 : Tags::Exp2Beta, Tags::OneMinusY>;
695 :
696 0 : static constexpr auto function = static_cast<void (*)(
697 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, -2>>*>,
698 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
699 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
700 : const Scalar<SpinWeighted<ComplexDataVector, 3>>&,
701 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
702 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
703 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
704 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
705 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
706 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
707 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
708 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
709 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
710 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
711 : &newman_penrose_lambda);
712 : };
713 :
714 : } // namespace Tags
715 :
716 : /*!
717 : * \brief Compute the Weyl scalar \f$\Psi_0\f$ in the volume according to a
718 : * standard set of Newman-Penrose vectors.
719 : *
720 : * \details The Bondi forms of the Newman-Penrose vectors that are needed for
721 : * \f$\Psi_0\f$ are:
722 : *
723 : * \f{align}{
724 : * \mathbf{l} &= \partial_r / \sqrt{2}\\
725 : * \mathbf{m} &= \frac{-1}{2 r} \left(\sqrt{1 + K} q^A \partial_A -
726 : * \frac{J}{\sqrt{1 + K}}\bar{q}^A \partial_A \right)
727 : * \f}
728 : *
729 : * Then, we may compute \f$\Psi_0 = l^\alpha m^\beta l^\mu m^\nu C_{\alpha
730 : * \beta \mu \nu}\f$ from the Bondi system, giving
731 : *
732 : * \f{align*}{
733 : * \Psi_0 = \frac{(1 - y)^4}{16 r^2 K}
734 : * \bigg[& \partial_y \beta \left((1 + K) (\partial_y J)
735 : * - \frac{J^2 \partial_y \bar J}{1 + K}\right)
736 : * - \frac{1}{2} (1 + K) (\partial_y^2 J)
737 : * + \frac{J^2 \partial_y^2 \bar J}{2(K + 1)}\\
738 : * & + \frac{1}{K^2} \left(- \frac{1}{4} J \left(\bar{J}^2 \left(\partial_y
739 : * J\right)^2 + J^2 \left(\partial_y \bar J\right)^2\right)
740 : * + \frac{1 + K^2}{2} J (\partial_y J) (\partial_y \bar J)
741 : * \right)\bigg].
742 : * \f}
743 : */
744 : template <>
745 1 : struct VolumeWeyl<Tags::Psi0> {
746 0 : using return_tags = tmpl::list<Tags::Psi0>;
747 0 : using argument_tags = tmpl::list<Tags::BondiJ, Tags::Dy<Tags::BondiJ>,
748 : Tags::Dy<Tags::Dy<Tags::BondiJ>>,
749 : Tags::BondiK, Tags::BondiR, Tags::OneMinusY>;
750 0 : static void apply(
751 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*> psi_0,
752 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j,
753 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_j,
754 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_dy_j,
755 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_k,
756 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
757 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
758 : };
759 :
760 : namespace Tags {
761 : /*!
762 : * \brief Compute tag for $\Psi_0$ in the volume.
763 : *
764 : * \details Uses `apply` function from `VolumeWeyl<Tags::Psi0>` for the
765 : * computation.
766 : */
767 1 : struct Psi0Compute : Tags::Psi0, db::ComputeTag {
768 0 : using base = Tags::Psi0;
769 0 : using return_type = typename base::type;
770 0 : using argument_tags = typename VolumeWeyl<Tags::Psi0>::argument_tags;
771 :
772 0 : static constexpr auto function = static_cast<void (*)(
773 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>,
774 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
775 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
776 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
777 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
778 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
779 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
780 : &VolumeWeyl<Tags::Psi0>::apply);
781 : };
782 : } // namespace Tags
783 :
784 : /*!
785 : * \brief Compute the Weyl scalar \f$\Psi_1\f$ in the volume according to the
786 : * standard set of Newman-Penrose vectors.
787 : *
788 : * \details Our convention is \f$\Psi_1 =
789 : * l^\alpha n^\beta l^\mu m^\nu C_{\alpha
790 : * \beta \mu \nu}\f$.
791 : *
792 : * \f{align*}{
793 : * \Psi_1 =
794 : * &\frac{(1-y)^2}{\sqrt{128} \sqrt{1 + K} R^2}\Bigg\{
795 : * J(\bar{\eth }\beta + \tfrac{1}{2} \bar{Q})
796 : * - (1 + K) (\eth \beta + \tfrac{1}{2} Q) \\
797 : * &+(1-y)\Bigg[
798 : * (1 + K)\eth\partial_{y}\beta - J\bar{\eth }\partial_{y}\beta
799 : * + \left(- J \frac{\bar{\eth} R}{R} + (1 + K) \frac{\eth R}{R}\right)
800 : * \partial_{y}\beta \\
801 : * &\quad + \frac{1}{4K}\Bigg(
802 : * J\left\{
803 : * -2 \partial_{y}\bar{Q} + \partial_{y}\bar{J} [2 (\eth\beta + \tfrac{1}{2}Q) +
804 : * J(\bar{\eth}\beta + \tfrac{1}{2} \bar{Q})]
805 : * \right\}\\
806 : * &\qquad +(1+K)\Big\{
807 : * 2 (\partial_{y}Q + J \partial_{y}\bar{Q}) + (\bar{J} \partial_{y}J - J
808 : * \partial_{y}\bar{J}) (\eth\beta + \tfrac{1}{2} Q) \\
809 : * &\qquad\quad - (1+K)
810 : * [2 \partial_{y}Q + \partial _{y}J (\bar{\eth }\beta + \tfrac{1}{2} \bar{Q})]
811 : * \Big\}\Bigg)\Bigg]\Bigg\}
812 : * \f}
813 : */
814 : template <>
815 1 : struct VolumeWeyl<Tags::Psi1> {
816 0 : using return_tags = tmpl::list<Tags::Psi1>;
817 0 : using argument_tags =
818 : tmpl::list<Tags::BondiJ, Tags::Dy<Tags::BondiJ>,
819 : Tags::BondiK, Tags::BondiQ,
820 : Tags::Dy<Tags::BondiQ>, Tags::BondiR, Tags::EthRDividedByR,
821 : Tags::Dy<Tags::BondiBeta>,
822 : Spectral::Swsh::Tags::Derivative<Tags::BondiBeta,
823 : Spectral::Swsh::Tags::Eth>,
824 : Spectral::Swsh::Tags::Derivative<Tags::Dy<Tags::BondiBeta>,
825 : Spectral::Swsh::Tags::Eth>,
826 : Tags::OneMinusY>;
827 0 : static void apply(
828 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*> psi_1,
829 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j,
830 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_j,
831 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_k,
832 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& bondi_q,
833 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& dy_q,
834 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
835 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_r_divided_by_r,
836 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& dy_beta,
837 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_beta,
838 : const Scalar<SpinWeighted<ComplexDataVector, 1>>& eth_dy_beta,
839 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
840 : };
841 :
842 : namespace Tags {
843 : /*!
844 : * \brief Compute tag for $\Psi_1$ in the volume.
845 : *
846 : * \details Uses `apply` function from `VolumeWeyl<Tags::Psi1>` for the
847 : * computation.
848 : */
849 1 : struct Psi1Compute : Tags::Psi1, db::ComputeTag {
850 0 : using base = Tags::Psi1;
851 0 : using return_type = typename base::type;
852 0 : using argument_tags = typename VolumeWeyl<Tags::Psi1>::argument_tags;
853 :
854 0 : static constexpr auto function = static_cast<void (*)(
855 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*>,
856 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
857 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
858 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
859 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
860 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
861 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
862 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
863 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
864 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
865 : const Scalar<SpinWeighted<ComplexDataVector, 1>>&,
866 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
867 : &VolumeWeyl<Tags::Psi1>::apply);
868 : };
869 : } // namespace Tags
870 :
871 : /*!
872 : * \brief Compute the Weyl scalar $\Psi_2$ in the volume according to the
873 : * standard set of Newman-Penrose vectors.
874 : *
875 : * \details Our convention is $\Psi_2 =
876 : * l^\alpha m^\beta \bar{m}^\mu n^\nu
877 : * C_{\alpha \beta \mu \nu}$.
878 : *
879 : * \begin{align}
880 : * \Psi_2 = {}&\frac{1-y}{4 R} \left[ \sqrt{2}(1-y)\partial_y \mu +
881 : * \sqrt{1+K}\eth\pi - \frac{J}{\sqrt{1+K}}\bar{\eth}\pi\right]
882 : * \nonumber \\
883 : * & {}+ (\epsilon^{SW}+\bar{\epsilon}^{SW}-\bar{\rho})\mu +
884 : * (\bar{\alpha}^{SW}-\beta^{SW}_{NP}-\bar{\pi})\pi
885 : * - \sigma\lambda + \nu\kappa
886 : * \end{align}
887 : *
888 : * In our choice of tetrad, $\kappa=0$, so the final term is omitted.
889 : */
890 : template <>
891 1 : struct VolumeWeyl<Tags::Psi2> {
892 0 : using return_tags = tmpl::list<Tags::Psi2>;
893 0 : using argument_tags =
894 : tmpl::list<Tags::BondiJ,
895 : Tags::BondiK,
896 : Tags::BondiR,
897 : Tags::Dy<Tags::NewmanPenroseMu>,
898 : Spectral::Swsh::Tags::Derivative<Tags::NewmanPenrosePi,
899 : Spectral::Swsh::Tags::Eth>,
900 : Spectral::Swsh::Tags::Derivative<Tags::NewmanPenrosePi,
901 : Spectral::Swsh::Tags::Ethbar>,
902 : Tags::NewmanPenroseAlpha,
903 : Tags::NewmanPenroseBeta,
904 : Tags::NewmanPenroseEpsilon,
905 : Tags::NewmanPenroseSigma,
906 : Tags::NewmanPenroseRho,
907 : Tags::NewmanPenrosePi,
908 : Tags::NewmanPenroseMu,
909 : Tags::NewmanPenroseLambda,
910 : Tags::OneMinusY>;
911 0 : static void apply(
912 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> psi_2,
913 : const Scalar<SpinWeighted<ComplexDataVector, +2>>& bondi_j,
914 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_k,
915 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
916 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& dy_mu,
917 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& eth_pi,
918 : const Scalar<SpinWeighted<ComplexDataVector, -2>>& ethbar_pi,
919 : const Scalar<SpinWeighted<ComplexDataVector, -1>>& np_alpha,
920 : const Scalar<SpinWeighted<ComplexDataVector, +1>>& np_beta,
921 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& np_epsilon,
922 : const Scalar<SpinWeighted<ComplexDataVector, +2>>& np_sigma,
923 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& np_rho,
924 : const Scalar<SpinWeighted<ComplexDataVector, -1>>& np_pi,
925 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& np_mu,
926 : const Scalar<SpinWeighted<ComplexDataVector, -2>>& np_lambda,
927 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
928 : };
929 :
930 : namespace Tags {
931 : /*!
932 : * \brief Compute tag for $\Psi_2$ in the volume.
933 : *
934 : * \details Uses `VolumeWeyl<Tags::Psi2>::apply()` for the
935 : * computation.
936 : */
937 1 : struct Psi2Compute : Tags::Psi2, db::ComputeTag {
938 0 : using base = Tags::Psi2;
939 0 : using return_type = typename base::type;
940 0 : using argument_tags = typename VolumeWeyl<Tags::Psi2>::argument_tags;
941 :
942 0 : static constexpr auto function = static_cast<void (*)(
943 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>,
944 : const Scalar<SpinWeighted<ComplexDataVector, 2>>&,
945 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
946 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
947 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
948 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
949 : const Scalar<SpinWeighted<ComplexDataVector, -2>>&,
950 : const Scalar<SpinWeighted<ComplexDataVector, -1>>&,
951 : const Scalar<SpinWeighted<ComplexDataVector, +1>>&,
952 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
953 : const Scalar<SpinWeighted<ComplexDataVector, +2>>&,
954 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
955 : const Scalar<SpinWeighted<ComplexDataVector, -1>>&,
956 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&,
957 : const Scalar<SpinWeighted<ComplexDataVector, -2>>&,
958 : const Scalar<SpinWeighted<ComplexDataVector, 0>>&)>(
959 : &VolumeWeyl<Tags::Psi2>::apply);
960 : };
961 : } // namespace Tags
962 :
963 : /*!
964 : * \brief Transform `Tags::BondiJ` from the partially flat coordinates
965 : * to the Cauchy coordinates.
966 : *
967 : * \details The spin-2 quantity \f$\hat J\f$ transforms as
968 : * \f{align*}{
969 : * J = \frac{1}{4 \omega^2} (\bar d^2 \hat J + c^2 \bar{\hat J}
970 : * + 2 c \bar d \hat K )
971 : * \f}
972 : *
973 : * with
974 : * \f{align*}{
975 : * \hat K = \sqrt{1+\hat J \bar{\hat J}}
976 : * \f}
977 : */
978 1 : struct TransformBondiJToCauchyCoords {
979 0 : using return_tags = tmpl::list<Tags::BondiJCauchyView>;
980 0 : using argument_tags = tmpl::list<
981 : Tags::CauchyGaugeC, Tags::BondiJ, Tags::CauchyGaugeD,
982 : Tags::CauchyGaugeOmega,
983 : Spectral::Swsh::Tags::SwshInterpolator<Tags::PartiallyFlatAngularCoords>,
984 : Tags::LMax>;
985 0 : static void apply(
986 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>
987 : cauchy_view_volume_j,
988 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& gauge_cauchy_c,
989 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& volume_j,
990 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& gauge_cauchy_d,
991 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega_cauchy,
992 : const Spectral::Swsh::SwshInterpolator& interpolator,
993 : const size_t l_max);
994 : };
995 :
996 : /*!
997 : * \brief Compute the Weyl scalar \f$\Psi_0\f$ in the volume for the purpose
998 : * of CCM, the quantity is in the Cauchy coordinates.
999 : *
1000 : * \details The Weyl scalar \f$\Psi_0\f$ is given by:
1001 : *
1002 : * \f{align*}{
1003 : * \Psi_0 = \frac{(1 - y)^4}{16 r^2 K}
1004 : * \bigg[& \partial_y \beta \left((1 + K) (\partial_y J)
1005 : * - \frac{J^2 \partial_y \bar J}{1 + K}\right)
1006 : * - \frac{1}{2} (1 + K) (\partial_y^2 J)
1007 : * + \frac{J^2 \partial_y^2 \bar J}{2(K + 1)}\\
1008 : * & + \frac{1}{K^2} \left(- \frac{1}{4} J \left(\bar{J}^2 \left(\partial_y
1009 : * J\right)^2 + J^2 \left(\partial_y \bar J\right)^2\right)
1010 : * + \frac{1 + K^2}{2} J (\partial_y J) (\partial_y \bar J)
1011 : * \right)\bigg].
1012 : * \f}
1013 : *
1014 : * The quantities above are all in the Cauchy coordinates, where \f$K\f$ is
1015 : * updated from \f$J\f$ and \f$\bar J\f$, \f$(1-y)\f$ is invariant under
1016 : * the coordinate transformation. \f$r\f$ transforms as
1017 : *
1018 : * \f{align*}{
1019 : * r = \omega \hat r
1020 : * \f}
1021 : */
1022 : template <>
1023 1 : struct VolumeWeyl<Tags::Psi0Match> {
1024 0 : using return_tags = tmpl::list<Tags::Psi0Match>;
1025 0 : using argument_tags =
1026 : tmpl::list<Tags::BondiJCauchyView, Tags::Dy<Tags::BondiJCauchyView>,
1027 : Tags::Dy<Tags::Dy<Tags::BondiJCauchyView>>,
1028 : Tags::BoundaryValue<Tags::BondiR>, Tags::OneMinusY,
1029 : Tags::LMax>;
1030 0 : static void apply(
1031 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*> psi_0,
1032 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j_cauchy,
1033 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_j_cauchy,
1034 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_dy_j_cauchy,
1035 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r_cauchy,
1036 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y,
1037 : const size_t l_max);
1038 : };
1039 :
1040 : /*!
1041 : * \brief Compute the Weyl scalar \f$\Psi_0\f$ and its radial derivative
1042 : * \f$\partial_\lambda \Psi_0\f$ on the inner boundary of CCE domain.
1043 : * The quantities are in the Cauchy coordinates.
1044 : *
1045 : * \details The radial derivative of the Weyl scalar \f$\partial_\lambda
1046 : * \Psi_0\f$ is given by
1047 : *
1048 : * \f{align*}{
1049 : * \partial_\lambda \Psi_0 = \frac{(1-y)^2}{2r}e^{-2\beta}
1050 : * \partial_y \Psi_0
1051 : * \f}
1052 : *
1053 : * Note that \f$(1-y)\f$, \f$r\f$, and \f$\beta\f$ are in the Cauchy
1054 : * coordinates, where \f$(1-y)\f$ is invariant under the coordinate
1055 : * transformation, while \f$r\f$ and \f$\beta\f$ transform as
1056 : *
1057 : * \f{align*}{
1058 : * &r = \omega \hat r
1059 : * & \beta = \hat \beta - \frac{1}{2} \log \omega
1060 : * \f}
1061 : */
1062 1 : struct InnerBoundaryWeyl {
1063 0 : using return_tags =
1064 : tmpl::list<Tags::BoundaryValue<Tags::Psi0Match>,
1065 : Tags::BoundaryValue<Tags::Dlambda<Tags::Psi0Match>>>;
1066 0 : using argument_tags =
1067 : tmpl::list<Tags::Psi0Match, Tags::Dy<Tags::Psi0Match>, Tags::OneMinusY,
1068 : Tags::BoundaryValue<Tags::BondiR>,
1069 : Tags::BoundaryValue<Tags::BondiBeta>, Tags::LMax>;
1070 0 : static void apply(
1071 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*> psi_0_boundary,
1072 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>
1073 : dlambda_psi_0_boundary,
1074 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& psi_0,
1075 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_psi_0,
1076 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y,
1077 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r_cauchy,
1078 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_beta_cauchy,
1079 : const size_t l_max);
1080 : };
1081 : } // namespace Cce
|