SpECTRE Documentation Coverage Report
Current view: top level - DataStructures/Tensor/Expressions - IndexPropertyCheck.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 0.0 % 1 0
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 <type_traits>
       7              : 
       8              : #include "DataStructures/Tensor/Expressions/TensorIndex.hpp"
       9              : #include "DataStructures/Tensor/Expressions/TimeIndex.hpp"
      10              : #include "DataStructures/Tensor/IndexType.hpp"
      11              : #include "Utilities/TMPL.hpp"
      12              : 
      13              : namespace tenex {
      14              : namespace detail {
      15              : /// @{
      16              : /// \brief Helper struct for checking that one tensor's index is either a
      17              : /// spacetime index where a concrete time index has been used or can be
      18              : /// assigned to, added to, or subtracted from its corresponding index in another
      19              : /// tensor
      20              : ///
      21              : /// \details
      22              : /// Indices in one tensor correspond to those in another that use the same
      23              : /// generic index, such as `ti::a`. For it to be possible to add, subtract, or
      24              : /// assign one index to another, this checks that the following is true for the
      25              : /// index and its corresponding index in another tensor:
      26              : /// - has the same valence (`UpLo`)
      27              : /// - has the same `Frame` type
      28              : /// - has the same number of spatial dimensions (allowing for expressions that
      29              : ///   use generic spatial indices for spacetime indices on either side)
      30              : ///
      31              : /// \tparam IndexList1 the first tensor's \ref SpacetimeIndex "TensorIndexType"
      32              : /// list
      33              : /// \tparam IndexList2 the second tensor's \ref SpacetimeIndex "TensorIndexType"
      34              : /// list
      35              : /// \tparam TensorIndexList1 the first tensor's generic index list
      36              : /// \tparam TensorIndexList2 the second tensor's generic index list
      37              : /// \tparam CurrentTensorIndex1 the current generic index of the first tensor
      38              : /// that is being checked, e.g. the type of `ti::a`
      39              : /// \tparam Iteration the position of the current index of the first tensor
      40              : /// being checked, e.g. the position of `ti::a` in the first tensor
      41              : template <typename IndexList1, typename IndexList2, typename TensorIndexList1,
      42              :           typename TensorIndexList2, typename CurrentTensorIndex1,
      43              :           typename Iteration>
      44              : struct IndexPropertyCheckImpl {
      45              :   using index1 = tmpl::at<IndexList1, Iteration>;
      46              :   using index2 =
      47              :       tmpl::at<IndexList2,
      48              :                tmpl::index_of<TensorIndexList2, CurrentTensorIndex1>>;
      49              : 
      50              :   using type = std::bool_constant<
      51              :       index1::ul == index2::ul and
      52              :       std::is_same_v<typename index1::Frame, typename index2::Frame> and
      53              :       ((index1::index_type == index2::index_type and
      54              :         index1::dim == index2::dim) or
      55              :        (index1::index_type == IndexType::Spacetime and
      56              :         index1::dim == index2::dim + 1) or
      57              :        (index2::index_type == IndexType::Spacetime and
      58              :         index1::dim + 1 == index2::dim))>;
      59              : };
      60              : 
      61              : template <typename IndexList1, typename IndexList2, typename TensorIndexList1,
      62              :           typename TensorIndexList2, typename Iteration>
      63              : struct IndexPropertyCheckImpl<IndexList1, IndexList2, TensorIndexList1,
      64              :                               TensorIndexList2, std::decay_t<decltype(ti::T)>,
      65              :                               Iteration> {
      66              :   using index1 = tmpl::at<IndexList1, Iteration>;
      67              :   using type = std::bool_constant<index1::index_type == IndexType::Spacetime>;
      68              : };
      69              : 
      70              : template <typename IndexList1, typename IndexList2, typename TensorIndexList1,
      71              :           typename TensorIndexList2, typename Iteration>
      72              : struct IndexPropertyCheckImpl<IndexList1, IndexList2, TensorIndexList1,
      73              :                               TensorIndexList2, std::decay_t<decltype(ti::t)>,
      74              :                               Iteration> {
      75              :   using index1 = tmpl::at<IndexList1, Iteration>;
      76              :   using type = std::bool_constant<index1::index_type == IndexType::Spacetime>;
      77              : };
      78              : /// @}
      79              : 
      80              : /// \brief Helper struct for checking that one tensor's indices can be
      81              : /// mathematically assigned to, added to, or subtracted from their
      82              : /// corresponding indices in another tensor
      83              : ///
      84              : /// \details
      85              : /// This struct checks that:
      86              : /// (1) The shared generic indices between the two index lists can be
      87              : /// mathematically assigned to, added to, or subtracted from one another
      88              : /// (2) Any non-shared indices are spacetime indices where a concrete time index
      89              : /// has been used
      90              : ///
      91              : /// This struct checks that (2) is true for the second tensor's time indices and
      92              : /// calls `IndexPropertyCheckImpl` to check that (2) is true for the first
      93              : /// tensor's time indices and that (1) is true. To see more details regarding
      94              : /// how (1) is checked, see `IndexPropertyCheckImpl`.
      95              : ///
      96              : /// \tparam IndexList1 the first tensor's \ref SpacetimeIndex "TensorIndexType"
      97              : /// list
      98              : /// \tparam IndexList2 the second tensor's \ref SpacetimeIndex "TensorIndexType"
      99              : /// list
     100              : /// \tparam TensorIndexList1 the first tensor's generic index list
     101              : /// \tparam TensorIndexList2 the second tensor's generic index list
     102              : template <typename IndexList1, typename IndexList2, typename TensorIndexList1,
     103              :           typename TensorIndexList2>
     104              : struct IndexPropertyCheckHelper;
     105              : 
     106              : template <typename IndexList1, typename... RhsIndices,
     107              :           typename TensorIndexList1, typename... RhsTensorIndices>
     108              : struct IndexPropertyCheckHelper<IndexList1, tmpl::list<RhsIndices...>,
     109              :                                 TensorIndexList1,
     110              :                                 tmpl::list<RhsTensorIndices...>> {
     111              :   static constexpr bool value =
     112              :       // Check that second tensor's concrete time indices are used with
     113              :       // spacetime indices
     114              :       (... and ((not tt::is_time_index<RhsTensorIndices>::value) or
     115              :                 (tt::is_time_index<RhsTensorIndices>::value and
     116              :                  RhsIndices::index_type == IndexType::Spacetime))) and
     117              :       // Check that:
     118              :       // - the first tensor's concrete time indices are used with spacetime
     119              :       // indices
     120              :       // - shared generic indices between the two tensors can be mathematically
     121              :       // assigned to, added to, or subtracted from one another
     122              :       (tmpl::enumerated_fold<
     123              :           TensorIndexList1, tmpl::bool_<true>,
     124              :           tmpl::and_<
     125              :               tmpl::_state,
     126              :               IndexPropertyCheckImpl<tmpl::pin<IndexList1>,
     127              :                                      tmpl::pin<tmpl::list<RhsIndices...>>,
     128              :                                      tmpl::pin<TensorIndexList1>,
     129              :                                      tmpl::pin<tmpl::list<RhsTensorIndices...>>,
     130              :                                      tmpl::_element, tmpl::_3>>,
     131              :           tmpl::size_t<0>>::value);
     132              : };
     133              : 
     134              : /// \brief Check that one tensor's indices can be mathematically assigned to,
     135              : /// added to, or subtracted from their corresponding indices in another tensor
     136              : ///
     137              : /// \details
     138              : /// For more details on what is checked, see `IndexPropertyCheckImpl` followed
     139              : /// by `IndexPropertyCheckHelper`
     140              : ///
     141              : /// \tparam IndexList1 the first tensor's \ref SpacetimeIndex "TensorIndexType"
     142              : /// list
     143              : /// \tparam IndexList2 the second tensor's \ref SpacetimeIndex "TensorIndexType"
     144              : /// list
     145              : /// \tparam TensorIndexList1 the first tensor's generic index list
     146              : /// \tparam TensorIndexList2 the second tensor's generic index list
     147              : template <typename IndexList1, typename IndexList2, typename TensorIndexList1,
     148              :           typename TensorIndexList2>
     149              : using IndexPropertyCheck =
     150              :     IndexPropertyCheckHelper<IndexList1, IndexList2, TensorIndexList1,
     151              :                              TensorIndexList2>;
     152              : }  // namespace detail
     153              : }  // namespace tenex
        

Generated by: LCOV version 2.0-1