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