1#ifndef __DUNE_ACFEM_OPERATORS_FUNCTIONALS_OPERANDPROMOTION_HH__
2#define __DUNE_ACFEM_OPERATORS_FUNCTIONALS_OPERANDPROMOTION_HH__
4#include "../../common/types.hh"
5#include "../../expressions/interface.hh"
6#include "../../tensors/tensor.hh"
7#include "../../functions/functions.hh"
9#include "linearfunctional.hh"
10#include "functionaltraits.hh"
11#include "modules/dofstorage.hh"
17 namespace LinearFunctional {
19 using Expressions::Operand;
20 using namespace Literals;
23 using PromoteTensorOperands =
25 !
AnyIs<Expressions::IsPromotedTopLevel, T...>::value
27 &&
AnyIs<Tensor::IsNonTensorTensorOperand, T...>::value
29 &&
AnyIs<IsLinearFunctional, T...>::value)>;
32 template<std::size_t N,
class... T,
33 std::enable_if_t<(PromoteTensorOperands<T...>::value
34 && !
NthIs<N, Tensor::IsNonTensorTensorOperand, T...>::value
38 return std::forward<
TupleElement<N, std::tuple<T...> > >(
39 get<N>(std::forward_as_tuple(t...))
44 template<std::size_t N,
class... T,
45 std::enable_if_t<(PromoteTensorOperands<T...>::value
46 &&
NthIs<N, Tensor::IsNonTensorTensorOperand, T...>::value
50 return tensor(std::forward<
TupleElement<N, std::tuple<T...> > >(
51 get<N>(std::forward_as_tuple(t...))
56 using PromoteDiscreteFunctionOperands =
58 !
AnyIs<Expressions::IsPromotedTopLevel, T...>::value
60 &&
AnyIs<IsDiscreteFunction, T...>::value
62 &&
AnyIs<IsLinearFunctional, T...>::value)>;
65 template<std::size_t N,
class... T,
66 std::enable_if_t<(PromoteDiscreteFunctionOperands<T...>::value
67 && !
NthIs<N, IsDiscreteFunction, T...>::value
71 return std::forward<
TupleElement<N, std::tuple<T...> > >(
72 get<N>(std::forward_as_tuple(t...))
77 template<std::size_t N,
class... T,
78 std::enable_if_t<(PromoteDiscreteFunctionOperands<T...>::value
79 &&
NthIs<N, IsDiscreteFunction, T...>::value
83 return dofStorageFunctional(
85 get<N>(std::forward_as_tuple(t...))
89 template<
class T,
class SFINAE =
void>
90 struct IsProductWithDiscreteFunction
95 struct IsProductWithDiscreteFunction<
97 std::enable_if_t<(IsTensorFunction<T>::value
98 && IsProductExpression<GridFunction::RangeTensorType<T> >::value
100 :
BoolConstant<(TensorTraits<Operand<0, GridFunction::RangeTensorType<T>> >::rank == 0
101 && IsLocalFunctionPlaceholder<Operand<1, GridFunction::RangeTensorType<T> > >::value
102 && IsDiscreteFunction<
typename Operand<1, GridFunction::RangeTensorType<T> >::GridFunctionType>::value)>
106 using PromoteScaledDiscreteFunctionOperands =
108 !
AnyIs<Expressions::IsPromotedTopLevel, T...>::value
110 &&
AnyIs<IsProductWithDiscreteFunction, T...>::value
112 &&
AnyIs<IsLinearFunctional, T...>::value)>;
115 template<std::size_t N,
class... T,
116 std::enable_if_t<(PromoteScaledDiscreteFunctionOperands<T...>::value
117 && !
NthIs<N, IsProductWithDiscreteFunction, T...>::value
121 return std::forward<
TupleElement<N, std::tuple<T...> > >(
122 get<N>(std::forward_as_tuple(t...))
127 template<std::size_t N,
class... T,
128 std::enable_if_t<(PromoteScaledDiscreteFunctionOperands<T...>::value
129 &&
NthIs<N, IsProductWithDiscreteFunction, T...>::value
134 get<N>(std::forward_as_tuple(t...))
136 return einsum.operand(0_c)*dofStorageFunctional(
einsum.operand(1_c).gridFunction());
constexpr decltype(auto) operandPromotion(T &&... t)
The purpose of this function is to promote operands to other types, e.g.
Definition: interface.hh:154
std::tuple_element_t< N, std::decay_t< TupleLike > > TupleElement
Forward to std::tuple_element<N, std::decay_t<T> >
Definition: access.hh:125
constexpr decltype(auto) einsum(T1 &&t1, T2 &&t2)
Tensor contraction for proper tensors.
Definition: einsum.hh:561
Predicate< TypePackElement< N, T... > > NthIs
Instantiates to Predicate applied to the N-th element of T...
Definition: compare.hh:470
BoolConstant<(...||Predicate< T >::value)> AnyIs
TrueType if any type matches the predicate.
Definition: compare.hh:462
Constant< bool, V > BoolConstant
Short-cut for integral constant of type bool.
Definition: types.hh:48
BoolConstant< false > FalseType
Alias for std::false_type.
Definition: types.hh:110