SpECTRE Documentation Coverage Report
Current view: top level - DataStructures/Tensor - Metafunctions.hpp Hit Total Coverage
Commit: 9b01d30df5d2e946e7e38cc43c008be18ae9b1d2 Lines: 10 11 90.9 %
Date: 2024-04-23 04:54:49
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             : }  // namespace detail
      57             : 
      58             : /*!
      59             :  * \ingroup TensorGroup
      60             :  * \brief Check that each of symmetric indices is in the same frame and have the
      61             :  * same dimensionality.
      62             :  */
      63             : template <typename Symm, typename... IndexPack>
      64           1 : using check_index_symmetry = typename detail::check_index_symmetry_impl<
      65             :     tmpl::size<Symm>::value == 0 or tmpl::size<Symm>::value == 1 ? 0 : 2>::
      66             :     template f<Symm, tmpl::map<>, IndexPack...>;
      67             : template <typename Symm, typename... IndexPack>
      68           0 : constexpr bool check_index_symmetry_v =
      69             :     check_index_symmetry<Symm, IndexPack...>::value;
      70             : 
      71             : /*!
      72             :  * \ingroup TensorGroup
      73             :  * \brief Add a spatial index to the front of a Tensor
      74             :  *
      75             :  * \tparam Tensor the tensor type to which the new index is prepended
      76             :  * \tparam VolumeDim the volume dimension of the tensor index to prepend
      77             :  * \tparam Fr the ::Frame of the tensor index to prepend
      78             :  */
      79             : template <typename Tensor, std::size_t VolumeDim, UpLo Ul,
      80             :           typename Fr = Frame::Grid>
      81           1 : using prepend_spatial_index = ::Tensor<
      82             :     typename Tensor::type,
      83             :     tmpl::push_front<
      84             :         typename Tensor::symmetry,
      85             :         tmpl::int32_t<
      86             :             1 + tmpl::fold<typename Tensor::symmetry, tmpl::int32_t<0>,
      87             :                            tmpl::max<tmpl::_state, tmpl::_element>>::value>>,
      88             :     tmpl::push_front<typename Tensor::index_list,
      89             :                      SpatialIndex<VolumeDim, Ul, Fr>>>;
      90             : 
      91             : /*!
      92             :  * \ingroup TensorGroup
      93             :  * \brief Add a spacetime index to the front of a Tensor
      94             :  *
      95             :  * \tparam Tensor the tensor type to which the new index is prepended
      96             :  * \tparam VolumeDim the volume dimension of the tensor index to prepend
      97             :  * \tparam Fr the ::Frame of the tensor index to prepend
      98             :  */
      99             : template <typename Tensor, std::size_t VolumeDim, UpLo Ul,
     100             :           typename Fr = Frame::Grid>
     101           1 : using prepend_spacetime_index = ::Tensor<
     102             :     typename Tensor::type,
     103             :     tmpl::push_front<
     104             :         typename Tensor::symmetry,
     105             :         tmpl::int32_t<
     106             :             1 + tmpl::fold<typename Tensor::symmetry, tmpl::int32_t<0>,
     107             :                            tmpl::max<tmpl::_state, tmpl::_element>>::value>>,
     108             :     tmpl::push_front<typename Tensor::index_list,
     109             :                      SpacetimeIndex<VolumeDim, Ul, Fr>>>;
     110             : 
     111             : /// \ingroup TensorGroup
     112             : /// \brief remove the first index of a tensor
     113             : /// \tparam Tensor the tensor type whose first index is removed
     114             : template <typename Tensor>
     115           1 : using remove_first_index =
     116             :     ::Tensor<typename Tensor::type, tmpl::pop_front<typename Tensor::symmetry>,
     117             :              tmpl::pop_front<typename Tensor::index_list>>;
     118             : 
     119             : /// \ingroup TensorGroup
     120             : /// \brief Swap the valences of all indices on a Tensor
     121             : template <typename Tensor>
     122           1 : using change_all_valences =
     123             :     ::Tensor<typename Tensor::type, typename Tensor::symmetry,
     124             :              tmpl::transform<typename Tensor::index_list,
     125             :                              tmpl::bind<change_index_up_lo, tmpl::_1>>>;
     126             : 
     127             : /// \ingroup TensorGroup
     128             : /// \brief Swap the data type of a tensor for a new type
     129             : /// \tparam NewType the new data type
     130             : /// \tparam Tensor the tensor from which to keep symmetry and index information
     131             : template <typename NewType, typename Tensor>
     132           1 : using swap_type =
     133             :     ::Tensor<NewType, typename Tensor::symmetry, typename Tensor::index_list>;
     134             : 
     135             : namespace detail {
     136             : template <typename T, typename Frame>
     137             : using frame_is_the_same = std::is_same<typename T::Frame, Frame>;
     138             : }  // namespace detail
     139             : 
     140             : /// \ingroup TensorGroup
     141             : /// \brief Return tmpl::true_type if any indices of the Tensor are in the
     142             : /// frame Frame.
     143             : template <typename Tensor, typename Frame>
     144           1 : using any_index_in_frame =
     145             :     tmpl::any<typename Tensor::index_list,
     146             :               tmpl::bind<detail::frame_is_the_same, tmpl::_1, Frame>>;
     147             : 
     148             : /// \ingroup TensorGroup
     149             : /// \brief Return true if any indices of the Tensor are in the
     150             : /// frame Frame.
     151             : template <typename Tensor, typename Frame>
     152           1 : constexpr bool any_index_in_frame_v = any_index_in_frame<Tensor, Frame>::value;
     153             : 
     154             : }  // namespace TensorMetafunctions

Generated by: LCOV version 1.14