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
9namespace Dune::ACFem {
10
11 // forward
12 template<class Signature>
13 struct ReshapeOperation;
14
15}
16
17namespace 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
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
172namespace 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
STL namespace.
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.111.3 (Jul 15, 22:36, 2024)