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