SpECTRE Documentation Coverage Report
Current view: top level - PointwiseFunctions/GeneralRelativity/Surfaces - Spin.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 77.8 % 9 7
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 <array>
       7              : 
       8              : #include "DataStructures/Tensor/TypeAliases.hpp"
       9              : #include "NumericalAlgorithms/Strahlkorper/TagsTypeAliases.hpp"
      10              : 
      11              : /// \cond
      12              : class DataVector;
      13              : namespace ylm {
      14              : template <typename Frame>
      15              : class Strahlkorper;
      16              : }  // namespace ylm
      17              : namespace gsl {
      18              : template <typename>
      19              : struct not_null;
      20              : }  // namespace gsl
      21              : /// \endcond
      22              : 
      23              : namespace gr::surfaces {
      24              : /// @{
      25              : /*!
      26              :  * \ingroup SurfacesGroup
      27              :  * \brief Spin function of a 2D `Strahlkorper`.
      28              :  *
      29              :  * \details See Eqs. (2) and (10)
      30              :  * of \cite Owen2017yaj. This function computes the
      31              :  * "spin function," which is an ingredient for horizon surface integrals that
      32              :  * measure quasilocal spin. This function is proportional to the imaginary part
      33              :  * of the horizon's complex scalar curvature. For Kerr black holes, the spin
      34              :  * function is proportional to the horizon vorticity. It is also useful for
      35              :  * visualizing the direction of a black hole's spin.
      36              :  * Specifically, this function computes
      37              :  * \f$\Omega = \epsilon^{AB}\nabla_A\omega_B\f$,
      38              :  * where capital indices index the tangent bundle of the surface and
      39              :  * where \f$\omega_\mu=(K_{\rho\nu}-K g_{\rho\nu})h_\mu^\rho s^\nu\f$ is
      40              :  * the curl of the angular momentum density of the surface,
      41              :  * \f$h^\rho_\mu = \delta_\mu^\rho + u_\mu u^\rho - s_\mu s^\rho\f$
      42              :  * is the projector tangent to the 2-surface,
      43              :  * \f$g_{\rho\nu} = \psi_{\rho\nu} + u_\rho u_\nu\f$ is the spatial
      44              :  * metric of the spatial slice, \f$u^\rho\f$ is the unit normal to the
      45              :  * spatial slice, and \f$s^\nu\f$ is the unit normal vector to the surface.
      46              :  * Because the tangent basis vectors \f$e_A^\mu\f$ are
      47              :  * orthogonal to both \f$u^\mu\f$ and \f$s^\mu\f$, it is straightforward
      48              :  * to show that \f$\Omega = \epsilon^{AB} \nabla_A K_{B\mu}s^\mu\f$.
      49              :  * This function uses the tangent vectors of the `Strahlkorper` to
      50              :  * compute \f$K_{B\mu}s^\mu\f$ and then numerically computes the
      51              :  * components of its gradient. The argument `area_element`
      52              :  * can be computed via `gr::surfaces::area_element`.
      53              :  * The argument `unit_normal_vector` can be found by raising the
      54              :  * index of the one-form returned by `gr::surfaces::unit_normal_oneform`.
      55              :  * The argument `tangents` is a Tangents that can be obtained from the
      56              :  * StrahlkorperDataBox using the `ylm::Tags::Tangents` tag.
      57              :  */
      58              : template <typename Frame>
      59            1 : void spin_function(gsl::not_null<Scalar<DataVector>*> result,
      60              :                    const ylm::Tags::aliases::Jacobian<Frame>& tangents,
      61              :                    const ylm::Strahlkorper<Frame>& strahlkorper,
      62              :                    const tnsr::I<DataVector, 3, Frame>& unit_normal_vector,
      63              :                    const Scalar<DataVector>& area_element,
      64              :                    const tnsr::ii<DataVector, 3, Frame>& extrinsic_curvature);
      65              : 
      66              : template <typename Frame>
      67            1 : Scalar<DataVector> spin_function(
      68              :     const ylm::Tags::aliases::Jacobian<Frame>& tangents,
      69              :     const ylm::Strahlkorper<Frame>& strahlkorper,
      70              :     const tnsr::I<DataVector, 3, Frame>& unit_normal_vector,
      71              :     const Scalar<DataVector>& area_element,
      72              :     const tnsr::ii<DataVector, 3, Frame>& extrinsic_curvature);
      73              : /// @}
      74              : 
      75              : /// @{
      76              : /*!
      77              :  * \ingroup SurfacesGroup
      78              :  * \brief Spin magnitude measured on a 2D `Strahlkorper`.
      79              :  *
      80              :  * \details Measures the quasilocal spin magnitude of a Strahlkorper, by
      81              :  * inserting \f$\alpha=1\f$ into Eq. (10) of \cite Owen2009sb
      82              :  * and dividing by \f$8\pi\f$ to yield the spin magnitude. The
      83              :  * spin magnitude is a Euclidean norm of surface integrals over the horizon
      84              :  * \f$S = \frac{1}{8\pi}\oint z \Omega dA\f$,
      85              :  * where \f$\Omega\f$ is obtained via `gr::surfaces::spin_function()`,
      86              :  * \f$dA\f$ is the area element, and \f$z\f$ (the "spin potential") is a
      87              :  * solution of a generalized eigenproblem given by Eq. (9) of
      88              :  * \cite Owen2009sb. Specifically,
      89              :  * \f$\nabla^4 z + \nabla \cdot (R\nabla z) = \lambda \nabla^2 z\f$, where
      90              :  * \f$R\f$ is obtained via `gr::surfaces::ricci_scalar()`. The spin
      91              :  * magnitude is the Euclidean norm of the three values of \f$S\f$ obtained from
      92              :  * the eigenvectors \f$z\f$ with the 3 smallest-magnitude
      93              :  * eigenvalues \f$\lambda\f$. Note that this formulation of the eigenproblem
      94              :  * uses the "Owen" normalization, Eq. (A9) and surrounding discussion in
      95              :  * \cite Lovelace2008tw.
      96              :  * The eigenvectors are normalized  with the "Kerr normalization",
      97              :  * Eq. (A22) of \cite Lovelace2008tw.
      98              :  * The argument `spatial_metric` is the metric of the 3D spatial slice
      99              :  * evaluated on the `Strahlkorper`.
     100              :  * The argument `tangents` can be obtained from the StrahlkorperDataBox
     101              :  * using the `ylm::Tags::Tangents` tag, and the argument
     102              :  * `unit_normal_vector` can
     103              :  * be found by raising the index of the one-form returned by
     104              :  * `gr::surfaces::unit_normal_one_form`.
     105              :  * The argument `strahlkorper` is the surface on which the spin magnitude is
     106              :  * computed.
     107              :  * The argument `area_element`
     108              :  * can be computed via `gr::surfaces::area_element`.
     109              :  */
     110              : template <typename Frame>
     111            1 : void dimensionful_spin_magnitude(
     112              :     gsl::not_null<double*> result, const Scalar<DataVector>& ricci_scalar,
     113              :     const Scalar<DataVector>& spin_function,
     114              :     const tnsr::ii<DataVector, 3, Frame>& spatial_metric,
     115              :     const ylm::Tags::aliases::Jacobian<Frame>& tangents,
     116              :     const ylm::Strahlkorper<Frame>& strahlkorper,
     117              :     const Scalar<DataVector>& area_element);
     118              : 
     119              : template <typename Frame>
     120            1 : double dimensionful_spin_magnitude(
     121              :     const Scalar<DataVector>& ricci_scalar,
     122              :     const Scalar<DataVector>& spin_function,
     123              :     const tnsr::ii<DataVector, 3, Frame>& spatial_metric,
     124              :     const ylm::Tags::aliases::Jacobian<Frame>& tangents,
     125              :     const ylm::Strahlkorper<Frame>& strahlkorper,
     126              :     const Scalar<DataVector>& area_element);
     127              : /// @}
     128              : 
     129              : /// @{
     130              : /*!
     131              :  * \ingroup SurfacesGroup
     132              :  * \brief Dimensionless spin magnitude of a `Strahlkorper`.
     133              :  *
     134              :  * \details
     135              :  * This function computes the dimensionless spin magnitude \f$\chi\f$
     136              :  * from the dimensionful spin magnitude \f$S\f$ and the christodoulou
     137              :  * mass \f$M\f$ of a black hole. Specifically, computes
     138              :  * \f$\chi = \frac{S}{M^2}\f$.
     139              :  */
     140              : 
     141            1 : void dimensionless_spin_magnitude(const gsl::not_null<double*> result,
     142              :                                   const double dimensionful_spin_magnitude,
     143              :                                   const double christodoulou_mass);
     144              : 
     145            1 : double dimensionless_spin_magnitude(const double dimensionful_spin_magnitude,
     146              :                                     const double christodoulou_mass);
     147              : /// @}
     148              : 
     149              : /*!
     150              :  * \ingroup SurfacesGroup
     151              :  * \brief Spin vector of a 2D `Strahlkorper`.
     152              :  *
     153              :  * \details Computes the spin vector of a `Strahlkorper` in a
     154              :  * `MeasurementFrame`, such as `Frame::Inertial`. The result is a
     155              :  * `std::array<double, 3>` containing the Cartesian components (in
     156              :  * `MeasurementFrame`) of the spin vector whose magnitude is
     157              :  * `spin_magnitude`. `spin_vector` will return the dimensionless spin
     158              :  * components if `spin_magnitude` is the dimensionless spin magnitude,
     159              :  * and it will return the dimensionful spin components if
     160              :  * `spin_magnitude` is the dimensionful spin magnitude. The spin
     161              :  * vector is given by
     162              :  * a surface integral over the horizon \f$\mathcal{H}\f$ [Eq. (25) of
     163              :  * \cite Owen2017yaj]:
     164              :  * \f$S^i = \frac{S}{N} \oint_\mathcal{H} dA \Omega (x^i - x^i_0 - x^i_R) \f$,
     165              :  * where \f$S\f$ is the spin magnitude,
     166              :  * \f$N\f$ is a normalization factor enforcing \f$\delta_{ij}S^iS^j = S\f$,
     167              :  * \f$dA\f$ is the area element (via `gr::surfaces::area_element`),
     168              :  * \f$\Omega\f$ is the "spin function" (via `gr::surfaces::spin_function`),
     169              :  * \f$x^i\f$ are the `MeasurementFrame` coordinates of points on
     170              :  * the `Strahlkorper`,
     171              :  * \f$x^i_0\f$ are the `MeasurementFrame` coordinates of the center
     172              :  * of the Strahlkorper,
     173              :  * \f$x^i_R = \frac{1}{8\pi}\oint_\mathcal{H} dA (x^i - x^i_0) R \f$,
     174              :  * and \f$R\f$ is the intrinsic Ricci scalar of the `Strahlkorper`
     175              :  * (via `gr::surfaces::ricci_scalar`).
     176              :  * Note that measuring positions on the horizon relative to
     177              :  * \f$x^i_0 + x^i_R\f$ instead of \f$x^i_0\f$ ensures that the mass dipole
     178              :  * moment vanishes.
     179              :  *
     180              :  * \param result The computed spin vector in `MeasurementFrame`.
     181              :  * \param spin_magnitude The spin magnitude.
     182              :  * \param area_element The area element on `strahlkorper`'s
     183              :  *        collocation points.
     184              :  * \param ricci_scalar The intrinsic ricci scalar on `strahlkorper`'s
     185              :  *        collocation points.
     186              :  * \param spin_function The spin function on `strahlkorper`'s
     187              :  *        collocation points.
     188              :  * \param strahlkorper The Strahlkorper in the `MetricDataFrame` frame.
     189              :  * \param measurement_frame_coords The Cartesian coordinates of `strahlkorper`'s
     190              :  * collocation points, mapped to `MeasurementFrame`.
     191              :  *
     192              :  * Note that `spin_vector` uses two frames: the Strahlkorper and all of the
     193              :  * metric quantities are in `MetricDataFrame` and are used for doing integrals,
     194              :  * but the `measurement_frame_coordinates` are in `MeasurementFrame` and are
     195              :  * used for making sure the result is in the appropriate frame.  The two frames
     196              :  * `MeasurementFrame` and `MetricDataFrame` may or may not be the same.
     197              :  * In principle, spin_vector could be written using only a single frame
     198              :  * (`MeasurementFrame`) but that would require that the metric quantities
     199              :  * are known on the collocation points of a Strahlkorper in `MeasurementFrame`,
     200              :  * which would involve more interpolation.
     201              :  */
     202              : template <typename MetricDataFrame, typename MeasurementFrame>
     203            1 : void spin_vector(
     204              :     const gsl::not_null<std::array<double, 3>*> result, double spin_magnitude,
     205              :     const Scalar<DataVector>& area_element,
     206              :     const Scalar<DataVector>& ricci_scalar,
     207              :     const Scalar<DataVector>& spin_function,
     208              :     const ylm::Strahlkorper<MetricDataFrame>& strahlkorper,
     209              :     const tnsr::I<DataVector, 3, MeasurementFrame>& measurement_frame_coords);
     210              : 
     211              : template <typename MetricDataFrame, typename MeasurementFrame>
     212            0 : std::array<double, 3> spin_vector(
     213              :     double spin_magnitude, const Scalar<DataVector>& area_element,
     214              :     const Scalar<DataVector>& ricci_scalar,
     215              :     const Scalar<DataVector>& spin_function,
     216              :     const ylm::Strahlkorper<MetricDataFrame>& strahlkorper,
     217              :     const tnsr::I<DataVector, 3, MeasurementFrame>& measurement_frame_coords);
     218              : }  // namespace gr::surfaces
        

Generated by: LCOV version 2.0-1