SpECTRE Documentation Coverage Report
Current view: top level - DataStructures/Tensor/Expressions - IndexPropertyCheck.hpp Hit Total Coverage
Commit: 3c072f0ce967e2e56649d3fa12aa2a0e4fe2a42e Lines: 0 1 0.0 %
Date: 2024-04-23 20:50:18
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 1.14