DUNE-ACFEM (unstable)

reshape.hh
1 #ifndef __DUNE_ACFEM_TENSORS_OPERATIONS_RESHAPE_HH__
2 #define __DUNE_ACFEM_TENSORS_OPERATIONS_RESHAPE_HH__
3 
4 #include "../../expressions/storage.hh"
5 #include "../../mpl/multiindex.hh"
6 #include "../tensorbase.hh"
7 #include "../modules.hh"
8 
9 namespace Dune::ACFem {
10 
11  // forward
12  template<class Signature>
13  struct ReshapeOperation;
14 
15 }
16 
17 namespace Dune::ACFem::Tensor {
18 
27  template<class Parent, class Signature>
28  class Reshape;
29 
30  template<class T, class SFINAE = void>
31  struct IsReshape
32  : FalseType
33  {};
34 
35  template<class T>
36  struct IsReshape<T, std::enable_if_t<!IsDecay<T>::value> >
37  : IsReshape<std::decay_t<T> >
38  {};
39 
40  template<class Parent, class Signature>
41  struct IsReshape<Reshape<Parent, Signature> >
42  : TrueType
43  {};
44 
45 
47  template<class Parent, std::size_t... Dimensions>
48  class Reshape<Parent, Seq<Dimensions...> >
49  : public TensorBase<typename std::decay_t<Parent>::FieldType,
50  Seq<Dimensions...>,
51  Reshape<Parent, Seq<Dimensions...> > >
52  , public Expressions::Storage<OperationTraits<ReshapeOperation<Seq<Dimensions...> > >, Parent>
53  {
54  using ThisType = Reshape;
55  using ParentType = std::decay_t<Parent>;
56  using BaseType = TensorBase<typename ParentType::FieldType,
57  Seq<Dimensions...>,
58  Reshape<Parent, Seq<Dimensions...> > >;
59  using StorageType = Expressions::Storage<OperationTraits<ReshapeOperation<Seq<Dimensions...> > >, Parent>;
60  public:
61  using BaseType::rank;
62  using BaseType::dim;
63  using typename BaseType::FieldType;
64  using Signature = TensorSignature<Dimensions...>;
65  using ParentSignature = typename ParentType::Signature;
66  using StorageType::operation;
67  using StorageType::operand;
68 
69  static_assert(dim() == ParentType::dim(), "reshaped tensors total dimension needs to match parents");
70 
71  template<class Arg, std::enable_if_t<std::is_constructible<ParentType, Arg>::value, int> = 0>
72  Reshape(Arg&& parent)
73  : StorageType(std::forward<Arg>(parent))
74  {}
75 
77  template<
78  class... Dummy,
79  std::enable_if_t<(sizeof...(Dummy) == 0
80  && IsTypedValue<ParentType>::value), int> = 0>
81  Reshape(Dummy&&...)
82  : StorageType(ParentType{})
83  {}
84 
88  template<class... Indices,
89  std::enable_if_t<(sizeof...(Indices) == rank
90  &&
92  , int> = 0>
93  constexpr decltype(auto) operator()(Indices... indices) const
94  {
95  const auto index = flattenMultiIndex(Signature{}, indices...);
96  const auto parentIndexArray = multiIndex(index, ParentSignature{});
97 
98  // array -> tuple -> parameter pack function call
99  return tensorValue(operand(0_c), parentIndexArray);
100  }
101 
105  template<class... Indices,
106  std::enable_if_t<(sizeof...(Indices) == rank
107  &&
109  , int> = 0>
110  constexpr decltype(auto) operator()(Indices... indices)
111  {
112  const auto index = flattenMultiIndex(Signature{}, indices...);
113  const auto parentIndexArray = multiIndex(index, ParentSignature{});
114 
115  // array -> tuple -> parameter pack function call
116  return tensorValue(operand(0_c), parentIndexArray);
117  }
118 
120  template<std::size_t... Indices,
121  std::enable_if_t<sizeof...(Indices) == rank, int> = 0>
122  decltype(auto) constexpr operator()(Seq<Indices...>) const
123  {
124  constexpr std::size_t index = flattenMultiIndex<Indices...>(Signature{});
125 
126  return tensorValue(operand(0_c), multiIndex<index>(ParentSignature{}));
127  }
128 
130  template<std::size_t... Indices,
131  std::enable_if_t<sizeof...(Indices) == rank, int> = 0>
132  decltype(auto) constexpr operator()(Seq<Indices...>)
133  {
134  constexpr std::size_t index = flattenMultiIndex<Indices...>(Signature{});
135 
136  return tensorValue(operand(0_c), multiIndex<index>(ParentSignature{}));
137  }
138 
139  std::string name() const
140  {
141  return "reshape<" + toString(Signature{}) + ">(" + refPrefix() + toString(operand(0_c)) + ")";
142  }
143 
144  private:
145  std::string refPrefix() const
146  {
147  constexpr bool isRef = std::is_lvalue_reference<Parent>::value;
148  constexpr bool isConst = std::is_const<std::remove_reference_t<Parent> >::value;
149 
150  return isRef ? (isConst ? "cref" : "ref") : "";
151  }
152  };
153 
154  template<std::size_t... Dimensions, class T, std::enable_if_t<IsProperTensor<T>::value, int> = 0>
155  constexpr decltype(auto) reshape(T&& t, Seq<Dimensions...> = Seq<Dimensions...>{})
156  {
157  using Operation = ReshapeOperation<Seq<Dimensions...> >;
158 
159  return Expressions::finalize<Operation>(std::forward<T>(t));
160  }
161 
162  template<class Sig, class T>
163  constexpr auto operate(Expressions::DontOptimize, OperationTraits<ReshapeOperation<Sig> >, T&& t)
164  {
165  DUNE_ACFEM_RECORD_OPTIMIZATION;
166 
167  return Reshape<T, Sig>(std::forward<T>(t));
168  }
169 
170 } // namespace Dune::ACFem::Tensor
171 
172 namespace Dune {
173 
174  template<class Parent, class Signature>
175  struct FieldTraits<ACFem::Tensor::Reshape<Parent, Signature> >
176  : FieldTraits<typename std::decay_t<Parent>::FieldType>
177  {};
178 
179 }
180 
181 #endif // __DUNE_ACFEM_TENSORS_OPERATIONS_RESHAPE_HH__
OptimizeTag< 0 > DontOptimize
Bottom level is overloaded to do nothing.
Definition: optimizationbase.hh:74
BoolConstant< ExpressionTraits< T >::isTypedValue > IsTypedValue
Compile-time true if T is a "typed value", e.g. a std::integral_constant.
Definition: expressiontraits.hh:90
constexpr decltype(auto) operate(DefaultTag, OperationTraits< ReshapeOperation< ReshapeSignature > >, T &&t)
Definition: reshape.hh:51
decltype(auto) constexpr operator()(Seq< Indices... >) const
Constant access from index-sequence.
Definition: reshape.hh:122
decltype(auto) constexpr operator()(Seq< Indices... >)
Constant access from index-sequence.
Definition: reshape.hh:132
Reshape(Dummy &&...)
Allow default construction if contained types fulfill IsTypedValue.
Definition: reshape.hh:81
decltype(isIntegralPack(std::declval< T >()...)) IsIntegralPack
Decide whether the given parameter pack contains only integral types.
Definition: compare.hh:377
BoolConstant< false > FalseType
Alias for std::false_type.
Definition: types.hh:110
BoolConstant< true > TrueType
Alias for std::true_type.
Definition: types.hh:107
A namespace encapsulating everything defined in our dune-acfem project.
Definition: ellipticfemscheme.hh:56
constexpr auto multiIndex(IndexSequence< Dims... >, IndexConstant< I >=IndexConstant< I >{})
Generate the multi-index corresponding to the flattened index I where the multiindex varies between t...
Definition: multiindex.hh:60
constexpr std::size_t flattenMultiIndex(Dims, const std::array< std::size_t, N > &indices)
Flatten run-time variable std::array.
Definition: multiindex.hh:111
Signature of index positions of tensors.
Definition: expressionoperations.hh:232
Base class for all tensors.
Definition: tensorbase.hh:144
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)