SpECTRE Documentation Coverage Report
Current view: top level - DataStructures/Tensor/EagerMath - FrameTransform.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 95.0 % 20 19
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 <cstddef>
       7              : 
       8              : #include "DataStructures/DataBox/Tag.hpp"
       9              : #include "DataStructures/Tensor/Metafunctions.hpp"
      10              : #include "DataStructures/Tensor/TypeAliases.hpp"
      11              : #include "Utilities/Gsl.hpp"
      12              : 
      13              : /// \cond
      14              : class DataVector;
      15              : /// \endcond
      16              : 
      17              : /// Holds functions related to transforming between frames.
      18            1 : namespace transform {
      19              : /// @{
      20              : /*!
      21              :  * \ingroup GeneralRelativityGroup
      22              :  * Transforms tensor to different frame.
      23              :  *
      24              :  * The formula for transforming \f$T_{ij}\f$ is
      25              :  * \f{align}
      26              :  *   T_{\bar{\imath}\bar{\jmath}} &= T_{ij}
      27              :  *      \frac{\partial x^i}{\partial x^{\bar{\imath}}}
      28              :  *      \frac{\partial x^j}{\partial x^{\bar{\jmath}}}
      29              :  * \f}
      30              :  * where \f$x^i\f$ are the source coordinates and
      31              :  * \f$x^{\bar{\imath}}\f$ are the destination coordinates.
      32              :  *
      33              :  * Note that `Jacobian<DestFrame,SrcFrame>` is the same type as
      34              :  * `InverseJacobian<SrcFrame,DestFrame>` and represents
      35              :  * \f$\partial x^i/\partial x^{\bar{\jmath}}\f$.
      36              :  */
      37              : template <typename DataType, size_t VolumeDim, typename SrcFrame,
      38              :           typename DestFrame>
      39            1 : void to_different_frame(
      40              :     const gsl::not_null<tnsr::ii<DataType, VolumeDim, DestFrame>*> dest,
      41              :     const tnsr::ii<DataType, VolumeDim, SrcFrame>& src,
      42              :     const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian);
      43              : 
      44              : template <typename DataType, size_t VolumeDim, typename SrcFrame,
      45              :           typename DestFrame>
      46            1 : auto to_different_frame(
      47              :     const tnsr::ii<DataType, VolumeDim, SrcFrame>& src,
      48              :     const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian)
      49              :     -> tnsr::ii<DataType, VolumeDim, DestFrame>;
      50              : /// @}
      51              : 
      52              : /// @{
      53              : /*!
      54              :  * \ingroup GeneralRelativityGroup
      55              :  * \brief Transforms a tensor to a different frame.
      56              :  *
      57              :  * The tensor being transformed is always assumed to have density zero. In
      58              :  * particular `Scalar` is assumed to be invariant under transformations.
      59              :  *
      60              :  * \warning The \p jacobian argument is the derivative of the *source*
      61              :  * coordinates with respect to the *destination* coordinates.
      62              :  */
      63              : template <typename DataType, size_t VolumeDim, typename SrcFrame,
      64              :           typename DestFrame>
      65            1 : void to_different_frame(
      66              :     const gsl::not_null<Scalar<DataType>*> dest, const Scalar<DataType>& src,
      67              :     const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
      68              :     const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
      69              :         inv_jacobian);
      70              : 
      71              : template <typename DataType, size_t VolumeDim, typename SrcFrame,
      72              :           typename DestFrame>
      73            1 : auto to_different_frame(
      74              :     Scalar<DataType> src,
      75              :     const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
      76              :     const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
      77              :         inv_jacobian) -> Scalar<DataType>;
      78              : 
      79              : template <typename DataType, size_t VolumeDim, typename SrcFrame,
      80              :           typename DestFrame>
      81            1 : void to_different_frame(
      82              :     const gsl::not_null<tnsr::I<DataType, VolumeDim, DestFrame>*> dest,
      83              :     const tnsr::I<DataType, VolumeDim, SrcFrame>& src,
      84              :     const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
      85              :     const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
      86              :         inv_jacobian);
      87              : 
      88              : template <typename DataType, size_t VolumeDim, typename SrcFrame,
      89              :           typename DestFrame>
      90            1 : auto to_different_frame(
      91              :     const tnsr::I<DataType, VolumeDim, SrcFrame>& src,
      92              :     const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
      93              :     const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
      94              :         inv_jacobian) -> tnsr::I<DataType, VolumeDim, DestFrame>;
      95              : 
      96              : template <typename DataType, size_t VolumeDim, typename SrcFrame,
      97              :           typename DestFrame>
      98            1 : void to_different_frame(
      99              :     const gsl::not_null<tnsr::i<DataType, VolumeDim, DestFrame>*> dest,
     100              :     const tnsr::i<DataType, VolumeDim, SrcFrame>& src,
     101              :     const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
     102              :     const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
     103              :         inv_jacobian);
     104              : 
     105              : template <typename DataType, size_t VolumeDim, typename SrcFrame,
     106              :           typename DestFrame>
     107            1 : auto to_different_frame(
     108              :     const tnsr::i<DataType, VolumeDim, SrcFrame>& src,
     109              :     const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
     110              :     const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
     111              :         inv_jacobian) -> tnsr::i<DataType, VolumeDim, DestFrame>;
     112              : 
     113              : template <typename DataType, size_t VolumeDim, typename SrcFrame,
     114              :           typename DestFrame>
     115            1 : void to_different_frame(
     116              :     const gsl::not_null<tnsr::iJ<DataType, VolumeDim, DestFrame>*> dest,
     117              :     const tnsr::iJ<DataType, VolumeDim, SrcFrame>& src,
     118              :     const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
     119              :     const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
     120              :         inv_jacobian);
     121              : 
     122              : template <typename DataType, size_t VolumeDim, typename SrcFrame,
     123              :           typename DestFrame>
     124            1 : auto to_different_frame(
     125              :     const tnsr::iJ<DataType, VolumeDim, SrcFrame>& src,
     126              :     const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
     127              :     const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
     128              :         inv_jacobian) -> tnsr::iJ<DataType, VolumeDim, DestFrame>;
     129              : 
     130              : template <typename DataType, size_t VolumeDim, typename SrcFrame,
     131              :           typename DestFrame>
     132            1 : void to_different_frame(
     133              :     const gsl::not_null<tnsr::ii<DataType, VolumeDim, DestFrame>*> dest,
     134              :     const tnsr::ii<DataType, VolumeDim, SrcFrame>& src,
     135              :     const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
     136              :     const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
     137              :         inv_jacobian);
     138              : 
     139              : template <typename DataType, size_t VolumeDim, typename SrcFrame,
     140              :           typename DestFrame>
     141            1 : auto to_different_frame(
     142              :     const tnsr::ii<DataType, VolumeDim, SrcFrame>& src,
     143              :     const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
     144              :     const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
     145              :         inv_jacobian) -> tnsr::ii<DataType, VolumeDim, DestFrame>;
     146              : 
     147              : template <typename DataType, size_t VolumeDim, typename SrcFrame,
     148              :           typename DestFrame>
     149            1 : void to_different_frame(
     150              :     const gsl::not_null<tnsr::II<DataType, VolumeDim, DestFrame>*> dest,
     151              :     const tnsr::II<DataType, VolumeDim, SrcFrame>& src,
     152              :     const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
     153              :     const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
     154              :         inv_jacobian);
     155              : 
     156              : template <typename DataType, size_t VolumeDim, typename SrcFrame,
     157              :           typename DestFrame>
     158            1 : auto to_different_frame(
     159              :     const tnsr::II<DataType, VolumeDim, SrcFrame>& src,
     160              :     const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
     161              :     const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
     162              :         inv_jacobian) -> tnsr::II<DataType, VolumeDim, DestFrame>;
     163              : 
     164              : template <typename DataType, size_t VolumeDim, typename SrcFrame,
     165              :           typename DestFrame>
     166            1 : void to_different_frame(
     167              :     const gsl::not_null<tnsr::ijj<DataType, VolumeDim, DestFrame>*> dest,
     168              :     const tnsr::ijj<DataType, VolumeDim, SrcFrame>& src,
     169              :     const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
     170              :     const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
     171              :         inv_jacobian);
     172              : 
     173              : template <typename DataType, size_t VolumeDim, typename SrcFrame,
     174              :           typename DestFrame>
     175            1 : auto to_different_frame(
     176              :     const tnsr::ijj<DataType, VolumeDim, SrcFrame>& src,
     177              :     const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
     178              :     const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
     179              :         inv_jacobian) -> tnsr::ijj<DataType, VolumeDim, DestFrame>;
     180              : /// @}
     181              : 
     182              : /// @{
     183              : /*!
     184              :  * \ingroup GeneralRelativityGroup
     185              :  * Transforms only the first index to different frame.
     186              :  *
     187              :  * ## Examples for transforming some tensors
     188              :  *
     189              :  * ### Flux vector to logical coordinates
     190              :  *
     191              :  * A common example is taking the divergence of a flux vector $F^i$, where the
     192              :  * index $i$ is in inertial coordinates $x^i$ and the divergence is taken in
     193              :  * logical coordinates $\xi^\hat{i}$. So to transform the flux vector to logical
     194              :  * coordinates before taking the divergence we do this:
     195              :  *
     196              :  * \f{align}
     197              :  *   F^\hat{i} &= F^i \frac{\partial x^\hat{i}}{\partial x^i}
     198              :  * \f}
     199              :  *
     200              :  * Here, $\frac{\partial x^\hat{i}}{\partial x^i}$ is the inverse Jacobian (see
     201              :  * definitions in TypeAliases.hpp).
     202              :  *
     203              :  * Currently, this function is tested for any tensor with a first upper spatial
     204              :  * index. It can be extended/generalized to other tensor types if needed.
     205              :  */
     206              : template <typename ResultTensor, typename InputTensor, typename DataType,
     207              :           size_t Dim, typename SourceFrame, typename TargetFrame>
     208            1 : void first_index_to_different_frame(
     209              :     gsl::not_null<ResultTensor*> result, const InputTensor& input,
     210              :     const InverseJacobian<DataType, Dim, SourceFrame, TargetFrame>&
     211              :         inv_jacobian);
     212              : 
     213              : template <typename InputTensor, typename DataType, size_t Dim,
     214              :           typename SourceFrame, typename TargetFrame,
     215              :           typename ResultTensor = TensorMetafunctions::prepend_spatial_index<
     216              :               TensorMetafunctions::remove_first_index<InputTensor>, Dim,
     217              :               UpLo::Up, SourceFrame>>
     218            1 : ResultTensor first_index_to_different_frame(
     219              :     const InputTensor& input,
     220              :     const InverseJacobian<DataType, Dim, SourceFrame, TargetFrame>&
     221              :         inv_jacobian);
     222              : /// @}
     223              : }  // namespace transform
        

Generated by: LCOV version 2.0-1