Metafunctions.hpp
Go to the documentation of this file.
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 
10 #include "Utilities/TMPL.hpp"
11 
12 /// \cond
13 template <typename X, typename Symm, typename IndexList>
14 class Tensor;
15 /// \endcond
16 
17 /// \ingroup TensorGroup
18 /// Contains all metafunctions related to Tensor manipulations
20 namespace detail {
21 template <unsigned>
22 struct check_index_symmetry_impl;
23 // empty typelist or only had a vector to start with
24 template <>
25 struct check_index_symmetry_impl<0> {
26  template <typename...>
27  using f = std::true_type;
28 };
29 
30 // found incorrect symmetric index
31 template <>
32 struct check_index_symmetry_impl<1> {
33  template <typename...>
34  using f = std::false_type;
35 };
36 
37 // recurse the list
38 template <>
39 struct check_index_symmetry_impl<2> {
40  template <typename Symm, typename IndexSymm, typename Index0,
41  typename... IndexPack>
42  using f = typename check_index_symmetry_impl<
43  tmpl::has_key<IndexSymm, tmpl::front<Symm>>::value and
44  not std::is_same<Index0,
45  tmpl::at<IndexSymm, tmpl::front<Symm>>>::value
46  ? 1
47  : tmpl::size<Symm>::value == 1 ? 0 : 2>::
48  template f<tmpl::pop_front<Symm>,
49  tmpl::insert<IndexSymm, tmpl::pair<tmpl::front<Symm>, Index0>>,
50  IndexPack...>;
51 };
52 } // namespace detail
53 
54 /*!
55  * \ingroup TensorGroup
56  * \brief Check that each of symmetric indices is in the same frame and have the
57  * same dimensionality.
58  */
59 template <typename Symm, typename... IndexPack>
60 using check_index_symmetry = typename detail::check_index_symmetry_impl<
61  tmpl::size<Symm>::value == 0 or tmpl::size<Symm>::value == 1 ? 0 : 2>::
62  template f<Symm, tmpl::map<>, IndexPack...>;
63 template <typename Symm, typename... IndexPack>
64 constexpr bool check_index_symmetry_v =
65  check_index_symmetry<Symm, IndexPack...>::value;
66 
67 /*!
68  * \ingroup TensorGroup
69  * \brief Add a spatial index to the front of a Tensor
70  *
71  * \tparam Tensor the tensor type to which the new index is prepended
72  * \tparam VolumeDim the volume dimension of the tensor index to prepend
73  * \tparam Fr the ::Frame of the tensor index to prepend
74  */
75 template <typename Tensor, std::size_t VolumeDim, UpLo Ul,
76  typename Fr = Frame::Grid>
77 using prepend_spatial_index = ::Tensor<
78  typename Tensor::type,
79  tmpl::push_front<
80  typename Tensor::symmetry,
81  tmpl::int32_t<
82  1 + tmpl::fold<typename Tensor::symmetry, tmpl::int32_t<0>,
83  tmpl::max<tmpl::_state, tmpl::_element>>::value>>,
84  tmpl::push_front<typename Tensor::index_list,
86 
87 /*!
88  * \ingroup TensorGroup
89  * \brief Add a spacetime index to the front of a Tensor
90  *
91  * \tparam Tensor the tensor type to which the new index is prepended
92  * \tparam VolumeDim the volume dimension of the tensor index to prepend
93  * \tparam Fr the ::Frame of the tensor index to prepend
94  */
95 template <typename Tensor, std::size_t VolumeDim, UpLo Ul,
96  typename Fr = Frame::Grid>
97 using prepend_spacetime_index = ::Tensor<
98  typename Tensor::type,
99  tmpl::push_front<
100  typename Tensor::symmetry,
101  tmpl::int32_t<
102  1 + tmpl::fold<typename Tensor::symmetry, tmpl::int32_t<0>,
103  tmpl::max<tmpl::_state, tmpl::_element>>::value>>,
104  tmpl::push_front<typename Tensor::index_list,
106 
107 /// \ingroup TensorGroup
108 /// \brief remove the first index of a tensor
109 /// \tparam Tensor the tensor type whose first index is removed
110 template <typename Tensor>
111 using remove_first_index =
112  ::Tensor<typename Tensor::type, tmpl::pop_front<typename Tensor::symmetry>,
113  tmpl::pop_front<typename Tensor::index_list>>;
114 
115 /// \ingroup TensorGroup
116 /// \brief Swap the data type of a tensor for a new type
117 /// \tparam NewType the new data type
118 /// \tparam Tensor the tensor from which to keep symmetry and index information
119 template <typename NewType, typename Tensor>
120 using swap_type =
121  ::Tensor<NewType, typename Tensor::symmetry, typename Tensor::index_list>;
122 } // namespace TensorMetafunctions
Definition: IndexType.hpp:43
Contains all metafunctions related to Tensor manipulations.
Definition: Metafunctions.hpp:19
::Tensor< typename Tensor::type, tmpl::push_front< typename Tensor::symmetry, tmpl::int32_t< 1+tmpl::fold< typename Tensor::symmetry, tmpl::int32_t< 0 >, tmpl::max< tmpl::_state, tmpl::_element > >::value > >, tmpl::push_front< typename Tensor::index_list, SpacetimeIndex< VolumeDim, Ul, Fr > >> prepend_spacetime_index
Add a spacetime index to the front of a Tensor.
Definition: Metafunctions.hpp:105
Definition: Determinant.hpp:11
Tensor_detail::TensorIndexType< SpatialDim, Ul, Fr, IndexType::Spacetime > SpacetimeIndex
A SpacetimeIndex holds information about the number of spatial dimensions, whether the index is covar...
Definition: IndexType.hpp:199
Tensor_detail::TensorIndexType< SpatialDim, Ul, Fr, IndexType::Spatial > SpatialIndex
A SpatialIndex holds information about the number of spatial dimensions, whether the index is covaria...
Definition: IndexType.hpp:185
::Tensor< typename Tensor::type, tmpl::pop_front< typename Tensor::symmetry >, tmpl::pop_front< typename Tensor::index_list > > remove_first_index
remove the first index of a tensor
Definition: Metafunctions.hpp:113
::Tensor< NewType, typename Tensor::symmetry, typename Tensor::index_list > swap_type
Swap the data type of a tensor for a new type.
Definition: Metafunctions.hpp:121
Wraps the template metaprogramming library used (brigand)
typename detail::check_index_symmetry_impl< tmpl::size< Symm >::value==0 or tmpl::size< Symm >::value==1 ? 0 :2 >::template f< Symm, tmpl::map<>, IndexPack... > check_index_symmetry
Check that each of symmetric indices is in the same frame and have the same dimensionality.
Definition: Metafunctions.hpp:62
::Tensor< typename Tensor::type, tmpl::push_front< typename Tensor::symmetry, tmpl::int32_t< 1+tmpl::fold< typename Tensor::symmetry, tmpl::int32_t< 0 >, tmpl::max< tmpl::_state, tmpl::_element > >::value > >, tmpl::push_front< typename Tensor::index_list, SpatialIndex< VolumeDim, Ul, Fr > >> prepend_spatial_index
Add a spatial index to the front of a Tensor.
Definition: Metafunctions.hpp:85
UpLo
Whether a TensorIndexType is covariant or contravariant.
Definition: IndexType.hpp:20
Defines classes representing tensor indices.