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/SpinWeighted.hpp"
7 : #include "DataStructures/Tensor/Tensor.hpp"
8 : #include "Evolution/Systems/Cce/Tags.hpp"
9 : #include "NumericalAlgorithms/SpinWeightedSphericalHarmonics/SwshDerivatives.hpp"
10 : #include "NumericalAlgorithms/SpinWeightedSphericalHarmonics/SwshInterpolation.hpp"
11 : #include "Utilities/Gsl.hpp"
12 : #include "Utilities/TMPL.hpp"
13 :
14 : /// \cond
15 : class ComplexDataVector;
16 : /// \endcond
17 :
18 : namespace Cce {
19 :
20 : /// \cond
21 : namespace Tags {
22 : struct LMax;
23 : } // namespace Tags
24 : template <typename Tag>
25 : struct VolumeWeyl;
26 : /// \endcond
27 :
28 : /*!
29 : * \brief Compute the Weyl scalar \f$\Psi_0\f$ in the volume according to a
30 : * standard set of Newman-Penrose vectors.
31 : *
32 : * \details The Bondi forms of the Newman-Penrose vectors that are needed for
33 : * \f$\Psi_0\f$ are:
34 : *
35 : * \f{align}{
36 : * \mathbf{l} &= \partial_r / \sqrt{2}\\
37 : * \mathbf{m} &= \frac{-1}{2 r} \left(\sqrt{1 + K} q^A \partial_A -
38 : * \frac{J}{\sqrt{1 + K}}\bar{q}^A \partial_A \right)
39 : * \f}
40 : *
41 : * Then, we may compute \f$\Psi_0 = l^\alpha m^\beta l^\mu m^\nu C_{\alpha
42 : * \beta \mu \nu}\f$ from the Bondi system, giving
43 : *
44 : * \f{align*}{
45 : * \Psi_0 = \frac{(1 - y)^4}{16 r^2 K}
46 : * \bigg[& \partial_y \beta \left((1 + K) (\partial_y J)
47 : * - \frac{J^2 \partial_y \bar J}{1 + K}\right)
48 : * - \frac{1}{2} (1 + K) (\partial_y^2 J)
49 : * + \frac{J^2 \partial_y^2 \bar J}{2(K + 1)}\\
50 : * & + \frac{1}{K^2} \left(- \frac{1}{4} J \left(\bar{J}^2 \left(\partial_y
51 : * J\right)^2 + J^2 \left(\partial_y \bar J\right)^2\right)
52 : * + \frac{1 + K^2}{2} J (\partial_y J) (\partial_y \bar J)
53 : * \right)\bigg].
54 : * \f}
55 : */
56 : template <>
57 1 : struct VolumeWeyl<Tags::Psi0> {
58 0 : using return_tags = tmpl::list<Tags::Psi0>;
59 0 : using argument_tags = tmpl::list<Tags::BondiJ, Tags::Dy<Tags::BondiJ>,
60 : Tags::Dy<Tags::Dy<Tags::BondiJ>>,
61 : Tags::BondiK, Tags::BondiR, Tags::OneMinusY>;
62 0 : static void apply(
63 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*> psi_0,
64 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j,
65 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_j,
66 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_dy_j,
67 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_k,
68 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r,
69 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y);
70 : };
71 :
72 : /*!
73 : * \brief Transform `Tags::BondiJ` from the partially flat coordinates
74 : * to the Cauchy coordinates.
75 : *
76 : * \details The spin-2 quantity \f$\hat J\f$ transforms as
77 : * \f{align*}{
78 : * J = \frac{1}{4 \omega^2} (\bar d^2 \hat J + c^2 \bar{\hat J}
79 : * + 2 c \bar d \hat K )
80 : * \f}
81 : *
82 : * with
83 : * \f{align*}{
84 : * \hat K = \sqrt{1+\hat J \bar{\hat J}}
85 : * \f}
86 : */
87 1 : struct TransformBondiJToCauchyCoords {
88 0 : using return_tags = tmpl::list<Tags::BondiJCauchyView>;
89 0 : using argument_tags = tmpl::list<
90 : Tags::CauchyGaugeC, Tags::BondiJ, Tags::CauchyGaugeD,
91 : Tags::CauchyGaugeOmega,
92 : Spectral::Swsh::Tags::SwshInterpolator<Tags::PartiallyFlatAngularCoords>,
93 : Tags::LMax>;
94 0 : static void apply(
95 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>
96 : cauchy_view_volume_j,
97 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& gauge_cauchy_c,
98 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& volume_j,
99 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& gauge_cauchy_d,
100 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& omega_cauchy,
101 : const Spectral::Swsh::SwshInterpolator& interpolator,
102 : const size_t l_max);
103 : };
104 :
105 : /*!
106 : * \brief Compute the Weyl scalar \f$\Psi_0\f$ in the volume for the purpose
107 : * of CCM, the quantity is in the Cauchy coordinates.
108 : *
109 : * \details The Weyl scalar \f$\Psi_0\f$ is given by:
110 : *
111 : * \f{align*}{
112 : * \Psi_0 = \frac{(1 - y)^4}{16 r^2 K}
113 : * \bigg[& \partial_y \beta \left((1 + K) (\partial_y J)
114 : * - \frac{J^2 \partial_y \bar J}{1 + K}\right)
115 : * - \frac{1}{2} (1 + K) (\partial_y^2 J)
116 : * + \frac{J^2 \partial_y^2 \bar J}{2(K + 1)}\\
117 : * & + \frac{1}{K^2} \left(- \frac{1}{4} J \left(\bar{J}^2 \left(\partial_y
118 : * J\right)^2 + J^2 \left(\partial_y \bar J\right)^2\right)
119 : * + \frac{1 + K^2}{2} J (\partial_y J) (\partial_y \bar J)
120 : * \right)\bigg].
121 : * \f}
122 : *
123 : * The quantities above are all in the Cauchy coordinates, where \f$K\f$ is
124 : * updated from \f$J\f$ and \f$\bar J\f$, \f$(1-y)\f$ is invariant under
125 : * the coordinate transformation. \f$r\f$ transforms as
126 : *
127 : * \f{align*}{
128 : * r = \omega \hat r
129 : * \f}
130 : */
131 : template <>
132 1 : struct VolumeWeyl<Tags::Psi0Match> {
133 0 : using return_tags = tmpl::list<Tags::Psi0Match>;
134 0 : using argument_tags =
135 : tmpl::list<Tags::BondiJCauchyView, Tags::Dy<Tags::BondiJCauchyView>,
136 : Tags::Dy<Tags::Dy<Tags::BondiJCauchyView>>,
137 : Tags::BoundaryValue<Tags::BondiR>, Tags::OneMinusY,
138 : Tags::LMax>;
139 0 : static void apply(
140 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*> psi_0,
141 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& bondi_j_cauchy,
142 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_j_cauchy,
143 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_dy_j_cauchy,
144 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r_cauchy,
145 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y,
146 : const size_t l_max);
147 : };
148 :
149 : /*!
150 : * \brief Compute the Weyl scalar \f$\Psi_0\f$ and its radial derivative
151 : * \f$\partial_\lambda \Psi_0\f$ on the inner boundary of CCE domain.
152 : * The quantities are in the Cauchy coordinates.
153 : *
154 : * \details The radial derivative of the Weyl scalar \f$\partial_\lambda
155 : * \Psi_0\f$ is given by
156 : *
157 : * \f{align*}{
158 : * \partial_\lambda \Psi_0 = \frac{(1-y)^2}{2r}e^{-2\beta}
159 : * \partial_y \Psi_0
160 : * \f}
161 : *
162 : * Note that \f$(1-y)\f$, \f$r\f$, and \f$\beta\f$ are in the Cauchy
163 : * coordinates, where \f$(1-y)\f$ is invariant under the coordinate
164 : * transformation, while \f$r\f$ and \f$\beta\f$ transform as
165 : *
166 : * \f{align*}{
167 : * &r = \omega \hat r
168 : * & \beta = \hat \beta - \frac{1}{2} \log \omega
169 : * \f}
170 : */
171 1 : struct InnerBoundaryWeyl {
172 0 : using return_tags =
173 : tmpl::list<Tags::BoundaryValue<Tags::Psi0Match>,
174 : Tags::BoundaryValue<Tags::Dlambda<Tags::Psi0Match>>>;
175 0 : using argument_tags =
176 : tmpl::list<Tags::Psi0Match, Tags::Dy<Tags::Psi0Match>, Tags::OneMinusY,
177 : Tags::BoundaryValue<Tags::BondiR>,
178 : Tags::BoundaryValue<Tags::BondiBeta>, Tags::LMax>;
179 0 : static void apply(
180 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*> psi_0_boundary,
181 : gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>
182 : dlambda_psi_0_boundary,
183 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& psi_0,
184 : const Scalar<SpinWeighted<ComplexDataVector, 2>>& dy_psi_0,
185 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& one_minus_y,
186 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_r_cauchy,
187 : const Scalar<SpinWeighted<ComplexDataVector, 0>>& bondi_beta_cauchy,
188 : const size_t l_max);
189 : };
190 : } // namespace Cce
|