SpatialSpacetimeIndex.hpp
Go to the documentation of this file.
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
9 #include "Utilities/Algorithm.hpp"
11 #include "Utilities/Gsl.hpp"
12 #include "Utilities/TMPL.hpp"
13 
14 /// \file
15 /// Defines functions and metafunctions used for helping evaluate
16 /// TensorExpression equations where generic spatial indices are used for
17 /// spacetime indices
18 
19 namespace TensorExpressions {
20 namespace detail {
21 template <typename State, typename Element, typename Iteration,
22  typename TensorIndexList>
23 struct spatial_spacetime_index_positions_impl {
24  using type = typename std::conditional_t<
25  Element::index_type == IndexType::Spacetime and
26  not tmpl::at<TensorIndexList, Iteration>::is_spacetime,
27  tmpl::push_back<State, Iteration>, State>;
28 };
29 
30 /// \brief Given a generic index list and tensor index list, returns the list of
31 /// positions where the generic index is spatial and the tensor index is
32 /// spacetime
33 ///
34 /// \tparam TensorIndexList the generic index list
35 /// \tparam TensorIndexTypeList the list of
36 /// \ref SpacetimeIndex "TensorIndexType"s
37 template <typename TensorIndexTypeList, typename TensorIndexList>
38 using spatial_spacetime_index_positions = tmpl::enumerated_fold<
39  TensorIndexTypeList, tmpl::list<>,
40  spatial_spacetime_index_positions_impl<
41  tmpl::_state, tmpl::_element, tmpl::_3, tmpl::pin<TensorIndexList>>,
42  tmpl::size_t<0>>;
43 
44 /// \brief Given a generic index list and tensor index list, returns the list of
45 /// positions where the generic index is spatial and the tensor index is
46 /// spacetime
47 ///
48 /// \tparam TensorIndexList the generic index list
49 /// \tparam TensorIndexTypeList the list of
50 /// \ref SpacetimeIndex "TensorIndexType"s
51 /// \return the list of positions where the generic index is spatial and the
52 /// tensor index is spacetime
53 template <typename TensorIndexTypeList, typename TensorIndexList>
54 constexpr auto get_spatial_spacetime_index_positions() noexcept {
55  using spatial_spacetime_index_positions_ =
56  spatial_spacetime_index_positions<TensorIndexTypeList, TensorIndexList>;
57  using make_list_type = std::conditional_t<
58  tmpl::size<spatial_spacetime_index_positions_>::value == 0, size_t,
59  spatial_spacetime_index_positions_>;
60  return make_array_from_list<make_list_type>();
61 }
62 
63 /// \brief Given a tensor symmetry and the positions of indices where a generic
64 /// spatial index is used for a spacetime index, this returns the symmetry
65 /// after making those indices nonsymmetric with others
66 ///
67 /// \details
68 /// Example: If `symmetry` is `[2, 1, 1, 1]` and
69 /// `spatial_spacetime_index_positions` is `[1]`, then position 1 is the only
70 /// position where a generic spatial index is used for a spacetime index. The
71 /// resulting symmetry will make the index at position 1 no longer be symmetric
72 /// with the indices at positions 2 and 3. Therefore, the resulting symmetry
73 /// will be equivalent to the form of `[3, 2, 1, 1]`.
74 ///
75 /// Note: the symmetry returned by this function is not in the canonical form
76 /// specified by ::Symmetry. In reality, for the example above, this function
77 /// would return `[2, 3, 1, 1]`.
78 ///
79 /// \param symmetry the input tensor symmetry to transform
80 /// \param spatial_spacetime_index_positions the positions of the indices of the
81 /// tensor where a generic spatial index is used for a spacetime index
82 /// \return the symmetry after making the `spatial_spacetime_index_positions` of
83 /// `symmetry` nonsymmetric with other indices
84 template <size_t NumIndices, size_t NumSpatialSpacetimeIndices>
86 get_spatial_spacetime_index_symmetry(
89  spatial_spacetime_index_positions) noexcept {
90  std::array<std::int32_t, NumIndices> spatial_spacetime_index_symmetry{};
91  const std::int32_t max_symm_value =
92  static_cast<std::int32_t>(*alg::max_element(symmetry));
93  for (size_t i = 0; i < NumIndices; i++) {
94  gsl::at(spatial_spacetime_index_symmetry, i) = gsl::at(symmetry, i);
95  }
96  for (size_t i = 0; i < NumSpatialSpacetimeIndices; i++) {
97  spatial_spacetime_index_symmetry[spatial_spacetime_index_positions[i]] +=
98  max_symm_value;
99  gsl::at(spatial_spacetime_index_symmetry,
100  gsl::at(spatial_spacetime_index_positions, i)) += max_symm_value;
101  }
102 
103  return spatial_spacetime_index_symmetry;
104 }
105 
106 template <typename S, typename E>
107 struct replace_spatial_spacetime_indices_helper {
108  using type = tmpl::replace_at<S, E, change_index_type<tmpl::at<S, E>>>;
109 };
110 
111 // The list of indices resulting from taking `TensorIndexTypeList` and
112 // replacing the spacetime indices at positions `SpatialSpacetimeIndexPositions`
113 // with spatial indices
114 template <typename TensorIndexTypeList, typename SpatialSpacetimeIndexPositions>
115 using replace_spatial_spacetime_indices = tmpl::fold<
116  SpatialSpacetimeIndexPositions, TensorIndexTypeList,
117  replace_spatial_spacetime_indices_helper<tmpl::_state, tmpl::_element>>;
118 } // namespace detail
119 } // namespace TensorExpressions
gsl::at
constexpr T & at(std::array< T, N > &arr, Size index)
Retrieve a entry from a container, with checks in Debug mode that the index being retrieved is valid.
Definition: Gsl.hpp:125
IndexType.hpp
Symmetry.hpp
Element
Definition: Element.hpp:29
IndexType::Spacetime
@ Spacetime
The TensorIndexType is a spacetime index.
TensorExpressions
Definition: AddSubtract.hpp:36
std::array
ConstantExpressions.hpp
std::int32_t
Gsl.hpp
alg::max_element
constexpr decltype(auto) max_element(const Container &c)
Convenience wrapper around std::max_element.
Definition: Algorithm.hpp:327
std::conditional_t
TMPL.hpp
TensorIndex.hpp