1#ifndef __DUNE_ACFEM_TENSORS_TENSORBASE_HH__
2#define __DUNE_ACFEM_TENSORS_TENSORBASE_HH__
4#include <dune/common/fvector.hh>
5#include <dune/common/tupleutility.hh>
7#include "../common/types.hh"
8#include "../mpl/generators.hh"
9#include "../mpl/subtuple.hh"
10#include "../mpl/filter.hh"
11#include "../mpl/compare.hh"
12#include "../mpl/multiindex.hh"
13#include "../expressions/constantoperations.hh"
14#include "../expressions/interface.hh"
16#include "operations/restrictionoperators.hh"
18#define DUNE_ACFEM_TENSOR_WORKAROUND_GCC(MAJOR) DUNE_ACFEM_IS_GCC(MAJOR, MAJOR)
26 using namespace Literals;
27 using namespace Expressions;
32 template<std::size_t... Ints>
38 template<std::size_t... Dimensions>
39 using TensorSignature = Seq<Dimensions...>;
41 template<
class T,
class SFINAE =
void>
47 struct IsTensor<T,
std::enable_if_t<!IsDecay<T>::value> >
48 : IsTensor<std::decay_t<T> >
53 struct IsTensor<T,
std::enable_if_t<(IsDecay<T>::value
54 && T::Signature::size() == T::rank
63 std::enable_if_t<(IsTensor<T>::value
67 decltype(
auto) tensor(T&& t)
69 return std::forward<T>(t);
76 std::enable_if_t<(IsTensor<T>::value
80 std::decay_t<T> tensor(T&& t)
82 return std::forward<T>(t);
92 std::enable_if_t<(IsTensor<T>::value
93 && Expressions::IsClosure<std::decay_t<T> >::value
94 && !IsTypedValue<Operand<0, T> >::value
96 constexpr decltype(
auto) tensor(T&& t)
98 Expressions::danglingReferenceCheck<0>(std::forward<T>(t));
99 return operand<0>(std::forward<T>(t));
104 std::enable_if_t<(IsTensor<T>::value
105 && Expressions::IsClosure<std::decay_t<T> >::value
106 && IsTypedValue<Operand<0, T> >::value
108 std::decay_t<Operand<0, T> > tensor(T&& t)
110 return std::forward<T>(t).template operand<0>();
114 template<
class T,
class SFINAE =
void>
132 template<
class T,
class SFINAE =
void>
136 template<
class T, std::enable_if_t<(IsTensorOperand<T>::value && !IsTensor<T>::value),
int> = 0>
139 return TensorTraits<T>::toTensor(std::forward<T>(t));
143 template<
class Field,
class Seq,
class Impl>
148 class RestrictionOperators;
153 template<
class Field, std::size_t... Dimensions,
class Impl>
154 struct TensorBase<Field, TensorSignature<Dimensions...>, Impl>
155 :
public RestrictionOperators<Impl>
158 using TensorType = Impl;
159 using FieldType = Field;
160 using Signature = TensorSignature<Dimensions...>;
162 static constexpr std::size_t rank =
sizeof...(Dimensions);
167 template<std::size_t... Ind, std::enable_if_t<(
sizeof...(Ind) <= rank),
int> = 0>
168 static std::size_t
constexpr dim(Seq<Ind...> = Seq<Ind...>{})
170 using SubSignature = ConditionalType<
sizeof...(Ind) == 0, Signature, SubSequence<Signature, Ind...> >;
177 template<std::size_t... Ind, std::enable_if_t<(
sizeof...(Ind) > rank),
int> = 0>
178 static std::size_t
constexpr dim(Seq<Ind...> = Seq<Ind...>{})
180 return std::numeric_limits<std::size_t>::max();
184 static auto constexpr signature()
189 template<std::size_t... Indices,
class Pos =
MakeIndexSequence<
sizeof...(Indices)> >
190 static bool constexpr isZero(Seq<Indices...> = Seq<Indices...>{}, Pos = Pos{})
195 std::string name()
const
197 return name(Signature{});
200 template<
class T, std::enable_if_t<(rank == 0 && SameDecay<T, FieldType>::value),
int> = 0>
203 return static_cast<const Impl&
>(*this)();
207 std::string name(Seq<>)
const
209 return std::to_string(
static_cast<const Impl&
>(*
this)());
212 template<std::size_t D0, std::size_t... Rest>
213 std::string name(Seq<D0, Rest...> sig)
const
215 return "tensor<"+toString(sig)+
">";
220 template<
class T,
class SFINAE>
223 using Signature = Seq<>;
224 static constexpr std::size_t rank = std::numeric_limits<std::size_t>::max();
228 constexpr inline bool HasTensorTraitsV =
232 struct TensorTraitsBase
234 using TensorType = std::decay_t<T>;
235 using FieldType =
typename TensorType::FieldType;
236 using Signature =
typename TensorType::Signature;
237 static constexpr std::size_t rank = TensorType::rank;
239 template<std::size_t... Indices,
class Pos =
MakeIndexSequence<
sizeof...(Indices)> >
240 static bool constexpr isZero(Seq<Indices...> = Seq<Indices...>{}, Pos = Pos{})
242 return TensorType::isZero(Seq<Indices...>{}, Pos{});
248 template<std::size_t... Ind, std::enable_if_t<(
sizeof...(Ind) <= rank),
int> = 0>
249 static std::size_t
constexpr dim(Seq<Ind...> = Seq<Ind...>{})
251 using SubSignature = ConditionalType<
sizeof...(Ind) == 0, Signature, SubSequence<Signature, Ind...> >;
258 template<std::size_t... Ind, std::enable_if_t<(
sizeof...(Ind) > rank),
int> = 0>
259 static std::size_t
constexpr dim(Seq<Ind...> = Seq<Ind...>{})
261 return std::numeric_limits<std::size_t>::max();
267 static Signature
constexpr signature()
272 using ZeroIndex = MakeIndexSequence<rank, 0, 0>;
274 static TrueType mutableArg(FieldType&);
275 static FalseType mutableArg(
const FieldType&);
276 static FalseType mutableArg(FieldType&&);
280 template<
class U,
class SFINE =
void>
281 struct ElementZeroHelper
283 using Type =
decltype(std::declval<const U&>()(ZeroIndex{}));
284 static constexpr bool hasMutableCallOperator =
false;
288 struct ElementZeroHelper<U,
VoidType<decltype(
std::declval<U&>()(ZeroIndex{}))> >
290 using Type =
decltype(std::declval<U&>()(ZeroIndex{}));
291 static constexpr bool hasMutableCallOperator =
true;
294 using ElementZero =
typename ElementZeroHelper<T>::Type;
295 static constexpr bool hasMutableComponents =
decltype(mutableArg(std::declval<ElementZero>()))::value;
296 static constexpr bool hasMutableCallOperator = ElementZeroHelper<T>::hasMutableCallOperator;
300 struct TensorTraits<T,
std::enable_if_t<!IsDecay<T>::value> >
301 : TensorTraits<std::decay_t<T> >
305 struct TensorTraits<T,
std::enable_if_t<IsTensor<T>::value && IsDecay<T>::value> >
306 : TensorTraitsBase<T>
309 template<class T, std::enable_if_t<IsTensorOperand<T>::value,
int> = 0>
310 constexpr auto rank(T&& t)
312 return TensorTraits<T>::rank;
315 template<class T, std::enable_if_t<IsTensorOperand<T>::value,
int> = 0>
316 constexpr auto signature(T&& t)
318 return typename TensorTraits<T>::Signature{};
321 template<
class T,
class SFINAE =
void>
329 std::enable_if_t<(IsTensor<T>::value
336 template<
class T,
class SFINAE =
void>
337 struct IsTensorNotZero
342 struct IsTensorNotZero<
344 std::enable_if_t<(IsTensor<T>::value
353 template<
class Tensor,
class Tuple, std::size_t... Unpack>
354 decltype(
auto) tensorValueHelper(Tensor&& t,
356 IndexSequence<Unpack...>&&)
358 return std::forward<Tensor>(t)(std::get<Unpack>(indices)...);
365 std::enable_if_t<(IsTensor<Tensor>::value
366 && IsTupleLike<Tuple>::value
368 decltype(
auto) tensorValue(Tensor&& tensor, Tuple&& indices)
370 return tensorValueHelper(std::forward<Tensor>(tensor), std::forward<Tuple>(indices),
376 std::size_t... Indices,
377 std::enable_if_t<(IsTensor<Tensor>::value
378 &&
sizeof...(Indices) == TensorTraits<Tensor>::rank
380 decltype(
auto) tensorValue(Tensor&& tensor, IndexSequence<Indices...>)
383 return std::forward<Tensor>(tensor)(
IndexSequence<Indices...>{});
387 class T,
class Indices,
388 std::enable_if_t<(IsTensorOperand<T>::value
389 && !IsTensor<T>::value
391 decltype(
auto) tensorValue(T&& t, Indices&& indices)
393 return tensorValue(tensor(std::forward<T>(t)), std::forward<Indices>(indices));
399 template<class T, std::enable_if_t<!Expressions::IsClosure<T>::value && IsTensorOperand<T>::value,
int> = 0>
400 constexpr auto name(T&& t)
402 return tensor(std::forward<T>(t)).name();
405 template<class T, std::enable_if_t<Expressions::IsClosure<T>::value && IsTensor<T>::value,
int> = 0>
406 constexpr auto name(T&& t)
408 return std::forward<T>(t).name();
413 using Tensor::HasTensorTraitsV;
414 using Tensor::IsTensor;
415 using Tensor::IsTensorOperand;
416 using Tensor::TensorTraits;
417 using Tensor::tensor;
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 std::size_t size()
Gives the number of elements in tuple-likes and std::integer_sequence.
Definition: size.hh:73
MakeSequence< std::size_t, N, Offset, Stride, Repeat > MakeIndexSequence
Make a sequence of std::size_t elements.
Definition: generators.hh:34
Sequence< std::size_t, V... > IndexSequence
Sequence of std::size_t values.
Definition: types.hh:64
typename MakeType< void, Other... >::Type VoidType
Generate void regardless of the template argument list.
Definition: types.hh:151
BoolConstant< false > FalseType
Alias for std::false_type.
Definition: types.hh:110
BoolConstant< true > TrueType
Alias for std::true_type.
Definition: types.hh:107
constexpr bool isZero
Shortcut identifying a zero model.
Definition: modeltraits.hh:642
static std::size_t constexpr multiDim(IndexSequence< Dimensions... >, IndexSequence< IndexPositions... >=IndexSequence< IndexPositions... >{})
Compute the "dimension" corresponding to the given signature, i.e.
Definition: multiindex.hh:171
An expression closure is a wrapper class which wraps an expression in order to interface to other exi...
Definition: interface.hh:50
Definition: tensorbase.hh:117
Base class for all tensors.
Definition: tensorbase.hh:144