DUNE-ACFEM (unstable)

constant.hh
1#ifndef __DUNE_ACFEM_TENSORS_MODULES_CONSTANT_HH__
2#define __DUNE_ACFEM_TENSORS_MODULES_CONSTANT_HH__
3
4#include "../../common/fractionconstant.hh"
5#include "../../expressions/terminal.hh"
6#include "../tensorbase.hh"
7#include "../bindings.hh"
8
9namespace Dune {
10
11 namespace ACFem {
12
13 namespace Tensor {
14
23 template<class Field, class Signature>
24 class ConstantTensor;
25
26 template<class T, class Field>
27 constexpr inline bool IsConstantTensorV = false;
28
29 template<class T, class Field>
30 constexpr inline bool IsConstantTensorV<T&, Field> = IsConstantTensorV<std::decay_t<T>, Field>;
31
32 template<class Signature, class Field>
33 constexpr inline bool IsConstantTensorV<ConstantTensor<Field, Signature>, Field> = true;
34
35 template<class T, class SFINAE = void>
36 struct IsConstantTensor
37 : FalseType
38 {};
39
40 template<class T>
41 struct IsConstantTensor<T, std::enable_if_t<!IsDecay<T>::value> >
42 : IsConstantTensor<std::decay_t<T> >
43 {};
44
45 template<class Field, class Dims>
46 struct IsConstantTensor<ConstantTensor<Field, Dims> >
47 : TrueType
48 {};
49
50 template<class T>
51 struct IsNamedConstantTensor
52 : FalseType
53 {};
54
55 template<class T>
56 struct IsNamedConstantTensor<T&>
57 : IsNamedConstantTensor<std::decay_t<T> >
58 {};
59
60 template<class T>
61 struct IsNamedConstantTensor<T&&>
62 : IsNamedConstantTensor<std::decay_t<T> >
63 {};
64
65 template<class Dims, class T, char... Name>
66 struct IsNamedConstantTensor<ConstantTensor<TypedValue::NamedConstant<T, Name...>, Dims> >
67 : TrueType
68 {};
69
70 template<class T>
71 struct IsFractionConstantTensor
72 : FalseType
73 {};
74
75 template<class T>
76 struct IsFractionConstantTensor<T&>
77 : IsFractionConstantTensor<std::decay_t<T> >
78 {};
79
80 template<class T>
81 struct IsFractionConstantTensor<T&&>
82 : IsFractionConstantTensor<std::decay_t<T> >
83 {};
84
85 template<class Dims, class Int, Int Numerator, Int Denominator>
86 struct IsFractionConstantTensor<ConstantTensor<FractionConstant<Int, Numerator, Denominator>, Dims> >
87 : TrueType
88 {};
89
90 template<class T>
91 struct IsOnes
92 : FalseType
93 {};
94
95 template<class T>
96 struct IsOnes<T&>
97 : IsOnes<std::decay_t<T> >
98 {};
99
100 template<class T>
101 struct IsOnes<T&&>
102 : IsOnes<std::decay_t<T> >
103 {};
104
105 template<class Dims, class Int>
106 struct IsOnes<ConstantTensor<FractionConstant<Int, 1, 1>, Dims> >
107 : TrueType
108 {};
109
110 template<class T, class SFINAE = void>
111 struct ConstantDataWrapper;
112
113 template<class T>
114 struct ConstantDataWrapper<T, std::enable_if_t<IsTypedValue<T>::value> >
115 {
116 using DataType = T;
117
118 ConstantDataWrapper()
119 {};
120
121 template<class DataArg, std::enable_if_t<std::is_constructible<DataType, DataArg>::value, int> = 0>
122 ConstantDataWrapper(DataArg&& = DataArg{})
123 {};
124
125 static_assert(!IsTypedValue<DataType>::value || IsDecay<DataType>::value,
126 "Typed values should not be stored as references.");
127
128 static constexpr T data() { return T{}; }
129 protected:
130 DataType data_;
131 };
132
133 template<class T>
134 struct ConstantDataWrapper<T, std::enable_if_t<!IsTypedValue<T>::value> >
135 {
136 using DataType = T;
137
138 template<class DataArg, std::enable_if_t<std::is_constructible<DataType, DataArg>::value, int> = 0>
139 ConstantDataWrapper(DataArg&& data = DataArg{})
140 : data_(std::forward<DataArg>(data))
141 {
142 //std::clog << "wrapper: " << data_ << std::endl;
143 //std::clog << typeString(MPL::TypeTuple<T>{}) << std::endl;
144 }
145
146 decltype(auto) data() const&
147 {
148 return data_;
149 }
150
151 decltype(auto) data() &
152 {
153 return data_;
154 }
155
156 DataType data() &&
157 {
158 return data_;
159 }
160 protected:
161 DataType data_;
162 };
163
167 template<class Field, std::size_t... Dimensions>
168 class ConstantTensor<Field, Seq<Dimensions...> >
169 : public TensorBase<std::decay_t<Field>, Seq<Dimensions...>, ConstantTensor<Field, Seq<Dimensions...> > >
170 , public ConstantDataWrapper<Field>
171 , public Expressions::SelfExpression<ConstantTensor<Field, Seq<Dimensions...> > >
172 , public MPL::UniqueTags<ConditionalType<IsConstantExprArg<Field>::value, ConstantExpression, void>,
173 ConditionalType<IsTypedValue<Field>::value, TypedValueExpression, void> >
174 {
175 using ThisType = ConstantTensor;
176 using BaseType = TensorBase<std::decay_t<Field>, Seq<Dimensions...>, ConstantTensor<Field, Seq<Dimensions...> > >;
177 using DataWrapperType = ConstantDataWrapper<Field>;
178 public:
179 using BaseType::rank;
180 using typename BaseType::FieldType;
181 using typename BaseType::Signature;
182 using typename DataWrapperType::DataType;
183 using DataWrapperType::data;
184
185 // This really should not take part in implicit type conversions.
186 template<class DataArg, std::enable_if_t<std::is_constructible<DataType, DataArg>::value, int> = 0>
187 explicit ConstantTensor(DataArg&& data)
188 : DataWrapperType(std::forward<DataArg>(data))
189 {}
190
192 template<
193 class... Dummy,
194 std::enable_if_t<(sizeof...(Dummy) == 0
195 && IsTypedValue<DataType>::value), int> = 0>
196 ConstantTensor(Dummy&&...)
197 : DataWrapperType()
198 {
199 //std::clog << "ConstantTensor: " << DataWrapperType::data_ << std::endl;
200 //std::clog << typeString(MPL::TypeTuple<Field>{}) << std::endl;
201 }
202
206 template<class... Dims,
207 std::enable_if_t<(sizeof...(Dims) == rank
208 &&
210 , int> = 0>
211 decltype(auto) operator()(Dims... indices) const
212 {
213 //std::clog << "returning const: " << data() << std::endl;
214 return data();
215 }
216
218 template<std::size_t... Indices,
219 std::enable_if_t<(sizeof...(Indices) == rank
220 && ThisType::template isZero<Indices...>()
221 ), int> = 0>
222 decltype(auto) constexpr operator()(Seq<Indices...>) const
223 {
224 //std::clog << "returning const: 0_c " << std::endl;
225 return IntFraction<0>{};
226 }
227
229 template<std::size_t... Indices,
230 std::enable_if_t<(sizeof...(Indices) == rank
231 && !ThisType::template isZero<Indices...>()
232 ), int> = 0>
233 decltype(auto) constexpr operator()(Seq<Indices...>) const
234 {
235 //std::clog << "returning const: " << data() << std::endl;
236 return data();
237 }
238
239 template<std::size_t... Indices, class Pos = MakeIndexSequence<sizeof...(Indices)> >
240 static bool constexpr isZero(Seq<Indices...> = Seq<Indices...>{}, Pos = Pos{})
241 {
242 return ExpressionTraits<FieldType>::isZero;
243 }
244
245 // in order to support projection optimizations we fake a non-const lookAt()
246 template<class... Whatever>
247 void lookAt(Whatever&&...)
248 {}
249
250 std::string name() const
251 {
252 std::string prefix;
253 if (std::is_same<DataType, IntFraction<0> >{}) {
254 prefix = "zeros<";
255 } else if(std::is_same<DataType, IntFraction<1> >{}) {
256 prefix = "ones<";
257 } else {
258 prefix = "tensor<"+toString(data());
259 if (std::is_reference<DataType>::value) {
260 prefix += std::is_const<DataType>::value ? "cref" : "ref";
261 }
262 prefix += rank > 0 ? "@" : "";
263 }
264
265 return prefix+toString(Signature{})+">";
266 }
267 };
268
269 template<std::size_t... Dimensions, class T, class F = Closure>
270 constexpr auto constantTensor(T&& t, Seq<Dimensions...> = Seq<Dimensions...>{}, F closure = F{})
271 {
272 using ValueType = ConditionalType<IsTypedValue<T>::value, std::decay_t<T>, T>;
273 return closure(ConstantTensor<ValueType, Seq<Dimensions...> >(std::forward<T>(t)));
274 }
275
276 template<class T, class Tensor, class F = Closure,
277 std::enable_if_t<IsTensorOperand<Tensor>::value, int> = 0>
278 constexpr auto constantTensor(T&& t, Tensor&&, F = F{})
279 {
280 using Signature = typename TensorTraits<Tensor>::Signature;
281 return constantTensor(std::forward<T>(t), Signature{}, F{});
282 }
283
284 template<std::size_t... Dimensions, class F = Closure>
285 auto zeros(Seq<Dimensions...> = Seq<Dimensions...>{}, F = F{})
286 {
287 return constantTensor(IntFraction<0>{}, Seq<Dimensions...>{}, F{});
288 }
289
290 template<class T, class F = Closure,
291 std::enable_if_t<IsTensor<T>::value, int> = 0>
292 constexpr auto zeros(F = F{})
293 {
294 using Signature = typename TensorTraits<T>::Signature;
295 return zeros(Signature{}, F{});
296 }
297
298 template<class T, class F = Closure,
299 std::enable_if_t<IsTensorOperand<T>::value, int> = 0>
300 constexpr auto zeros(T&&, F = F{})
301 {
302 return zeros<T>(F{});
303 }
304
305 template<std::size_t... Dimensions, class F = Closure>
306 constexpr auto ones(Seq<Dimensions...> = Seq<Dimensions...>{}, F = F{})
307 {
308 return constantTensor(IntFraction<1>{}, Seq<Dimensions...>{}, F{});
309 }
310
311 template<class T, class F = Closure,
312 std::enable_if_t<IsTensor<T>::value, int> = 0>
313 constexpr auto ones(F = F{})
314 {
315 using Signature = typename TensorTraits<T>::Signature;
316 return ones(Signature{}, F{});
317 }
318
319 template<class T, class F = Closure,
320 std::enable_if_t<IsTensor<T>::value, int> = 0>
321 constexpr auto ones(T&&, F = F{})
322 {
323 return ones<T>(F{});
324 }
325
326 template<class T>
327 using Zeros = ConditionalType<IsSequence<T>::value,
328 ConstantTensor<IntFraction<0>, T>,
329 ConstantTensor<IntFraction<0>, typename TensorTraits<T>::Signature> >;
330
331 template<class T>
332 using Ones = ConditionalType<IsSequence<T>::value,
333 ConstantTensor<IntFraction<1>, T>,
334 ConstantTensor<IntFraction<1>, typename TensorTraits<T>::Signature> >;
335
337
339
340 } // NS Tensor
341
342 namespace Expressions {
343
344 template<class T, class Seq>
345 constexpr inline std::size_t WeightV<Tensor::ConstantTensor<T, Seq> > = WeightV<std::decay_t<T> >;
346
347 }
348
349 } // NS ACFem
350
351 template<class Field, class Signature>
352 struct FieldTraits<ACFem::Tensor::ConstantTensor<Field, Signature> >
353 : FieldTraits<std::decay_t<Field> >
354 {};
355
356} // NS Dune
357
358#endif // __DUNE_ACFEM_TENSORS_MODULES_CONSTANT_HH__
decltype(auto) constexpr operator()(Seq< Indices... >) const
Constant access from index-sequence, zero optimization.
Definition: constant.hh:222
ConstantTensor(Dummy &&...)
Allow default construction if contained types fulfill IsTypedValue.
Definition: constant.hh:196
BoolConstant< ExpressionTraits< T >::isTypedValue > IsTypedValue
Compile-time true if T is a "typed value", e.g. a std::integral_constant.
Definition: expressiontraits.hh:90
MakeSequence< std::size_t, N, Offset, Stride, Repeat > MakeIndexSequence
Make a sequence of std::size_t elements.
Definition: generators.hh:34
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
STL namespace.
Terminals may derive from this class to express that they are expressions.
Definition: terminal.hh:25
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)