SpECTRE Documentation Coverage Report
Current view: top level - PointwiseFunctions/AnalyticSolutions/GeneralRelativity - SphericalKerrSchild.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 1.5 % 132 2
Test Date: 2026-10-22 17:29:42
Legend: Lines:     hit not hit

            Line data    Source code
       1            0 : // Distributed under the MIT License.
       2              : // See LICENSE.txt for details.
       3              : 
       4              : #pragma once
       5              : 
       6              : #include <algorithm>
       7              : #include <array>
       8              : #include <cstddef>
       9              : #include <pup.h>
      10              : 
      11              : #include "DataStructures/CachedTempBuffer.hpp"
      12              : #include "DataStructures/TaggedTuple.hpp"
      13              : #include "DataStructures/Tags/TempTensor.hpp"
      14              : #include "DataStructures/Tensor/TypeAliases.hpp"
      15              : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp"
      16              : #include "Options/Context.hpp"
      17              : #include "Options/String.hpp"
      18              : #include "PointwiseFunctions/AnalyticSolutions/AnalyticSolution.hpp"
      19              : #include "PointwiseFunctions/AnalyticSolutions/GeneralRelativity/Solutions.hpp"
      20              : #include "PointwiseFunctions/GeneralRelativity/TagsDeclarations.hpp"
      21              : #include "Utilities/ContainerHelpers.hpp"
      22              : #include "Utilities/ForceInline.hpp"
      23              : #include "Utilities/Gsl.hpp"
      24              : #include "Utilities/MakeArray.hpp"
      25              : #include "Utilities/TMPL.hpp"
      26              : 
      27              : /// \cond
      28              : namespace Tags {
      29              : template <typename Tag>
      30              : struct dt;
      31              : }  // namespace Tags
      32              : namespace gsl {
      33              : template <class T>
      34              : class not_null;
      35              : }  // namespace gsl
      36              : /// \endcond
      37              : 
      38              : namespace gr {
      39              : namespace Solutions {
      40              : 
      41              : /*!
      42              :  * \brief Kerr black hole in Spherical Kerr-Schild coordinates
      43              :  *
      44              :  * ## Introduction
      45              :  *
      46              :  * Given a Kerr-Schild (KS) black hole system, we denote the coordinate system
      47              :  * using \f$\{t,x,y,z\}\f$. In the transformed system, Spherical Kerr-Schild
      48              :  * (Spherical KS), we denote the coordinate system using
      49              :  * \f$\{t,\bar{x},\bar{y},\bar{z}\}\f$. Further, when considering indexed
      50              :  * objects, we will use Greek and Latin indices with the standard convention
      51              :  * \f$(\mu=0,1,2,3\f$ and \f$i=1,2,3\f$ respectively), but we will use a bar to
      52              :  * denote that a given index is in reference to the Spherical KS coordinate
      53              :  * system (i.e. \f$i\f$ vs. \f$\bar{\imath}\f$ and \f$\mu\f$ vs.
      54              :  * \f$\bar{\mu}\f$).
      55              :  *
      56              :  * ## Spin in the z direction
      57              :  *
      58              :  * ### The Transformation
      59              :  *
      60              :  * The Boyer-Lindquist radius for KS with its spin in the \f$z\f$ direction is
      61              :  * defined by
      62              :  *
      63              :  * \f{align}{
      64              :  *    \frac{x^2 + y^2}{r^2 + a^2} + \frac{z^2}{r^2} = 1,
      65              :  * \f}
      66              :  *
      67              :  * or equivalently,
      68              :  *
      69              :  * \f{align}{
      70              :  *    r^2 &= \frac{1}{2}\left(x^2+y^2+z^2-a^2\right) +
      71              :  *    \left(\frac{1}{4}\left(x^2+y^2+z^2-a^2\right)^2 + a^2z^2\right)^{1/2}.
      72              :  * \f}
      73              :  *
      74              :  * The Spherical KS coordinates
      75              :  *
      76              :  * \f{align}{
      77              :  *    \vec{\bar{x}} = x^{\bar{\imath}} = x_{\bar{\imath}} =
      78              :  *    (\bar{x},\bar{y},\bar{z}),
      79              :  * \f}
      80              :  *
      81              :  * and KS coordinates
      82              :  *
      83              :  * \f{align}{
      84              :  *    \vec{x} = x^{i} = x_{i} = (x,y,z),
      85              :  * \f}
      86              :  *
      87              :  * are related by
      88              :  *
      89              :  * \f{align}{
      90              :  *    \left(\frac{\bar{x}}{r},\frac{\bar{y}}{r},\frac{\bar{z}}{r}\right) \equiv
      91              :  *    \left(\frac{x}{\rho},\frac{y}{\rho},\frac{z}{r}\right),
      92              :  * \f}
      93              :  *
      94              :  * where we have defined
      95              :  *
      96              :  * \f{align}{
      97              :  *   \rho^2 \equiv r^2 + a^2. \label{eq:rho}
      98              :  * \f}
      99              :  *
     100              :  * Therefore, we have that \f$r\f$ satisfies the equation for a sphere in
     101              :  * Spherical KS
     102              :  *
     103              :  * \f{align}{
     104              :  *    r^2 = \vec{\bar{x}}\cdot\vec{\bar{x}} = \bar{x}^2 + \bar{y}^2 +
     105              :  *    \bar{z}^2.
     106              :  * \f}
     107              :  *
     108              :  * It is clear to see that the Spherical KS radius coincides with the
     109              :  * Boyer-Lindquist radius.
     110              :  *
     111              :  * ## Spin in an Arbitrary Direction
     112              :  *
     113              :  * Given that the remaining important quantities take forms that are easily
     114              :  * specialized to the \f$z\f$ spin case, we instead focus on the general case
     115              :  * for brevity.
     116              :  *
     117              :  * ### The Transformation
     118              :  *
     119              :  * The Boyer-Lindquist radius for KS with spin in an arbitrary direction is
     120              :  * defined by
     121              :  *
     122              :  * \f{align}{
     123              :  *    r^2 = \frac{1}{2}\left(\vec{x}\cdot\vec{x}-a^2\right) +
     124              :  *    \left(\frac{1}{4}\left(\vec{x}\cdot\vec{x}-a^2\right)^2 +
     125              :  *    \left(\vec{a}\cdot\vec{x}\right)^2\right)^{1/2}.
     126              :  * \f}
     127              :  *
     128              :  * Then, defining two transformation matrices \f$Q^{\bar{\imath}}{}_{j}\f$ and
     129              :  * \f$P^{j}{}_{\bar{\imath}}\f$ as
     130              :  *
     131              :  * \f{align}{
     132              :  *    Q^{\bar{\imath}}{}_{j} &= \frac{r}{\rho}\delta^{\bar{\imath}}{}_{j} +
     133              :  *    \frac{1}{(\rho + r)\rho}a^{\bar{\imath}}a_{j}, \\
     134              :  *    P^{j}{}_{\bar{\imath}} &= \frac{\rho}{r}\delta^{j}{}_{\bar{\imath}} -
     135              :  *    \frac{1}{(\rho + r)r}a^{j}a_{\bar{\imath}},
     136              :  * \f}
     137              :  *
     138              :  * where the definition of \f$\rho\f$ is identical to Eq. \f$(\ref{eq:rho})\f$,
     139              :  * such that
     140              :  *
     141              :  * \f{align}{
     142              :  *   Q^{\bar{\imath}}{}_{j}x^{j} &= x^{\bar{\imath}}, \\
     143              :  *   P^{j}{}_{\bar{\imath}}x^{\bar{\imath}} &= x^{j}.
     144              :  * \f}
     145              :  *
     146              :  * We again recover that \f$r\f$ satisfies the equation for a sphere in
     147              :  * Spherical KS
     148              :  *
     149              :  * \f{align}{
     150              :  *   r^2 = \vec{\bar{x}}\cdot\vec{\bar{x}} = \bar{x}^2+\bar{y}^2+\bar{z}^2,
     151              :  * \f}
     152              :  *
     153              :  * and we also have that
     154              :  *
     155              :  * \f{align}{
     156              :  *   \vec{a}\cdot\vec{\bar{x}} = \vec{a}\cdot\vec{x}.
     157              :  * \f}
     158              :  *
     159              :  * Note that \f$Q^{\bar{\imath}}{}_{ j}\f$ and \f$P^{j}{}_{\bar{\imath}}\f$
     160              :  * satisfy
     161              :  *
     162              :  * \f{align}{
     163              :  *   P^{i}{}_{\bar{\jmath}}\,Q^{\bar{\jmath}}{}_{ k} = \delta^{i}{}_{ k}.
     164              :  * \f}
     165              :  *
     166              :  * The Jacobian is then given by
     167              :  *
     168              :  * \f{align}{
     169              :  *   T^{i}{}_{\bar{\jmath}} = \partial_{\bar{\jmath}}\,x^{i} =
     170              :  *   \frac{\partial x^i}{\partial x^{\bar{\jmath}}},
     171              :  * \f}
     172              :  *
     173              :  * while its inverse is given by
     174              :  *
     175              :  * \f{align}{
     176              :  *   S^{\bar{\jmath}}{}_{ i} = \partial_{i}\,x^{\bar{\jmath}} =
     177              :  *   \frac{\partial x^{\bar{\jmath}}}{\partial x^i},
     178              :  * \f}
     179              :  *
     180              :  * which in turn satisfies
     181              :  *
     182              :  * \f{align}{
     183              :  *   T^{i}{}_{\bar{\jmath}}\,S^{\bar{\jmath}}{}_{ k} &= \delta^i_{\; k}.
     184              :  * \f}
     185              :  *
     186              :  * ### The Metric
     187              :  *
     188              :  * A KS coordinate system is defined by
     189              :  *
     190              :  * \f{align}{
     191              :  *   g_{\mu\nu} = \eta_{\mu\nu} + 2Hl_{\mu}l_{\nu},
     192              :  * \f}
     193              :  *
     194              :  * where \f$H\f$ is a scalar function of the coordinates, \f$\eta_{\mu\nu}\f$ is
     195              :  * the Minkowski metric, and \f$l^\mu\f$ is a null vector. Note that the inverse
     196              :  * of the spacetime metric is given by
     197              :  *
     198              :  * \f{align}{
     199              :  *   g^{\mu\nu} = \eta^{\mu\nu} - 2Hl^{\mu}l^{\nu}.
     200              :  * \f}
     201              :  *
     202              :  * The scalar function \f$H\f$ takes the form
     203              :  *
     204              :  * \f{align}{
     205              :  *   H = \frac{Mr^3}{r^4 + \left(\vec{a}\cdot\vec{x}\right)^{2}},
     206              :  * \f}
     207              :  *
     208              :  * where \f$M\f$ is the mass, while the spatial part of the null vector takes
     209              :  * the form
     210              :  *
     211              :  * \f{align}{
     212              :  *   l_{i} = l^{i} = \frac{r\vec{x} - \vec{a}\times\vec{x} +
     213              :  *   \frac{(\vec{a}\cdot\vec{x})\vec{a}}{r}}{\rho^2}.
     214              :  * \f}
     215              :  *
     216              :  * Note that the full spacetime form of the null vector is
     217              :  *
     218              :  * \f{align}{
     219              :  *   l_{\mu} &= (-1,l_{i}), & l^{\mu} &= (1,l^{i}).
     220              :  * \f}
     221              :  *
     222              :  * Transforming the KS spatial metric then yields the following Spherical KS
     223              :  * spatial metric
     224              :  *
     225              :  * \f{align}{
     226              :  *   \gamma_{\bar{\imath}\bar{\jmath}} &=
     227              :  *   \gamma_{mn}T^{m}{}_{\bar{\imath}}\,T^{n}{}_{\bar{\jmath}}, \nonumber \\
     228              :  *   &= \eta_{mn}T^{m}{}_{\bar{\imath}}\,T^{n}{}_{\bar{\jmath}} +
     229              :  *   2Hl_{m}l_{n}T^{m}{}_{\bar{\imath}}\,T^{n}{}_{\bar{\jmath}}, \nonumber \\
     230              :  *   &= \eta_{\bar{\imath}\bar{\jmath}} + 2Hl_{\bar{\imath}}l_{\bar{\jmath}}.
     231              :  * \f}
     232              :  *
     233              :  * The transformed spacetime Minkowski metric is given by
     234              :  *
     235              :  * \f{align}{
     236              :  *   \eta_{\bar{\mu}\bar{\nu}} = (-1)\otimes\eta_{\bar{\imath}\bar{\jmath}},
     237              :  * \f}
     238              :  *
     239              :  * and the transformed spacetime null vector is given by
     240              :  *
     241              :  * \f{align}{
     242              :  *   l_{\bar{\mu}} &= (-1,l_{\bar{\imath}}), &
     243              :  *   l^{\bar{\mu}} &= (1,l^{\bar{\imath}}).
     244              :  * \f}
     245              :  *
     246              :  * Therefore, the Spherical KS spacetime metric is
     247              :  *
     248              :  * \f{align}{
     249              :  *   g_{\bar{\mu}\bar{\nu}} = \eta_{\bar{\mu}\bar{\nu}} +
     250              :  *   2Hl_{\bar{\mu}}l_{\bar{\nu}}.
     251              :  * \f}
     252              :  *
     253              :  * Further, we have that the lapse in Spherical KS is given by
     254              :  *
     255              :  * \f{align}{
     256              :  *   \alpha = \left(1 + 2H\right)^{-1/2},
     257              :  * \f}
     258              :  *
     259              :  * and the shift in Spherical KS by
     260              :  *
     261              :  * \f{align}{
     262              :  *   \beta^{\bar{\imath}} &= -\frac{2Hl^{t}l^{\bar{\imath}}}{1 + 2Hl^{t}l^{t}} =
     263              :  *   -2H\alpha^{2}l^{t}l^{\bar{\imath}}, & \beta_{\bar{\imath}} &=
     264              :  *  -2Hl_{t}l_{\bar{\imath}}.
     265              :  * \f}
     266              :  *
     267              :  * ### Derivatives
     268              :  *
     269              :  * The derivatives of the preceding quantities are
     270              :  *
     271              :  * \f{align}{
     272              :  *   \frac{\partial r}{\partial x^{i}} &= \frac{r^{2}x_{i} +
     273              :  *   \left(\vec{a}\cdot\vec{x}\right)a_{i}}{rs}, \\
     274              :  *   \partial_{\bar{\imath}}H &= HT^{m}{}_{\bar{\imath}}
     275              :  *   \left[\frac{3}{r}\frac{\partial r}{\partial x^{m}} -
     276              :  *   \frac{4r^{3}\frac{\partial r}{\partial x^{m}} +
     277              :  *   2\left(\vec{a}\cdot\vec{x}\right)a_{m}}{r^{4} +
     278              :  *   \left(\vec{a}\cdot\vec{x}\right)^{2}}\right], \\
     279              :  *   \partial_{\bar{\jmath}}l^{\bar{\imath}} &=
     280              :  *   \partial_{\bar{\jmath}}\left(l_{k}T^{k}{}_{\bar{\imath}}\right),
     281              :  *   \nonumber \\
     282              :  *   &= T^{k}{}_{\bar{\imath}}T^{m}{}_{\bar{\jmath}}\frac{1}{\rho^{2}}
     283              :  *   \left[\left(x_{k} - 2rl_{k} -
     284              :  *   \frac{\left(\vec{a}\cdot\vec{x}\right)a_{k}}{r^{2}}\right)
     285              :  *   \frac{\partial r}{\partial x^{m}} + r\delta_{km} + \frac{a_{k}a_{m}}{r} +
     286              :  *   \epsilon^{kmn}a_{n}\right] +
     287              :  *   l_{k}\partial_{\bar{\jmath}}T^{k}{}_{\bar{\imath}}, \\
     288              :  *   \partial_{\bar{k}}\gamma_{\bar{\imath}\bar{\jmath}} &=
     289              :  *   2l_{\bar{\imath}}l_{\bar{\jmath}}\partial_{\bar{k}}H +
     290              :  *   4Hl_{(\bar{\imath}}\partial_{\bar{k}}l_{\bar{\jmath})} +
     291              :  *   T^{m}{}_{\bar{\jmath}}\partial_{\bar{k}}T^{m}{}_{\bar{\imath}} +
     292              :  *   T^{m}{}_{\bar{\imath}}\partial_{\bar{k}}T^{m}{}_{\bar{\jmath}}, \\
     293              :  *   \partial_{\bar{k}}\alpha &= -\left(1+2H\right)^{-3/2}\partial_{\bar{k}}H =
     294              :  *   -\alpha^{3}\partial_{\bar{k}}H, \\
     295              :  *   \partial_{\bar{k}}\beta^{i} &=
     296              :  *   2\alpha^{2}\left[l^{\bar{\imath}}\partial_{\bar{k}}H +
     297              :  *   H\left(S^{\bar{\imath}}{}_{j}S^{\bar{m}}{}_{n}
     298              :  *   \delta_{nj}\partial_{\bar{k}}l_{\bar{m}} +
     299              :  *   S^{\bar{\imath}}{}_{j}l_{\bar{m}}\partial_{\bar{k}}S^{\bar{m}}{}_{n}
     300              :  *   \delta_{nj} + S^{\bar{m}}{}_{n}\delta_{nj}l_{\bar{m}}
     301              :  *   \partial_{\bar{k}}S^{\bar{\imath}}{}_{j}\right)\right] -
     302              :  *   4Hl^{\bar{\imath}}\alpha^{4}\partial_{\bar{k}}H,
     303              :  * \f}
     304              :  *
     305              :  * where we have defined \f$s\f$ as
     306              :  *
     307              :  * \f{align}{
     308              :  *   s &\equiv r^{2} + \frac{\left(\vec{a}\cdot\vec{x}\right)^{2}}{r^{2}}.
     309              :  *   \label{eq: s_number}
     310              :  * \f}
     311              :  *
     312              :  * ## Code
     313              :  *
     314              :  * While the previous sections described the relevant physical quantities, the
     315              :  * actual files make use of internally defined objects to ease the computation
     316              :  * of the Jacobian, the inverse Jacobian, and their corresponding derivatives.
     317              :  * Therefore, we now list these intermediary objects as well as how they
     318              :  * construct the aforementioned physical quantities with the appropriate
     319              :  * definition found in the code (all for arbitrary spin).
     320              :  *
     321              :  * ### Helper Matrices
     322              :  *
     323              :  * The intermediary objects used to define the various Jacobian objects, the
     324              :  * so-called "helper matrices", are defined below.
     325              :  *
     326              :  * \f{align}{
     327              :  *   F^{i}{}_{\bar{k}} &\equiv
     328              :  *   -\frac{1}{\rho r^{3}}\left(a^{2}\delta^{i}{}_{\bar{k}} -
     329              :  *   a^{i}a_{\bar{k}}\right), \\
     330              :  *   \left(G_1\right)^{\bar{\imath}}{}_{ \bar{m}} &\equiv
     331              :  *   \frac{1}{\rho^{2}r}\left(a^{2}\delta^{\bar{\imath}}{}_{\bar{m}} -
     332              :  *   a^{\bar{\imath}}a_{\bar{m}}\right), \\
     333              :  *   \left(G_2\right)^{\bar{n}}{}_{ j} &\equiv
     334              :  *   \frac{\rho^{2}}{sr}Q^{\bar{n}}{}_{j}, \\
     335              :  *   D^{i}{}_{\bar{m}} &\equiv
     336              :  *   \frac{1}{\rho^{3}r}\left(a^{2}\delta^{i}{}_{\bar{m}} -
     337              :  *   a^{i}a_{\bar{m}}\right), \\
     338              :  *   C^{i}{}_{\bar{m}} &\equiv D^{i}{}_{\bar{m}} - 3F^{i}{}_{\bar{m}} =
     339              :  *   \frac{1}{\rho r}\left(\frac{1}{\rho^{2}} +
     340              :  *   \frac{3}{r^{2}}\right)\left(a^{2}\delta^{i}{}_{\bar{m}} -
     341              :  *   a^{i}a_{\bar{m}}\right), \\
     342              :  *   \left(E_1\right)^{i}{}_{\bar{m}} &\equiv
     343              :  *   -\frac{1}{\rho^{2}}\left(\frac{1}{r^{2}} +
     344              :  *   \frac{2}{\rho^{2}}\right)\left(a^{2}\delta^{i}{}_{\bar{m}} -
     345              :  *   a^{i}a_{\bar{m}}\right), \nonumber \\
     346              :  *   &= -\frac{\left(\rho^{2} +
     347              :  *   2r^{2}\right)}{r^{2}\rho^{4}}\left(a^{2}\delta^{i}{}_{\bar{m}} -
     348              :  *   a^{i}a_{\bar{m}}\right), \\
     349              :  *   \left(E_2\right)^{\bar{n}}{}_{ j} &\equiv \left[-\frac{a^{2}}{\rho^{2}r} -
     350              :  *   \frac{2}{s}\left(r - \frac{\left(\vec{a}\cdot\vec{x}\right)^{2}}{r^{3}}
     351              :  *   \right)\right]\cdot\left(G_2\right)^{\bar{n}}{}_{ j} +
     352              :  *   \frac{1}{s}P^{\bar{n}}{}_{ j},
     353              :  * \f}
     354              :  *
     355              :  * where \f$s\f$ is defined identically to Eq. \f$(\ref{eq: s_number})\f$.
     356              :  *
     357              :  * ### Physical Quantities
     358              :  *
     359              :  * Below are the definitions for how we construct the Jacobian, inverse
     360              :  * Jacobian, derivative of the Jacobian, and derivative of the inverse Jacobian
     361              :  * in the code using the helper matrices.
     362              :  *
     363              :  * \f{align}{
     364              :  *   T^{i}{}_{\bar{\jmath}} &= P^{i}{}_{\bar{\jmath}} +
     365              :  *   F^{i}{}_{\bar{k}}x^{\bar{k}}x_{\bar{\jmath}}, \\
     366              :  *   S^{\bar{\imath}}{}_{ j} &= Q^{\bar{\imath}}{}_{ j} +
     367              :  *   \left(G_1\right)^{\bar{\imath}}{}_{\bar{m}}x^{\bar{m}}x_{\bar{n}}
     368              :  *   \left(G_2\right)^{\bar{n}}{}_{ j}, \\
     369              :  *   \partial_{\bar{k}}T^{i}{}_{\bar{\jmath}} &=
     370              :  *   F^{i}{}_{\bar{\jmath}}x_{\bar{k}} + F^{i}{}_{\bar{k}}x_{\bar{\jmath}} +
     371              :  *   F^{i}{}_{\bar{m}}x^{\bar{m}}\delta_{jk} +
     372              :  *   C^{i}{}_{\bar{m}}\frac{x_{\bar{k}}x^{\bar{m}}x_{\bar{\jmath}}}{r^{2}}, \\
     373              :  *   \partial_{\bar{k}}S^{\;\bar{\imath}}{}_{ j} &=
     374              :  *   D^{\bar{\imath}}{}_{j}x_{\bar{k}} +
     375              :  *   \left(G_1\right)^{\bar{\imath}}{}_{\bar{k}}x_{\bar{n}}
     376              :  *   \left(G_2\right)^{\bar{n}}{}_{j} +
     377              :  *   \left(G_1\right)^{\bar{\imath}}{}_{\bar{m}}x^{\bar{m}}
     378              :  *   \left(G_2\right)^{\bar{n}}{}_{j}\delta_{\bar{n}\bar{k}} \nonumber \\
     379              :  *   &\quad +
     380              :  *   \left(E_1\right)^{i}{}_{\bar{m}}\frac{x_{\bar{k}}x^{\bar{m}}x_{\bar{n}}}{r}
     381              :  *   \left(G_2\right)^{\bar{n}}{}_{j} +
     382              :  *   \left(G_1\right)^{\bar{i}}{}_{\bar{m}}
     383              :  *   \frac{x_{\bar{k}}x^{\bar{m}}x_{\bar{n}}}{r}\left(E_2\right)^{\bar{n}}{}_{j}
     384              :  *   - \left(G_1\right)^{\bar{\imath}}{}_{\bar{m}}x^{\bar{m}}x_{\bar{n}}
     385              :  *   \left(G_2\right)^{\bar{n}}{}_{j}
     386              :  *   \frac{2\left(\vec{a}\cdot\vec{x}\right)}{sr^{2}}a_{\bar{k}}.
     387              :  * \f}
     388              :  */
     389            1 : class SphericalKerrSchild : public AnalyticSolution<3_st>,
     390              :                             public MarkAsAnalyticSolution {
     391              :  public:
     392            0 :   struct Mass {
     393            0 :     using type = double;
     394            0 :     static constexpr Options::String help = {"Mass of the black hole"};
     395            0 :     static type lower_bound() { return 0.; }
     396              :   };
     397            0 :   struct Spin {
     398            0 :     using type = std::array<double, volume_dim>;
     399            0 :     static constexpr Options::String help = {
     400              :         "The [x,y,z] dimensionless spin of the black hole"};
     401              :   };
     402            0 :   struct Center {
     403            0 :     using type = std::array<double, volume_dim>;
     404            0 :     static constexpr Options::String help = {
     405              :         "The [x,y,z] center of the black hole"};
     406              :   };
     407            0 :   using options = tmpl::list<Mass, Spin, Center>;
     408            0 :   static constexpr Options::String help{
     409              :       "Black hole in Spherical Kerr-Schild coordinates"};
     410              : 
     411              :   template <typename DataType, typename Frame = Frame::Inertial>
     412            0 :   using tags = tmpl::flatten<tmpl::list<
     413              :       AnalyticSolution<3_st>::tags<DataType, Frame>,
     414              :       gr::Tags::DerivDetSpatialMetric<DataType, 3, Frame>,
     415              :       gr::Tags::TraceExtrinsicCurvature<DataType>,
     416              :       gr::Tags::SpatialChristoffelFirstKind<DataType, 3, Frame>,
     417              :       gr::Tags::SpatialChristoffelSecondKind<DataType, 3, Frame>,
     418              :       gr::Tags::TraceSpatialChristoffelSecondKind<DataType, 3, Frame>>>;
     419              : 
     420            0 :   SphericalKerrSchild(double mass, Spin::type dimensionless_spin,
     421              :                       Center::type center,
     422              :                       const Options::Context& context = {});
     423              : 
     424            0 :   explicit SphericalKerrSchild(CkMigrateMessage* /*unused*/);
     425              : 
     426            0 :   SphericalKerrSchild() = default;
     427            0 :   SphericalKerrSchild(const SphericalKerrSchild& /*rhs*/) = default;
     428            0 :   SphericalKerrSchild& operator=(const SphericalKerrSchild& /*rhs*/) = default;
     429            0 :   SphericalKerrSchild(SphericalKerrSchild&& /*rhs*/) = default;
     430            0 :   SphericalKerrSchild& operator=(SphericalKerrSchild&& /*rhs*/) = default;
     431            0 :   ~SphericalKerrSchild() = default;
     432              : 
     433              :   // NOLINTNEXTLINE(google-runtime-references)
     434            0 :   void pup(PUP::er& p);
     435              : 
     436            0 :   SPECTRE_ALWAYS_INLINE double mass() const { return mass_; }
     437            0 :   SPECTRE_ALWAYS_INLINE const std::array<double, volume_dim>& center() const {
     438              :     return center_;
     439              :   }
     440              :   SPECTRE_ALWAYS_INLINE const std::array<double, volume_dim>&
     441            0 :   dimensionless_spin() const {
     442              :     return dimensionless_spin_;
     443              :   }
     444              : 
     445            0 :   struct internal_tags {
     446              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     447            0 :     using x_minus_center = ::Tags::TempI<0, 3, Frame, DataType>;
     448              :     template <typename DataType>
     449            0 :     using r_squared = ::Tags::TempScalar<1, DataType>;
     450              :     template <typename DataType>
     451            0 :     using r = ::Tags::TempScalar<2, DataType>;
     452              :     template <typename DataType>
     453            0 :     using rho = ::Tags::TempScalar<3, DataType>;
     454              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     455            0 :     using helper_matrix_F = ::Tags::TempIj<4, 3, Frame, DataType>;
     456              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     457            0 :     using transformation_matrix_P = ::Tags::TempIj<5, 3, Frame, DataType>;
     458              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     459            0 :     using jacobian = ::Tags::TempIj<6, 3, Frame, DataType>;
     460              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     461            0 :     using helper_matrix_D = ::Tags::TempIj<7, 3, Frame, DataType>;
     462              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     463            0 :     using helper_matrix_C = ::Tags::TempIj<8, 3, Frame, DataType>;
     464              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     465            0 :     using deriv_jacobian = ::Tags::TempiJk<9, 3, Frame, DataType>;
     466              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     467            0 :     using transformation_matrix_Q = ::Tags::TempIj<10, 3, Frame, DataType>;
     468              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     469            0 :     using helper_matrix_G1 = ::Tags::TempIj<11, 3, Frame, DataType>;
     470              :     template <typename DataType>
     471            0 :     using a_dot_x = ::Tags::TempScalar<12, DataType>;
     472              :     template <typename DataType>
     473            0 :     using s_number = ::Tags::TempScalar<13, DataType>;
     474              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     475            0 :     using helper_matrix_G2 = ::Tags::TempIj<14, 3, Frame, DataType>;
     476              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     477            0 :     using G1_dot_x = ::Tags::TempI<15, 3, Frame, DataType>;
     478              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     479            0 :     using G2_dot_x = ::Tags::Tempi<16, 3, Frame, DataType>;
     480              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     481            0 :     using inv_jacobian = ::Tags::TempIj<17, 3, Frame, DataType>;
     482              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     483            0 :     using helper_matrix_E1 = ::Tags::TempIj<18, 3, Frame, DataType>;
     484              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     485            0 :     using helper_matrix_E2 = ::Tags::TempIj<19, 3, Frame, DataType>;
     486              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     487            0 :     using deriv_inv_jacobian = ::Tags::TempiJk<20, 3, Frame, DataType>;
     488              :     template <typename DataType>
     489            0 :     using H = ::Tags::TempScalar<21, DataType>;
     490              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     491            0 :     using kerr_schild_x = ::Tags::TempI<22, 3, Frame, DataType>;
     492              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     493            0 :     using a_cross_x = ::Tags::TempI<23, 3, Frame, DataType>;
     494              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     495            0 :     using kerr_schild_l = ::Tags::TempI<24, 3, Frame, DataType>;
     496              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     497            0 :     using l_lower = ::Tags::Tempi<25, 4, Frame, DataType>;
     498              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     499            0 :     using l_upper = ::Tags::TempI<26, 4, Frame, DataType>;
     500              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     501            0 :     using deriv_r = ::Tags::TempI<27, 3, Frame, DataType>;
     502              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     503            0 :     using deriv_H = ::Tags::TempI<28, 4, Frame, DataType>;
     504              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     505            0 :     using kerr_schild_deriv_l = ::Tags::Tempij<29, 4, Frame, DataType>;
     506              :     template <typename DataType, typename Frame = ::Frame::Inertial>
     507            0 :     using deriv_l = ::Tags::Tempij<30, 4, Frame, DataType>;
     508              :     template <typename DataType>
     509            0 :     using lapse_squared = ::Tags::TempScalar<31, DataType>;
     510              :     template <typename DataType>
     511            0 :     using deriv_lapse_multiplier = ::Tags::TempScalar<32, DataType>;
     512              :     template <typename DataType>
     513            0 :     using shift_multiplier = ::Tags::TempScalar<33, DataType>;
     514              :   };
     515              : 
     516              :   template <typename DataType, typename Frame = ::Frame::Inertial>
     517            0 :   using CachedBuffer = CachedTempBuffer<
     518              :       internal_tags::x_minus_center<DataType, Frame>,
     519              :       internal_tags::r_squared<DataType>, internal_tags::r<DataType>,
     520              :       internal_tags::rho<DataType>,
     521              :       internal_tags::helper_matrix_F<DataType, Frame>,
     522              :       internal_tags::transformation_matrix_P<DataType, Frame>,
     523              :       internal_tags::jacobian<DataType, Frame>,
     524              :       internal_tags::helper_matrix_D<DataType, Frame>,
     525              :       internal_tags::helper_matrix_C<DataType, Frame>,
     526              :       internal_tags::deriv_jacobian<DataType, Frame>,
     527              :       internal_tags::transformation_matrix_Q<DataType, Frame>,
     528              :       internal_tags::helper_matrix_G1<DataType, Frame>,
     529              :       internal_tags::a_dot_x<DataType>, internal_tags::s_number<DataType>,
     530              :       internal_tags::helper_matrix_G2<DataType, Frame>,
     531              :       internal_tags::G1_dot_x<DataType, Frame>,
     532              :       internal_tags::G2_dot_x<DataType, Frame>,
     533              :       internal_tags::inv_jacobian<DataType, Frame>,
     534              :       internal_tags::helper_matrix_E1<DataType, Frame>,
     535              :       internal_tags::helper_matrix_E2<DataType, Frame>,
     536              :       internal_tags::deriv_inv_jacobian<DataType, Frame>,
     537              :       internal_tags::H<DataType>, internal_tags::kerr_schild_x<DataType, Frame>,
     538              :       internal_tags::a_cross_x<DataType, Frame>,
     539              :       internal_tags::kerr_schild_l<DataType, Frame>,
     540              :       internal_tags::l_lower<DataType, Frame>,
     541              :       internal_tags::l_upper<DataType, Frame>,
     542              :       internal_tags::deriv_r<DataType, Frame>,
     543              :       internal_tags::deriv_H<DataType, Frame>,
     544              :       internal_tags::kerr_schild_deriv_l<DataType, Frame>,
     545              :       internal_tags::deriv_l<DataType, Frame>,
     546              :       internal_tags::lapse_squared<DataType>, gr::Tags::Lapse<DataType>,
     547              :       internal_tags::deriv_lapse_multiplier<DataType>,
     548              :       internal_tags::shift_multiplier<DataType>,
     549              :       gr::Tags::Shift<DataType, 3, Frame>, DerivShift<DataType, Frame>,
     550              :       gr::Tags::SpatialMetric<DataType, 3, Frame>,
     551              :       DerivSpatialMetric<DataType, Frame>,
     552              :       ::Tags::dt<gr::Tags::SpatialMetric<DataType, 3, Frame>>,
     553              :       gr::Tags::ExtrinsicCurvature<DataType, 3, Frame>,
     554              :       gr::Tags::InverseSpatialMetric<DataType, 3, Frame>,
     555              :       gr::Tags::SpatialChristoffelFirstKind<DataType, 3, Frame>,
     556              :       gr::Tags::SpatialChristoffelSecondKind<DataType, 3, Frame>>;
     557              : 
     558              :   // forward-declaration needed.
     559              :   template <typename DataType, typename Frame>
     560              :   class IntermediateVars;
     561              : 
     562              :   template <typename DataType, typename Frame = Frame::Inertial>
     563            0 :   using allowed_tags =
     564              :       tmpl::push_back<tags<DataType, Frame>,
     565              :                       typename internal_tags::inv_jacobian<DataType, Frame>>;
     566              : 
     567              :   template <typename DataType, typename Frame, typename... Tags>
     568            0 :   tuples::TaggedTuple<Tags...> variables(
     569              :       const tnsr::I<DataType, volume_dim, Frame>& x, double /*t*/,
     570              :       tmpl::list<Tags...> /*meta*/) const {
     571              :     static_assert(
     572              :         tmpl2::flat_all_v<
     573              :             tmpl::list_contains_v<allowed_tags<DataType, Frame>, Tags>...>,
     574              :         "At least one of the requested tags is not supported. The requested "
     575              :         "tags are listed as template parameters of the `variables` function.");
     576              :     IntermediateVars<DataType, Frame> cache(get_size(*x.begin()));
     577              :     IntermediateComputer<DataType, Frame> computer(*this, x);
     578              :     return {cache.get_var(computer, Tags{})...};
     579              :   }
     580              : 
     581              :   template <typename DataType, typename Frame, typename... Tags>
     582            0 :   tuples::TaggedTuple<Tags...> variables(
     583              :       const tnsr::I<DataType, volume_dim, Frame>& x, double /*t*/,
     584              :       tmpl::list<Tags...> /*meta*/,
     585              :       gsl::not_null<IntermediateVars<DataType, Frame>*> cache) const {
     586              :     static_assert(
     587              :         tmpl2::flat_all_v<
     588              :             tmpl::list_contains_v<allowed_tags<DataType, Frame>, Tags>...>,
     589              :         "At least one of the requested tags is not supported. The requested "
     590              :         "tags are listed as template parameters of the `variables` function.");
     591              :     if (cache->number_of_grid_points() != get_size(*x.begin())) {
     592              :       *cache = IntermediateVars<DataType, Frame>(get_size(*x.begin()));
     593              :     }
     594              :     IntermediateComputer<DataType, Frame> computer(*this, x);
     595              :     return {cache->get_var(computer, Tags{})...};
     596              :   }
     597              : 
     598              :   template <typename DataType, typename Frame = ::Frame::Inertial>
     599            0 :   class IntermediateComputer {
     600              :    public:
     601            0 :     using CachedBuffer = SphericalKerrSchild::CachedBuffer<DataType, Frame>;
     602              : 
     603            0 :     IntermediateComputer(const SphericalKerrSchild& solution,
     604              :                          const tnsr::I<DataType, 3, Frame>& x);
     605              : 
     606              :     // spin_a_and_squared(const SphericalKerrSchild& solution);
     607              : 
     608            0 :     void operator()(
     609              :         const gsl::not_null<tnsr::I<DataType, 3, Frame>*> x_minus_center,
     610              :         const gsl::not_null<CachedBuffer*> /*cache*/,
     611              :         internal_tags::x_minus_center<DataType, Frame> /*meta*/) const;
     612              : 
     613            0 :     void operator()(const gsl::not_null<Scalar<DataType>*> r_squared,
     614              :                     const gsl::not_null<CachedBuffer*> cache,
     615              :                     internal_tags::r_squared<DataType> /*meta*/) const;
     616              : 
     617            0 :     void operator()(const gsl::not_null<Scalar<DataType>*> r,
     618              :                     const gsl::not_null<CachedBuffer*> cache,
     619              :                     internal_tags::r<DataType> /*meta*/) const;
     620              : 
     621            0 :     void operator()(const gsl::not_null<Scalar<DataType>*> rho,
     622              :                     const gsl::not_null<CachedBuffer*> cache,
     623              :                     internal_tags::rho<DataType> /*meta*/) const;
     624              : 
     625            0 :     void operator()(
     626              :         const gsl::not_null<tnsr::Ij<DataType, 3, Frame>*> helper_matrix_F,
     627              :         const gsl::not_null<CachedBuffer*> cache,
     628              :         internal_tags::helper_matrix_F<DataType, Frame> /*meta*/) const;
     629              : 
     630            0 :     void operator()(
     631              :         const gsl::not_null<tnsr::Ij<DataType, 3, Frame>*>
     632              :             transformation_matrix_P,
     633              :         const gsl::not_null<CachedBuffer*> cache,
     634              :         internal_tags::transformation_matrix_P<DataType, Frame> /*meta*/) const;
     635              : 
     636            0 :     void operator()(const gsl::not_null<tnsr::Ij<DataType, 3, Frame>*> jacobian,
     637              :                     const gsl::not_null<CachedBuffer*> cache,
     638              :                     internal_tags::jacobian<DataType, Frame> /*meta*/) const;
     639              : 
     640            0 :     void operator()(
     641              :         const gsl::not_null<tnsr::Ij<DataType, 3, Frame>*> helper_matrix_D,
     642              :         const gsl::not_null<CachedBuffer*> cache,
     643              :         internal_tags::helper_matrix_D<DataType, Frame> /*meta*/) const;
     644              : 
     645            0 :     void operator()(
     646              :         const gsl::not_null<tnsr::Ij<DataType, 3, Frame>*> helper_matrix_C,
     647              :         const gsl::not_null<CachedBuffer*> cache,
     648              :         internal_tags::helper_matrix_C<DataType, Frame> /*meta*/) const;
     649              : 
     650            0 :     void operator()(
     651              :         const gsl::not_null<tnsr::iJk<DataType, 3, Frame>*> deriv_jacobian,
     652              :         const gsl::not_null<CachedBuffer*> cache,
     653              :         internal_tags::deriv_jacobian<DataType, Frame> /*meta*/) const;
     654              : 
     655            0 :     void operator()(
     656              :         const gsl::not_null<tnsr::Ij<DataType, 3, Frame>*>
     657              :             transformation_matrix_Q,
     658              :         const gsl::not_null<CachedBuffer*> cache,
     659              :         internal_tags::transformation_matrix_Q<DataType, Frame> /*meta*/) const;
     660              : 
     661            0 :     void operator()(
     662              :         const gsl::not_null<tnsr::Ij<DataType, 3, Frame>*> helper_matrix_G1,
     663              :         const gsl::not_null<CachedBuffer*> cache,
     664              :         internal_tags::helper_matrix_G1<DataType, Frame> /*meta*/) const;
     665              : 
     666            0 :     void operator()(const gsl::not_null<Scalar<DataType>*> a_dot_x,
     667              :                     const gsl::not_null<CachedBuffer*> cache,
     668              :                     internal_tags::a_dot_x<DataType> /*meta*/) const;
     669              : 
     670            0 :     void operator()(const gsl::not_null<Scalar<DataType>*> s_number,
     671              :                     const gsl::not_null<CachedBuffer*> cache,
     672              :                     internal_tags::s_number<DataType> /*meta*/) const;
     673              : 
     674            0 :     void operator()(
     675              :         const gsl::not_null<tnsr::Ij<DataType, 3, Frame>*> helper_matrix_G2,
     676              :         const gsl::not_null<CachedBuffer*> cache,
     677              :         internal_tags::helper_matrix_G2<DataType, Frame> /*meta*/) const;
     678              : 
     679            0 :     void operator()(const gsl::not_null<tnsr::I<DataType, 3, Frame>*> G1_dot_x,
     680              :                     const gsl::not_null<CachedBuffer*> cache,
     681              :                     internal_tags::G1_dot_x<DataType, Frame> /*meta*/) const;
     682              : 
     683            0 :     void operator()(const gsl::not_null<tnsr::i<DataType, 3, Frame>*> G2_dot_x,
     684              :                     const gsl::not_null<CachedBuffer*> cache,
     685              :                     internal_tags::G2_dot_x<DataType, Frame> /*meta*/) const;
     686              : 
     687            0 :     void operator()(
     688              :         const gsl::not_null<tnsr::Ij<DataType, 3, Frame>*> inv_jacobian,
     689              :         const gsl::not_null<CachedBuffer*> cache,
     690              :         internal_tags::inv_jacobian<DataType, Frame> /*meta*/) const;
     691              : 
     692            0 :     void operator()(
     693              :         const gsl::not_null<tnsr::Ij<DataType, 3, Frame>*> helper_matrix_E1,
     694              :         const gsl::not_null<CachedBuffer*> cache,
     695              :         internal_tags::helper_matrix_E1<DataType, Frame> /*meta*/) const;
     696              : 
     697            0 :     void operator()(
     698              :         const gsl::not_null<tnsr::Ij<DataType, 3, Frame>*> helper_matrix_E2,
     699              :         const gsl::not_null<CachedBuffer*> cache,
     700              :         internal_tags::helper_matrix_E2<DataType, Frame> /*meta*/) const;
     701              : 
     702            0 :     void operator()(
     703              :         const gsl::not_null<tnsr::iJk<DataType, 3, Frame>*> deriv_inv_jacobian,
     704              :         const gsl::not_null<CachedBuffer*> cache,
     705              :         internal_tags::deriv_inv_jacobian<DataType, Frame> /*meta*/) const;
     706              : 
     707            0 :     void operator()(const gsl::not_null<Scalar<DataType>*> H,
     708              :                     const gsl::not_null<CachedBuffer*> cache,
     709              :                     internal_tags::H<DataType> /*meta*/) const;
     710              : 
     711            0 :     void operator()(
     712              :         const gsl::not_null<tnsr::I<DataType, 3, Frame>*> kerr_schild_x,
     713              :         const gsl::not_null<CachedBuffer*> /*cache*/,
     714              :         internal_tags::kerr_schild_x<DataType, Frame> /*meta*/) const;
     715              : 
     716            0 :     void operator()(const gsl::not_null<tnsr::I<DataType, 3, Frame>*> a_cross_x,
     717              :                     const gsl::not_null<CachedBuffer*> cache,
     718              :                     internal_tags::a_cross_x<DataType, Frame> /*meta*/) const;
     719              : 
     720            0 :     void operator()(
     721              :         const gsl::not_null<tnsr::I<DataType, 3, Frame>*> kerr_schild_l,
     722              :         const gsl::not_null<CachedBuffer*> cache,
     723              :         internal_tags::kerr_schild_l<DataType, Frame> /*meta*/) const;
     724              : 
     725            0 :     void operator()(const gsl::not_null<tnsr::i<DataType, 4, Frame>*> l_lower,
     726              :                     const gsl::not_null<CachedBuffer*> cache,
     727              :                     internal_tags::l_lower<DataType, Frame> /*meta*/) const;
     728              : 
     729            0 :     void operator()(const gsl::not_null<tnsr::I<DataType, 4, Frame>*> l_upper,
     730              :                     const gsl::not_null<CachedBuffer*> cache,
     731              :                     internal_tags::l_upper<DataType, Frame> /*meta*/) const;
     732              : 
     733            0 :     void operator()(const gsl::not_null<tnsr::I<DataType, 3, Frame>*> deriv_r,
     734              :                     const gsl::not_null<CachedBuffer*> cache,
     735              :                     internal_tags::deriv_r<DataType, Frame> /*meta*/) const;
     736              : 
     737            0 :     void operator()(const gsl::not_null<tnsr::I<DataType, 4, Frame>*> deriv_H,
     738              :                     const gsl::not_null<CachedBuffer*> cache,
     739              :                     internal_tags::deriv_H<DataType, Frame> /*meta*/) const;
     740              : 
     741            0 :     void operator()(
     742              :         const gsl::not_null<tnsr::ij<DataType, 4, Frame>*> kerr_schild_deriv_l,
     743              :         const gsl::not_null<CachedBuffer*> cache,
     744              :         internal_tags::kerr_schild_deriv_l<DataType, Frame> /*meta*/) const;
     745              : 
     746            0 :     void operator()(const gsl::not_null<tnsr::ij<DataType, 4, Frame>*> deriv_l,
     747              :                     const gsl::not_null<CachedBuffer*> cache,
     748              :                     internal_tags::deriv_l<DataType, Frame> /*meta*/) const;
     749              : 
     750            0 :     void operator()(const gsl::not_null<Scalar<DataType>*> lapse_squared,
     751              :                     const gsl::not_null<CachedBuffer*> cache,
     752              :                     internal_tags::lapse_squared<DataType> /*meta*/) const;
     753              : 
     754            0 :     void operator()(const gsl::not_null<Scalar<DataType>*> lapse,
     755              :                     const gsl::not_null<CachedBuffer*> cache,
     756              :                     gr::Tags::Lapse<DataType> /*meta*/) const;
     757              : 
     758            0 :     void operator()(
     759              :         const gsl::not_null<Scalar<DataType>*> deriv_lapse_multiplier,
     760              :         const gsl::not_null<CachedBuffer*> cache,
     761              :         internal_tags::deriv_lapse_multiplier<DataType> /*meta*/) const;
     762              : 
     763            0 :     void operator()(const gsl::not_null<Scalar<DataType>*> shift_multiplier,
     764              :                     const gsl::not_null<CachedBuffer*> cache,
     765              :                     internal_tags::shift_multiplier<DataType> /*meta*/) const;
     766              : 
     767            0 :     void operator()(const gsl::not_null<tnsr::I<DataType, 3, Frame>*> shift,
     768              :                     const gsl::not_null<CachedBuffer*> cache,
     769              :                     gr::Tags::Shift<DataType, 3, Frame> /*meta*/) const;
     770              : 
     771            0 :     void operator()(
     772              :         const gsl::not_null<tnsr::iJ<DataType, 3, Frame>*> deriv_shift,
     773              :         const gsl::not_null<CachedBuffer*> cache,
     774              :         DerivShift<DataType, Frame> /*meta*/) const;
     775              : 
     776            0 :     void operator()(
     777              :         const gsl::not_null<tnsr::ii<DataType, 3, Frame>*> spatial_metric,
     778              :         const gsl::not_null<CachedBuffer*> cache,
     779              :         gr::Tags::SpatialMetric<DataType, 3, Frame> /*meta*/) const;
     780              : 
     781            0 :     void operator()(
     782              :         const gsl::not_null<tnsr::II<DataType, 3, Frame>*>
     783              :             inverse_spatial_metric,
     784              :         const gsl::not_null<CachedBuffer*> cache,
     785              :         gr::Tags::InverseSpatialMetric<DataType, 3, Frame> /*meta*/) const;
     786              : 
     787            0 :     void operator()(const gsl::not_null<tnsr::ijj<DataType, 3, Frame>*>
     788              :                         deriv_spatial_metric,
     789              :                     const gsl::not_null<CachedBuffer*> cache,
     790              :                     DerivSpatialMetric<DataType, Frame> /*meta*/) const;
     791              : 
     792            0 :     void operator()(
     793              :         const gsl::not_null<tnsr::ii<DataType, 3, Frame>*> dt_spatial_metric,
     794              :         const gsl::not_null<CachedBuffer*> cache,
     795              :         ::Tags::dt<gr::Tags::SpatialMetric<DataType, 3, Frame>> /*meta*/) const;
     796              : 
     797            0 :     void operator()(
     798              :         const gsl::not_null<tnsr::ii<DataType, 3, Frame>*> extrinsic_curvature,
     799              :         const gsl::not_null<CachedBuffer*> cache,
     800              :         gr::Tags::ExtrinsicCurvature<DataType, 3, Frame> /*meta*/) const;
     801              : 
     802            0 :     void operator()(
     803              :         const gsl::not_null<tnsr::ijj<DataType, 3, Frame>*>
     804              :             christoffel_first_kind,
     805              :         const gsl::not_null<CachedBuffer*> cache,
     806              :         gr::Tags::SpatialChristoffelFirstKind<DataType, 3, Frame> /*meta*/)
     807              :         const;
     808              : 
     809            0 :     void operator()(
     810              :         const gsl::not_null<tnsr::Ijj<DataType, 3, Frame>*>
     811              :             christoffel_second_kind,
     812              :         const gsl::not_null<CachedBuffer*> cache,
     813              :         gr::Tags::SpatialChristoffelSecondKind<DataType, 3, Frame> /*meta*/)
     814              :         const;
     815              : 
     816              :    private:
     817            0 :     const SphericalKerrSchild& solution_;
     818            0 :     const tnsr::I<DataType, 3, Frame>& x_;
     819              :     // Here null_vector_0 is simply -1, but if you have a boosted solution,
     820              :     // then null_vector_0 can be something different, so we leave it coded
     821              :     // in instead of eliminating it.
     822            0 :     static constexpr double null_vector_0_ = -1.0;
     823              :   };
     824              : 
     825              :   template <typename DataType, typename Frame = ::Frame::Inertial>
     826            0 :   class IntermediateVars : public CachedBuffer<DataType, Frame> {
     827              :    public:
     828            0 :     using CachedBuffer = SphericalKerrSchild::CachedBuffer<DataType, Frame>;
     829              :     using CachedBuffer::CachedBuffer;
     830            1 :     using CachedBuffer::get_var;
     831              : 
     832            0 :     tnsr::i<DataType, 3, Frame> get_var(
     833              :         const IntermediateComputer<DataType, Frame>& computer,
     834              :         DerivLapse<DataType, Frame> /*meta*/);
     835              : 
     836            0 :     Scalar<DataType> get_var(
     837              :         const IntermediateComputer<DataType, Frame>& computer,
     838              :         ::Tags::dt<gr::Tags::Lapse<DataType>> /*meta*/);
     839              : 
     840            0 :     tnsr::I<DataType, 3, Frame> get_var(
     841              :         const IntermediateComputer<DataType, Frame>& computer,
     842              :         ::Tags::dt<gr::Tags::Shift<DataType, 3, Frame>> /*meta*/);
     843              : 
     844            0 :     Scalar<DataType> get_var(
     845              :         const IntermediateComputer<DataType, Frame>& computer,
     846              :         gr::Tags::SqrtDetSpatialMetric<DataType> /*meta*/);
     847              : 
     848            0 :     tnsr::i<DataType, 3, Frame> get_var(
     849              :         const IntermediateComputer<DataType, Frame>& computer,
     850              :         gr::Tags::DerivDetSpatialMetric<DataType, 3, Frame> /*meta*/);
     851              : 
     852            0 :     Scalar<DataType> get_var(
     853              :         const IntermediateComputer<DataType, Frame>& computer,
     854              :         gr::Tags::TraceExtrinsicCurvature<DataType> /*meta*/);
     855              : 
     856            0 :     tnsr::I<DataType, 3, Frame> get_var(
     857              :         const IntermediateComputer<DataType, Frame>& computer,
     858              :         gr::Tags::TraceSpatialChristoffelSecondKind<DataType, 3,
     859              :                                                     Frame> /*meta*/);
     860              : 
     861              :    private:
     862              :     // Here null_vector_0 is simply -1, but if you have a boosted solution,
     863              :     // then null_vector_0 can be something different, so we leave it coded
     864              :     // in instead of eliminating it.
     865            0 :     static constexpr double null_vector_0_ = -1.0;
     866              :   };
     867              : 
     868              :  private:
     869            0 :   double mass_{std::numeric_limits<double>::signaling_NaN()};
     870            0 :   std::array<double, volume_dim> dimensionless_spin_ =
     871              :       make_array<volume_dim>(std::numeric_limits<double>::signaling_NaN());
     872            0 :   std::array<double, volume_dim> center_ =
     873              :       make_array<volume_dim>(std::numeric_limits<double>::signaling_NaN());
     874              : };
     875              : 
     876            0 : bool operator==(const SphericalKerrSchild& lhs, const SphericalKerrSchild& rhs);
     877              : 
     878            0 : bool operator!=(const SphericalKerrSchild& lhs, const SphericalKerrSchild& rhs);
     879              : 
     880              : }  // namespace Solutions
     881              : }  // namespace gr
        

Generated by: LCOV version 2.0-1