Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 :
8 : #include "DataStructures/Tensor/Tensor.hpp"
9 : #include "Evolution/Systems/Cce/AnalyticSolutions/WorldtubeData.hpp"
10 : #include "Evolution/Systems/Cce/BoundaryDataTags.hpp"
11 : #include "Evolution/Systems/Cce/Tags.hpp"
12 : #include "Evolution/Systems/GeneralizedHarmonic/Tags.hpp"
13 : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
14 : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
15 : #include "Utilities/Gsl.hpp"
16 : #include "Utilities/TMPL.hpp"
17 :
18 : /// \cond
19 : class DataVector;
20 : /// \endcond
21 :
22 : namespace Cce {
23 : namespace Solutions {
24 :
25 : /*!
26 : * \brief Abstract base class for analytic worldtube data most easily derived in
27 : * spherical coordinate form.
28 : *
29 : * \details This class provides the functions required by the `WorldtubeData`
30 : * interface that convert from a spherical coordinate spacetime metric to
31 : * Cartesian coordinates. Derived classes of `SphericalMetricData` need not
32 : * implement the `variables_impl`s for the Cartesian quantities. Instead, the
33 : * derived classes must override the protected functions:
34 : * - `SphericalMetricData::spherical_metric()`
35 : * - `SphericalMetricData::dr_spherical_metric()`
36 : * - `SphericalMetricData::dt_spherical_metric()`
37 : *
38 : * Derived classes are still responsible for overriding
39 : * `WorldtubeData::get_clone()`, `WorldtubeData::variables_impl()` for tag
40 : * `Cce::Tags::News`, and `WorldtubeData::prepare_solution()`.
41 : */
42 1 : struct SphericalMetricData : public WorldtubeData {
43 :
44 0 : WRAPPED_PUPable_abstract(SphericalMetricData); // NOLINT
45 :
46 0 : SphericalMetricData() = default;
47 :
48 0 : explicit SphericalMetricData(CkMigrateMessage* msg) : WorldtubeData(msg) {}
49 :
50 0 : explicit SphericalMetricData(const double extraction_radius)
51 : : WorldtubeData{extraction_radius} {}
52 :
53 0 : ~SphericalMetricData() override = default;
54 :
55 : /*!
56 : * Computes the Jacobian
57 : * \f$\partial x_{\mathrm{Cartesian}}^j / \partial x_{\mathrm{spherical}}^i\f$
58 : *
59 : * \details The Jacobian (with \f$ \sin \theta \f$
60 : * scaled out of \f$\phi\f$ components) in question is
61 : *
62 : * \f{align*}{
63 : * \frac{\partial x_{\mathrm{Cartesian}}^j}{\partial x_{\mathrm{spherical}}^i}
64 : * = \left[
65 : * \begin{array}{ccc}
66 : * \frac{\partial x}{\partial r} & \frac{\partial y}{\partial r} &
67 : * \frac{\partial z}{\partial r} \\
68 : * \frac{\partial x}{\partial \theta} & \frac{\partial y}{\partial \theta} &
69 : * \frac{\partial z}{\partial \theta} \\
70 : * \frac{\partial x}{\sin \theta \partial \phi} &
71 : * \frac{\partial y}{\sin \theta \partial \phi} &
72 : * \frac{\partial y}{\sin \theta \partial \phi}
73 : * \end{array}
74 : * \right]
75 : * = \left[
76 : * \begin{array}{ccc}
77 : * \sin \theta \cos \phi & \sin \theta \sin \phi & \cos \theta \\
78 : * r \cos \theta \cos \phi & r \cos \theta \sin \phi & -r \sin \theta \\
79 : * -r \sin \phi & r \cos \phi & 0
80 : * \end{array}
81 : * \right]
82 : * \f}
83 : */
84 1 : void jacobian(gsl::not_null<SphericaliCartesianJ*> jacobian,
85 : size_t l_max) const;
86 :
87 : /*!
88 : * Computes the first radial derivative of the
89 : * Jacobian: \f$\partial_r (\partial x_{\mathrm{Cartesian}}^j /
90 : * \partial x_{\mathrm{Spherical}}^i)\f$
91 : *
92 : * \details The radial derivative of the Jacobian (with \f$ \sin \theta \f$
93 : * scaled out of \f$\phi\f$ components) in question is
94 : *
95 : * \f{align*}{
96 : * \frac{\partial}{\partial r}
97 : * \frac{\partial x_{\mathrm{Cartesian}}^j}{\partial x_{\mathrm{spherical}}^i}
98 : * = \left[
99 : * \begin{array}{ccc}
100 : * \frac{\partial^2 x}{(\partial r)^2} & \frac{\partial^2 y}{(\partial r)^2} &
101 : * \frac{\partial^2 z}{(\partial r)^2} \\
102 : * \frac{\partial^2 x}{\partial r \partial \theta} &
103 : * \frac{\partial^2 y}{\partial r \partial \theta} &
104 : * \frac{\partial^2 z}{\partial r \partial \theta} \\
105 : * \frac{\partial^2 x}{\sin \theta \partial r \partial \phi} &
106 : * \frac{\partial^2 y}{\sin \theta \partial r \partial \phi} &
107 : * \frac{\partial^2 y}{\sin \theta \partial r \partial \phi}
108 : * \end{array}
109 : * \right]
110 : * = \left[
111 : * \begin{array}{ccc}
112 : * 0 & 0 & 0 \\
113 : * \cos \theta \cos \phi & \cos \theta \sin \phi & - \sin \theta \\
114 : * - \sin \phi & \cos \phi & 0
115 : * \end{array}
116 : * \right]
117 : * \f}
118 : */
119 1 : static void dr_jacobian(gsl::not_null<SphericaliCartesianJ*> dr_jacobian,
120 : size_t l_max);
121 :
122 : /*!
123 : * Computes the Jacobian
124 : * \f$\partial x_{\mathrm{spherical}}^j / \partial
125 : * x_{\mathrm{Cartesian}}^i\f$
126 : *
127 : * \details The Jacobian (with \f$ \sin \theta \f$
128 : * scaled out of \f$\phi\f$ components) in question is
129 : *
130 : * \f{align*}{
131 : * \frac{\partial x_{\mathrm{spherical}}^j}{\partial x_{\mathrm{Cartesian}}^i}
132 : * = \left[
133 : * \begin{array}{ccc}
134 : * \frac{\partial r}{\partial x} & \frac{\partial \theta}{\partial x} &
135 : * \frac{\sin \theta \partial \phi}{\partial x} \\
136 : * \frac{\partial r}{\partial y} & \frac{\partial \theta}{\partial y} &
137 : * \frac{\sin \theta \partial \phi}{\partial y} \\
138 : * \frac{\partial r}{\partial z} & \frac{\partial \theta}{\partial z} &
139 : * \frac{\sin \theta \partial \phi}{\partial z}
140 : * \end{array}
141 : * \right]
142 : * = \left[
143 : * \begin{array}{ccc}
144 : * \cos \phi \sin \theta & \frac{\cos \phi \cos \theta}{r} &
145 : * - \frac{\sin \phi}{r} \\
146 : * \sin \phi \sin \theta & \frac{\cos \theta \sin \phi}{r} &
147 : * \frac{\cos \phi}{r} \\
148 : * \cos \theta & -\frac{\sin \theta}{r} & 0
149 : * \end{array}
150 : * \right]
151 : * \f}
152 : */
153 1 : void inverse_jacobian(gsl::not_null<CartesianiSphericalJ*> inverse_jacobian,
154 : size_t l_max) const;
155 :
156 : /*!
157 : * Computes the first radial derivative of the
158 : * Jacobian: \f$\partial_r (\partial x_{\mathrm{spherical}}^j / \partial
159 : * x_{\mathrm{Cartesian}}^i)\f$
160 : *
161 : * \details The first radial derivative of the Jacobian (with
162 : * \f$ \sin \theta \f$ scaled out of \f$\phi\f$ components) in question is
163 : *
164 : * \f{align*}{
165 : * \frac{\partial}{\partial r}
166 : * \frac{\partial x_{\mathrm{spherical}}^j}{\partial x_{\mathrm{Cartesian}}^i}
167 : * = \left[
168 : * \begin{array}{ccc}
169 : * \frac{\partial}{\partial r} \frac{\partial r}{\partial x} &
170 : * \frac{\partial}{\partial r} \frac{\partial \theta}{\partial x} &
171 : * \frac{\partial}{\partial r} \frac{\sin \theta \partial \phi}{\partial x} \\
172 : * \frac{\partial}{\partial r} \frac{\partial r}{\partial y} &
173 : * \frac{\partial}{\partial r} \frac{\partial \theta}{\partial y} &
174 : * \frac{\partial}{\partial r} \frac{\sin \theta \partial \phi}{\partial y} \\
175 : * \frac{\partial}{\partial r} \frac{\partial r}{\partial z} &
176 : * \frac{\partial}{\partial r} \frac{\partial \theta}{\partial z} &
177 : * \frac{\partial}{\partial r} \frac{\sin \theta \partial \phi}{\partial z}
178 : * \end{array}
179 : * \right]
180 : * = \left[
181 : * \begin{array}{ccc}
182 : * 0 & - \frac{\cos \phi \cos \theta}{r^2} & \frac{\sin \phi}{r^2} \\
183 : * 0 & - \frac{\cos \theta \sin \phi}{r^2} & -\frac{\cos \phi}{r^2} \\
184 : * 0 & \frac{\sin \theta}{r^2} & 0
185 : * \end{array}
186 : * \right]
187 : * \f}
188 : */
189 1 : void dr_inverse_jacobian(
190 : gsl::not_null<CartesianiSphericalJ*> dr_inverse_jacobian,
191 : size_t l_max) const;
192 :
193 0 : void pup(PUP::er& p) override;
194 :
195 : protected:
196 0 : using WorldtubeData::variables_impl;
197 :
198 : /*!
199 : * \brief Computes the Cartesian spacetime metric from the spherical solution
200 : * provided by the derived classes.
201 : *
202 : * \details The derived classes provide spherical metric data via the virtual
203 : * function `SphericalMetricData::spherical_metric()` at a resolution
204 : * determined by the `l_max` argument. This function performs the
205 : * coordinate transformation using the Jacobian computed from
206 : * `SphericalMetricData::inverse_jacobian()`.
207 : */
208 1 : void variables_impl(
209 : gsl::not_null<tnsr::aa<DataVector, 3>*> spacetime_metric, size_t l_max,
210 : double time,
211 : tmpl::type_<gr::Tags::SpacetimeMetric<DataVector, 3>> /*meta*/)
212 : const override;
213 :
214 : /*!
215 : * \brief Computes the time derivative of the Cartesian spacetime metric from
216 : * the spherical solution provided by the derived classes.
217 : *
218 : * \details The derived classes provide the time derivative of the spherical
219 : * metric data via the virtual function
220 : * `SphericalMetricData::dt_spherical_metric()` at a resolution determined by
221 : * the `l_max` argument. This function performs the coordinate
222 : * transformation using the Jacobian computed from
223 : * `SphericalMetricData::inverse_jacobian()`.
224 : */
225 1 : void variables_impl(
226 : gsl::not_null<tnsr::aa<DataVector, 3>*> dt_spacetime_metric, size_t l_max,
227 : double time,
228 : tmpl::type_<
229 : ::Tags::dt<gr::Tags::SpacetimeMetric<DataVector, 3>>> /*meta*/)
230 : const override;
231 :
232 : /*!
233 : * \brief Computes the spatial derivatives of the Cartesian spacetime metric
234 : * from the spherical solution provided by the derived classes.
235 : *
236 : * \details The derived classes provide the radial derivative of the spherical
237 : * metric data via the virtual function
238 : * `SphericalMetricData::dr_spherical_metric()` at a resolution determined by
239 : * the `l_max_` argument. This function performs the additional angular
240 : * derivatives necessary to assemble the full spatial derivative and performs
241 : * the coordinate transformation to Cartesian coordinates via the Jacobians
242 : * computed in `SphericalMetricData::inverse_jacobian()` and
243 : * `SphericalMetricData::inverse_jacobian()`.
244 : */
245 1 : void variables_impl(
246 : gsl::not_null<tnsr::iaa<DataVector, 3>*> d_spacetime_metric, size_t l_max,
247 : double time,
248 : tmpl::type_<gh::Tags::Phi<DataVector, 3>> /*meta*/) const override;
249 :
250 : /// Must be overriden in the derived class; should compute the spacetime
251 : /// metric of the analytic solution in spherical coordinates.
252 1 : virtual void spherical_metric(
253 : gsl::not_null<
254 : tnsr::aa<DataVector, 3, ::Frame::Spherical<::Frame::Inertial>>*>
255 : spherical_metric,
256 : size_t l_max, double time) const = 0;
257 :
258 : /// Must be overriden in the derived class; should compute the first radial
259 : /// derivative of the spacetime metric of the analytic solution in spherical
260 : /// coordinates.
261 1 : virtual void dr_spherical_metric(
262 : gsl::not_null<
263 : tnsr::aa<DataVector, 3, ::Frame::Spherical<::Frame::Inertial>>*>
264 : dr_spherical_metric,
265 : size_t l_max, double time) const = 0;
266 :
267 : /// Must be overriden in the derived class; should compute the first time
268 : /// derivative of the spacetime metric of the analytic solution in spherical
269 : /// coordinates.
270 1 : virtual void dt_spherical_metric(
271 : gsl::not_null<
272 : tnsr::aa<DataVector, 3, ::Frame::Spherical<::Frame::Inertial>>*>
273 : dt_spherical_metric,
274 : size_t l_max, double time) const = 0;
275 : };
276 :
277 : } // namespace Solutions
278 : } // namespace Cce
|