SpECTRE Documentation Coverage Report
Current view: top level - DataStructures/Tensor - Metafunctions.hpp Hit Total Coverage
Commit: 1f2210958b4f38fdc0400907ee7c6d5af5111418 Lines: 11 12 91.7 %
Date: 2025-12-05 05:03:31
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 1.14