TensorAsExpression.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 expressions that represent tensors
6 
7 #pragma once
8 
9 #include <array>
10 #include <cstddef>
11 #include <type_traits>
12 
17 #include "Utilities/TMPL.hpp"
18 
19 namespace TensorExpressions {
20 /// \ingroup TensorExpressionsGroup
21 /// \brief Defines an expression representing a Tensor
22 ///
23 /// \details
24 /// In order to represent a tensor as an expression, instead of having Tensor
25 /// derive off of TensorExpression, a TensorAsExpression derives off of
26 /// TensorExpression and contains a pointer to a Tensor. The reason having
27 /// Tensor derive off of TensorExpression is problematic is that the index
28 /// structure is part of the type of the TensorExpression, so every possible
29 /// permutation and combination of indices must be derived from. For a rank 3
30 /// tensor, this is already over 500 base classes, which the Intel compiler
31 /// takes too long to compile.
32 ///
33 /// \tparam T the type of Tensor being represented as an expression
34 /// \tparam ArgsList the tensor indices, e.g. `_a` and `_b` in `F(_a, _b)`
35 template <typename T, typename ArgsList>
37 
38 template <typename X, typename Symm, template <typename...> class IndexList,
39  typename... Indices, template <typename...> class ArgsList,
40  typename... Args>
41 struct TensorAsExpression<Tensor<X, Symm, IndexList<Indices...>>,
42  ArgsList<Args...>>
43  : public TensorExpression<
44  TensorAsExpression<Tensor<X, Symm, IndexList<Indices...>>,
45  ArgsList<Args...>>,
46  X, Symm, IndexList<Indices...>, ArgsList<Args...>> {
47  using type = X;
48  using symmetry = Symm;
49  using index_list = IndexList<Indices...>;
50  static constexpr auto num_tensor_indices = tmpl::size<index_list>::value;
51  using args_list = ArgsList<Args...>;
52 
53  /// Construct an expression from a Tensor
54  explicit TensorAsExpression(const Tensor<X, Symm, IndexList<Indices...>>& t)
55  : t_(&t) {}
56  ~TensorAsExpression() override = default;
57 
58  /// \brief Returns the value of a left hand side tensor's multi-index
59  ///
60  /// \details
61  /// One big challenge with TensorExpression implementation is the reordering
62  /// of the indices on the left hand side (LHS) and right hand side (RHS) of
63  /// the expression. The algorithms implemented in
64  /// `compute_index_transformation` and `compute_rhs_multi_index` handle the
65  /// index sorting by mapping between the generic index orders of the LHS and
66  /// RHS tensors.
67  ///
68  /// \tparam LhsIndices the TensorIndexs of the Tensor on the LHS of the tensor
69  /// expression
70  /// \param lhs_multi_index the multi-index of the LHS tensor component to
71  /// retrieve
72  /// \return the value of the DataType of the component at `lhs_multi_index` in
73  /// the LHS tensor
74  template <typename... LhsIndices>
75  SPECTRE_ALWAYS_INLINE decltype(auto) get(
76  const std::array<size_t, num_tensor_indices>& lhs_multi_index)
77  const noexcept {
78  if constexpr (std::is_same_v<tmpl::list<LhsIndices...>,
79  tmpl::list<Args...>>) {
80  return t_->get(lhs_multi_index);
81  } else {
82  constexpr std::array<size_t, num_tensor_indices> index_transformation =
83  compute_tensorindex_transformation<num_tensor_indices>(
84  {{LhsIndices::value...}}, {{Args::value...}});
85  return t_->get(
86  transform_multi_index(lhs_multi_index, index_transformation));
87  }
88  }
89 
90  /// Retrieve the i'th entry of the Tensor being held
91  SPECTRE_ALWAYS_INLINE type operator[](const size_t i) const {
92  return t_->operator[](i);
93  }
94 
95  private:
96  const Tensor<X, Symm, IndexList<Indices...>>* t_ = nullptr;
97 };
98 } // namespace TensorExpressions
TensorExpressions::TensorAsExpression< Tensor< X, Symm, IndexList< Indices... > >, ArgsList< Args... > >::operator[]
type operator[](const size_t i) const
Retrieve the i'th entry of the Tensor being held.
Definition: TensorAsExpression.hpp:91
TensorExpression.hpp
db::get
const auto & get(const DataBox< TagList > &box) noexcept
Retrieve the item with tag Tag from the DataBox.
Definition: DataBox.hpp:791
TensorExpressions::transform_multi_index
constexpr std::array< size_t, NumIndices > transform_multi_index(const std::array< size_t, NumIndices > &input_multi_index, const std::array< size_t, NumIndices > &tensorindex_transformation) noexcept
Computes the tensor multi-index that is equivalent to a given tensor multi-index, according to the di...
Definition: TensorIndexTransformation.hpp:93
TensorExpressions::TensorAsExpression< Tensor< X, Symm, IndexList< Indices... > >, ArgsList< Args... > >::TensorAsExpression
TensorAsExpression(const Tensor< X, Symm, IndexList< Indices... >> &t)
Construct an expression from a Tensor.
Definition: TensorAsExpression.hpp:54
TensorExpressions::TensorAsExpression
Defines an expression representing a Tensor.
Definition: TensorAsExpression.hpp:36
TensorExpressions
Definition: AddSubtract.hpp:36
SPECTRE_ALWAYS_INLINE
#define SPECTRE_ALWAYS_INLINE
Definition: ForceInline.hpp:16
cstddef
array
ForceInline.hpp
Tensor.hpp
type_traits
TMPL.hpp
TensorIndexTransformation.hpp