SpECTRE Documentation Coverage Report
Current view: top level - DataStructures/Tensor - Metafunctions.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 91.7 % 12 11
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 metafunctions used by Tensor
       6              : 
       7              : #pragma once
       8              : 
       9              : #include <cstddef>
      10              : #include <cstdint>
      11              : #include <type_traits>
      12              : 
      13              : #include "DataStructures/Tensor/IndexType.hpp"
      14              : #include "Utilities/TMPL.hpp"
      15              : 
      16              : /// \cond
      17              : template <typename X, typename Symm, typename IndexList>
      18              : class Tensor;
      19              : /// \endcond
      20              : 
      21              : /// \ingroup TensorGroup
      22              : /// Contains all metafunctions related to Tensor manipulations
      23            1 : namespace TensorMetafunctions {
      24              : namespace detail {
      25              : template <unsigned>
      26              : struct check_index_symmetry_impl;
      27              : // empty typelist or only had a vector to start with
      28              : template <>
      29              : struct check_index_symmetry_impl<0> {
      30              :   template <typename...>
      31              :   using f = std::true_type;
      32              : };
      33              : 
      34              : // found incorrect symmetric index
      35              : template <>
      36              : struct check_index_symmetry_impl<1> {
      37              :   template <typename...>
      38              :   using f = std::false_type;
      39              : };
      40              : 
      41              : // recurse the list
      42              : template <>
      43              : struct check_index_symmetry_impl<2> {
      44              :   template <typename Symm, typename IndexSymm, typename Index0,
      45              :             typename... IndexPack>
      46              :   using f = typename check_index_symmetry_impl<
      47              :       tmpl::has_key<IndexSymm, tmpl::front<Symm>>::value and
      48              :               not std::is_same<Index0,
      49              :                                tmpl::at<IndexSymm, tmpl::front<Symm>>>::value
      50              :           ? 1
      51              :           : tmpl::size<Symm>::value == 1 ? 0 : 2>::
      52              :       template f<tmpl::pop_front<Symm>,
      53              :                  tmpl::insert<IndexSymm, tmpl::pair<tmpl::front<Symm>, Index0>>,
      54              :                  IndexPack...>;
      55              : };
      56              : 
      57              : // helper function for prepending indices
      58              : template <typename TheTensor>
      59              : using new_sym_index =
      60              :     tmpl::int32_t<1 +
      61              :                   tmpl::fold<typename TheTensor::symmetry, tmpl::int32_t<0>,
      62              :                              tmpl::max<tmpl::_state, tmpl::_element>>::value>;
      63              : }  // namespace detail
      64              : 
      65              : /*!
      66              :  * \ingroup TensorGroup
      67              :  * \brief Check that each of symmetric indices is in the same frame and have the
      68              :  * same dimensionality.
      69              :  */
      70              : template <typename Symm, typename... IndexPack>
      71            1 : using check_index_symmetry = typename detail::check_index_symmetry_impl<
      72              :     tmpl::size<Symm>::value == 0 or tmpl::size<Symm>::value == 1 ? 0 : 2>::
      73              :     template f<Symm, tmpl::map<>, IndexPack...>;
      74              : template <typename Symm, typename... IndexPack>
      75            0 : constexpr bool check_index_symmetry_v =
      76              :     check_index_symmetry<Symm, IndexPack...>::value;
      77              : 
      78              : /*!
      79              :  * \ingroup TensorGroup
      80              :  * \brief Add a spatial index to the front of a Tensor
      81              :  *
      82              :  * \tparam TheTensor the tensor type to which the new index is prepended
      83              :  * \tparam VolumeDim the volume dimension of the tensor index to prepend
      84              :  * \tparam Fr the ::Frame of the tensor index to prepend
      85              :  */
      86              : template <typename TheTensor, std::size_t VolumeDim, UpLo Ul, typename Fr>
      87            1 : using prepend_spatial_index =
      88              :     ::Tensor<typename TheTensor::type,
      89              :              tmpl::push_front<typename TheTensor::symmetry,
      90              :                               detail::new_sym_index<TheTensor>>,
      91              :              tmpl::push_front<typename TheTensor::index_list,
      92              :                               SpatialIndex<VolumeDim, Ul, Fr>>>;
      93              : 
      94              : /*!
      95              :  * \ingroup TensorGroup
      96              :  * \brief Add two symmetric spatial indices to the front of a Tensor (e.g. when
      97              :  * doing second derivatives)
      98              :  *
      99              :  * \tparam TheTensor the tensor type to which the new indices is prepended
     100              :  * \tparam VolumeDim the volume dimension of the tensor indices to prepend
     101              :  * \tparam Fr the ::Frame of the tensor indices to prepend
     102              :  */
     103              : template <typename TheTensor, std::size_t VolumeDim, UpLo Ul, typename Fr>
     104            1 : using prepend_two_symmetric_spatial_indices = ::Tensor<
     105              :     typename TheTensor::type,
     106              :     tmpl::push_front<tmpl::push_front<typename TheTensor::symmetry,
     107              :                                       detail::new_sym_index<TheTensor>>,
     108              :                      detail::new_sym_index<TheTensor>>,
     109              :     tmpl::push_front<tmpl::push_front<typename TheTensor::index_list,
     110              :                                       SpatialIndex<VolumeDim, Ul, Fr>>,
     111              :                      SpatialIndex<VolumeDim, Ul, Fr>>>;
     112              : 
     113              : /*!
     114              :  * \ingroup TensorGroup
     115              :  * \brief Add a spacetime index to the front of a Tensor
     116              :  *
     117              :  * \tparam TheTensor the tensor type to which the new index is prepended
     118              :  * \tparam VolumeDim the volume dimension of the tensor index to prepend
     119              :  * \tparam Fr the ::Frame of the tensor index to prepend
     120              :  */
     121              : template <typename TheTensor, std::size_t VolumeDim, UpLo Ul, typename Fr>
     122            1 : using prepend_spacetime_index =
     123              :     ::Tensor<typename TheTensor::type,
     124              :              tmpl::push_front<typename TheTensor::symmetry,
     125              :                               detail::new_sym_index<TheTensor>>,
     126              :              tmpl::push_front<typename TheTensor::index_list,
     127              :                               SpacetimeIndex<VolumeDim, Ul, Fr>>>;
     128              : 
     129              : /// \ingroup TensorGroup
     130              : /// \brief remove the first index of a tensor
     131              : /// \tparam TheTensor the tensor type whose first index is removed
     132              : template <typename TheTensor>
     133            1 : using remove_first_index =
     134              :     ::Tensor<typename TheTensor::type,
     135              :              tmpl::pop_front<typename TheTensor::symmetry>,
     136              :              tmpl::pop_front<typename TheTensor::index_list>>;
     137              : 
     138              : /// \ingroup TensorGroup
     139              : /// \brief Swap the valences of all indices on a Tensor
     140              : template <typename TheTensor>
     141            1 : using change_all_valences =
     142              :     ::Tensor<typename TheTensor::type, typename TheTensor::symmetry,
     143              :              tmpl::transform<typename TheTensor::index_list,
     144              :                              tmpl::bind<change_index_up_lo, tmpl::_1>>>;
     145              : 
     146              : /// \ingroup TensorGroup
     147              : /// \brief Swap the data type of a tensor for a new type
     148              : /// \tparam NewType the new data type
     149              : /// \tparam TheTensor the tensor from which to keep symmetry and index
     150              : /// information
     151              : template <typename NewType, typename TheTensor>
     152            1 : using swap_type = ::Tensor<NewType, typename TheTensor::symmetry,
     153              :                            typename TheTensor::index_list>;
     154              : 
     155              : namespace detail {
     156              : template <typename T, typename Frame>
     157              : using frame_is_the_same = std::is_same<typename T::Frame, Frame>;
     158              : }  // namespace detail
     159              : 
     160              : /// \ingroup TensorGroup
     161              : /// \brief Return tmpl::true_type if any indices of the Tensor are in the
     162              : /// frame Frame.
     163              : template <typename TheTensor, typename Frame>
     164            1 : using any_index_in_frame =
     165              :     tmpl::any<typename TheTensor::index_list,
     166              :               tmpl::bind<detail::frame_is_the_same, tmpl::_1, Frame>>;
     167              : 
     168              : /// \ingroup TensorGroup
     169              : /// \brief Return true if any indices of the Tensor are in the
     170              : /// frame Frame.
     171              : template <typename TheTensor, typename Frame>
     172            1 : constexpr bool any_index_in_frame_v =
     173              :     any_index_in_frame<TheTensor, Frame>::value;
     174              : 
     175              : }  // namespace TensorMetafunctions
        

Generated by: LCOV version 2.0-1