SpECTRE Documentation Coverage Report
Current view: top level - DataStructures/Tensor - IndexType.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 69.6 % 23 16
Test Date: 2026-10-22 17:29:42
Legend: Lines:     hit not hit

            Line data    Source code
       1            1 : // Distributed under the MIT License.
       2              : // See LICENSE.txt for details.
       3              : 
       4              : /// \file
       5              : /// Defines classes representing tensor indices
       6              : 
       7              : #pragma once
       8              : 
       9              : #include <cstddef>
      10              : #include <ostream>
      11              : #include <string>
      12              : #include <type_traits>
      13              : 
      14              : #include "Utilities/Literals.hpp"
      15              : #include "Utilities/TMPL.hpp"
      16              : 
      17              : /// \ingroup TensorGroup
      18              : /// Whether a \ref SpacetimeIndex "TensorIndexType" is covariant or
      19              : /// contravariant
      20            1 : enum class UpLo {
      21              :   /// Contravariant, or Upper index
      22              :   Up,
      23              :   /// Covariant, or Lower index
      24              :   Lo
      25              : };
      26              : 
      27              : /// \cond HIDDEN_SYMBOLS
      28              : inline std::ostream& operator<<(std::ostream& os, const UpLo& ul) {
      29              :   return os << (ul == UpLo::Up ? "Up"s : "Lo"s);
      30              : }
      31              : /// \endcond
      32              : 
      33              : /// \ingroup TensorGroup
      34              : /// Indicates the ::Frame that a \ref SpacetimeIndex "TensorIndexType"
      35              : /// is in.
      36            1 : namespace Frame {
      37              : /// \ingroup TensorGroup
      38              : /// Marks a Frame as being "physical" in the sense that it is meaningful to
      39              : /// evaluate an analytic solution in that frame.
      40            1 : struct FrameIsPhysical {};
      41              : 
      42            0 : struct BlockLogical {};
      43            0 : struct ElementLogical {};
      44            0 : struct Fluid {};
      45            0 : struct Grid {};
      46            0 : struct Inertial : FrameIsPhysical {};
      47            0 : struct Distorted {};
      48              : /// Represents an index that is not in a known frame, e.g. some internal
      49              : /// intermediate frame that is irrelevant to the interface.
      50            1 : struct NoFrame {};
      51              : 
      52              : /// Represents a spherical-coordinate frame that is associated with a
      53              : /// Cartesian frame, e.g. \f$(r,\theta,\phi)\f$ associated with the Inertial
      54              : /// frame, as used on an apparent horizon or a wave-extraction surface.
      55              : template <typename CartesianFrame>
      56            1 : struct Spherical {};
      57              : 
      58              : /// \ingroup TensorGroup
      59              : /// Returns std::true_type if the frame is "physical" in the sense that it is
      60              : /// meaningful to evaluate an analytic solution in that frame.
      61              : /// \example
      62              : /// \snippet Test_Tensor.cpp is_frame_physical
      63              : template <typename CheckFrame>
      64            1 : using is_frame_physical =
      65              :     std::integral_constant<bool,
      66              :                            std::is_base_of<FrameIsPhysical, CheckFrame>::value>;
      67              : 
      68              : /// \ingroup TensorGroup
      69              : /// Returns true if the frame is "physical" in the sense that it is
      70              : /// meaningful to evaluate an analytic solution in that frame.
      71              : /// \example
      72              : /// \snippet Test_Tensor.cpp is_frame_physical
      73              : template <typename CheckFrame>
      74            1 : constexpr bool is_frame_physical_v = is_frame_physical<CheckFrame>::value;
      75              : 
      76              : /// \cond HIDDEN_SYMBOLS
      77              : inline std::ostream& operator<<(std::ostream& os,
      78              :                                 const Frame::BlockLogical& /*meta*/) {
      79              :   return os << "BlockLogical";
      80              : }
      81              : inline std::ostream& operator<<(std::ostream& os,
      82              :                                 const Frame::ElementLogical& /*meta*/) {
      83              :   return os << "ElementLogical";
      84              : }
      85              : inline std::ostream& operator<<(std::ostream& os,
      86              :                                 const Frame::Fluid& /*meta*/) {
      87              :   return os << "Fluid";
      88              : }
      89              : inline std::ostream& operator<<(std::ostream& os,
      90              :                                 const Frame::Grid& /*meta*/) {
      91              :   return os << "Grid";
      92              : }
      93              : inline std::ostream& operator<<(std::ostream& os,
      94              :                                 const Frame::Inertial& /*meta*/) {
      95              :   return os << "Inertial";
      96              : }
      97              : inline std::ostream& operator<<(std::ostream& os,
      98              :                                 const Frame::Distorted& /*meta*/) {
      99              :   return os << "Distorted";
     100              : }
     101              : inline std::ostream& operator<<(std::ostream& os,
     102              :                                 const Frame::NoFrame& /*meta*/) {
     103              :   return os << "NoFrame";
     104              : }
     105              : /// \endcond
     106              : 
     107              : /// \ingroup TensorGroup
     108              : /// The frame-dependent prefix used when constructing the string returned by the
     109              : /// name function of a tag.
     110              : ///
     111              : /// For Frame::Inertial it is the empty string, otherwise, it is the name of
     112              : /// the Frame followed by an underscore (as the name will be used in I/O).
     113              : /// \example
     114              : /// \snippet Hydro/Test_Tags.cpp prefix_example
     115              : template <typename Fr>
     116            1 : inline std::string prefix();
     117              : 
     118              : /// \cond HIDDEN_SYMBOLS
     119              : template <>
     120              : inline std::string prefix<Frame::BlockLogical>() {
     121              :   return "BlockLogical_";
     122              : }
     123              : 
     124              : template <>
     125              : inline std::string prefix<Frame::ElementLogical>() {
     126              :   return "ElementLogical_";
     127              : }
     128              : 
     129              : template <>
     130              : inline std::string prefix<Frame::Fluid>() {
     131              :   return "Fluid_";
     132              : }
     133              : 
     134              : template <>
     135              : inline std::string prefix<Frame::Grid>() {
     136              :   return "Grid_";
     137              : }
     138              : 
     139              : template <>
     140              : inline std::string prefix<Frame::Inertial>() {
     141              :   return "";
     142              : }
     143              : 
     144              : template <>
     145              : inline std::string prefix<Frame::Distorted>() {
     146              :   return "Distorted_";
     147              : }
     148              : /// \endcond
     149              : }  // namespace Frame
     150              : 
     151              : /// \ingroup TensorGroup
     152              : /// Indicates whether the \ref SpacetimeIndex "TensorIndexType" is
     153              : /// Spatial or Spacetime
     154            1 : enum class IndexType : char {
     155              :   /// The \ref SpatialIndex "TensorIndexType" is purely spatial
     156              :   Spatial,
     157              :   /// The \ref SpacetimeIndex "TensorIndexType" is a spacetime index
     158              :   Spacetime
     159              : };
     160              : 
     161              : /// \cond HIDDEN_SYMBOLS
     162              : inline std::ostream& operator<<(std::ostream& os, const IndexType& index_type) {
     163              :   return os << (index_type == IndexType::Spatial ? "Spatial" : "Spacetime");
     164              : }
     165              : /// \endcond
     166              : 
     167              : namespace Tensor_detail {
     168              : /// \ingroup TensorGroup
     169              : /// A ::TensorIndexType holds information about what type of index an index of a
     170              : /// Tensor is. It holds the information about the number of spatial dimensions,
     171              : /// whether the index is covariant or contravariant (::UpLo), the ::Frame the
     172              : /// index is in, and whether the Index is Spatial or Spacetime.
     173              : /// \tparam SpatialDim the spatial dimensionality of the TensorIndex
     174              : /// \tparam Ul either UpLo::Up or UpLo::Lo for contra or covariant
     175              : /// \tparam Fr the Frame the TensorIndex is in
     176              : /// \tparam Index either IndexType::Spatial or IndexType::Spacetime
     177              : template <size_t SpatialDim, UpLo Ul, typename Fr, IndexType Index>
     178              : struct TensorIndexType {
     179              :   static_assert(SpatialDim > 0,
     180              :                 "Cannot have a spatial dimensionality less than 1 (one) in a "
     181              :                 "TensorIndexType");
     182              :   using value_type = decltype(SpatialDim);
     183              :   static constexpr value_type dim =
     184              :       Index == IndexType::Spatial ? SpatialDim
     185              :                                   : SpatialDim + static_cast<value_type>(1);
     186              :   // value is here just so that some generic metafunctions can retrieve the dim
     187              :   // easily
     188              :   static constexpr value_type value = dim;
     189              :   static constexpr UpLo ul = Ul;
     190              :   using Frame = Fr;
     191              :   static constexpr IndexType index_type = Index;
     192              : };
     193              : }  // namespace Tensor_detail
     194              : 
     195              : /// \ingroup TensorGroup
     196              : /// A SpatialIndex holds information about the number of spatial
     197              : /// dimensions, whether the index is covariant or contravariant (::UpLo), and
     198              : /// the ::Frame the index is in.
     199              : /// \tparam SpatialDim the spatial dimensionality of the \ref
     200              : /// SpatialIndex "TensorIndexType"
     201              : /// \tparam Ul either UpLo::Up or UpLo::Lo for contra or covariant
     202              : /// \tparam Fr the ::Frame the \ref SpatialIndex "TensorIndexType"
     203              : /// is in
     204              : template <size_t SpatialDim, UpLo Ul, typename Fr>
     205            1 : using SpatialIndex =
     206              :     Tensor_detail::TensorIndexType<SpatialDim, Ul, Fr, IndexType::Spatial>;
     207              : 
     208              : /// \ingroup TensorGroup
     209              : /// A SpacetimeIndex holds information about the number of spatial
     210              : /// dimensions, whether the index is covariant or contravariant (::UpLo), and
     211              : /// the ::Frame the index is in.
     212              : ///
     213              : /// \tparam SpatialDim the spatial dimensionality of the \ref
     214              : /// SpacetimeIndex "TensorIndexType"
     215              : /// \tparam Ul either UpLo::Up or UpLo::Lo for contra or covariant
     216              : /// \tparam Fr the ::Frame the \ref SpacetimeIndex "TensorIndexType"
     217              : /// is in
     218              : template <size_t SpatialDim, UpLo Ul, typename Fr>
     219            1 : using SpacetimeIndex =
     220              :     Tensor_detail::TensorIndexType<SpatialDim, Ul, Fr, IndexType::Spacetime>;
     221              : 
     222              : namespace tt {
     223              : /// @{
     224              : /// \ingroup TensorGroup TypeTraitsGroup
     225              : /// Inherits from std::true_type if T is a \ref SpacetimeIndex
     226              : /// "TensorIndexType"
     227              : /// \tparam T the type to check
     228              : template <typename T>
     229            1 : struct is_tensor_index_type : std::false_type {};
     230              : /// \cond HIDDEN_SYMBOLS
     231              : template <size_t SpatialDim, UpLo Ul, typename Fr, IndexType Index>
     232              : struct is_tensor_index_type<
     233              :     Tensor_detail::TensorIndexType<SpatialDim, Ul, Fr, Index>>
     234              :     : std::true_type {};
     235              : /// \endcond
     236              : /// \see is_tensor_index_type
     237              : template <typename T>
     238            1 : using is_tensor_index_type_t = typename is_tensor_index_type<T>::type;
     239              : /// @}
     240              : }  // namespace tt
     241              : 
     242              : /// \ingroup TensorGroup
     243              : /// Change the \ref SpacetimeIndex "TensorIndexType" to be covariant
     244              : /// if it's contravariant and vice-versa
     245              : ///
     246              : /// Here is an example of how to use ::change_index_up_lo
     247              : /// \snippet Test_Tensor.cpp change_up_lo
     248              : ///
     249              : /// \tparam Index the \ref SpacetimeIndex "TensorIndexType" to change
     250              : template <typename Index>
     251            1 : using change_index_up_lo = Tensor_detail::TensorIndexType<
     252              :     Index::index_type == IndexType::Spatial ? Index::value : Index::value - 1,
     253              :     Index::ul == UpLo::Up ? UpLo::Lo : UpLo::Up, typename Index::Frame,
     254              :     Index::index_type>;
     255              : 
     256              : template <typename... Ts>
     257            0 : using index_list = tmpl::list<Ts...>;
     258              : 
     259              : /// \ingroup TensorGroup
     260              : /// Change the \ref SpacetimeIndex "TensorIndexType" to be spacetime
     261              : /// if it's spatial and vice versa
     262              : ///
     263              : /// \tparam Index the \ref SpacetimeIndex "TensorIndexType" to change
     264              : template <typename Index>
     265            1 : using change_index_type = Tensor_detail::TensorIndexType<
     266              :     Index::index_type == IndexType::Spatial ? Index::dim : Index::dim - 1,
     267              :     Index::ul, typename Index::Frame,
     268              :     Index::index_type == IndexType::Spatial ? IndexType::Spacetime
     269              :                                             : IndexType::Spatial>;
        

Generated by: LCOV version 2.0-1