1#ifndef __DUNE_ACFEM_FUNCTIONAL_EXPRESSIONS_HH__
2#define __DUNE_ACFEM_FUNCTIONAL_EXPRESSIONS_HH__
4#include "functionalexpressionbase.hh"
5#include "../../expressions/parameterexpression.hh"
34 template<
class UnOp,
class Functional>
35 class UnaryFunctionalExpression;
37 template<
class UnOp,
class Functional>
38 class UnaryLocalFunctionalExpression;
40 template<
class BinOp,
class LeftFunctionional,
class RightFunctionional>
41 class BinaryFunctionalExpression;
43 template<
class BinOp,
class LeftFunctionional,
class RightFunctionional>
44 class BinaryLocalFunctionalExpression;
47 struct UnaryFunctionalExpressionOperation
51 struct UnaryFunctionalExpressionOperation<MinusOperation>
53 template<
class Scalar>
54 static Scalar apply(
const Scalar& s)
61 struct UnaryFunctionalExpressionOperation<IdentityOperation>
63 template<
class Scalar>
64 static Scalar apply(
const Scalar& s)
71 template<
class UnOp,
class Functional>
74 UnaryLocalFunctionalExpression<UnOp, Functional> >
77 template<
class UnOp,
class Functional>
78 class UnaryFunctionalExpression
79 :
public DiscreteLinearFunctionalExpression<typename Functional::DiscreteFunctionSpaceType,
80 UnaryFunctionalExpressionTraits<UnOp, Functional> >
83 typedef UnaryFunctionalExpression ThisType;
85 typedef typename Functional::DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
88 typedef DiscreteLinearFunctionalExpression<DiscreteFunctionSpaceType, TraitsType> BaseType;
90 typedef Functional ContainedExpressionType;
91 typedef typename TraitsType::LocalFunctionalType LocalFunctionalType;
92 typedef typename DiscreteFunctionSpaceType::GridPartType GridPartType;
93 typedef typename DiscreteFunctionSpaceType::EntityType EntityType;
94 typedef typename DiscreteFunctionSpaceType::RangeFieldType FieldType;
95 typedef FieldType RangeType;
97 UnaryFunctionalExpression(
const ContainedExpressionType& phi)
98 : BaseType(phi.space()), functional_(phi)
101 using BaseType::operator();
102 using BaseType::coefficients;
103 using BaseType::space;
104 using BaseType::localFunctional;
106 const ContainedExpressionType& containedExpression()
const
108 return functional_();
111 std::string name()
const
113 return OpType::name() +
"(" + functional_().name() +
")";
117 ExpressionStorage<ContainedExpressionType> functional_;
120 template<
class UnOp,
class Functional>
121 class UnaryLocalFunctionalExpression
123 LocalLinearFunctionalDefault<typename Functional::DiscreteFunctionSpaceType,
124 UnaryFunctionalExpressionTraits<UnOp, Functional> >
127 typedef UnaryFunctionalExpressionOperation<OpType> OperationType;
128 typedef UnaryLocalFunctionalExpression ThisType;
130 typedef typename Functional::DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
131 typedef UnaryFunctionalExpressionTraits<OpType, Functional> TraitsType;
132 typedef typename TraitsType::GlobalFunctionalType FunctionalType;
133 typedef typename TraitsType::LocalFunctionalType LocalFunctionalType;
135 typedef LocalLinearFunctionalDefault<DiscreteFunctionSpaceType, TraitsType> BaseType;
137 typedef Functional ContainedFunctionalType;
138 typedef typename Functional::LocalFunctionalType ContainedLocalFunctionalType;
140 typedef typename DiscreteFunctionSpaceType::EntityType EntityType;
141 typedef typename DiscreteFunctionSpaceType::RangeFieldType FieldType;
142 typedef FieldType RangeType;
144 UnaryLocalFunctionalExpression(
const FunctionalType& expr)
145 : BaseType(expr), localContainedFunctional_(expr.containedExpression())
148 UnaryLocalFunctionalExpression(
const EntityType& entity,
const FunctionalType& expr)
149 : BaseType(entity, expr),
150 localContainedFunctional_(expr.containedExpression().localFunctional(entity))
154 void init(
const EntityType& entity)
156 localContainedFunctional_.init(entity);
160 template<
class LocalFunction>
161 RangeType
operator()(
const LocalFunction& arg)
163 return OperationType::apply(localContainedFunctional_(arg));
166 template<
class LocalFunction>
167 void coefficients(
const RangeType& c, LocalFunction& coeffs)
const
169 localContainedFunctional_.coefficients(OperationType::apply(c), coeffs);
172 template<
class LocalFunction>
178 using BaseType::functional;
179 using BaseType::entity;
182 ContainedLocalFunctionalType localContainedFunctional_;
190 template<
class BinOp>
191 struct BinaryFunctionalExpressionOperation
195 struct BinaryFunctionalExpressionOperation<PlusOperation>
197 template<
class Field>
198 static Field apply(
const Field& left,
const Field& right)
203 template<
class Field,
class LeftArg,
class RightArg,
class LocalFunction>
204 static void apply(
const Field& c,
const LeftArg& left,
const RightArg& right, LocalFunction& coeffs)
206 left.coefficients(c, coeffs);
207 right.coefficients(c, coeffs);
211 static std::string leftName(
const Left& left)
216 template<
class Right>
217 static std::string rightName(
const Right& right)
224 struct BinaryFunctionalExpressionOperation<MinusOperation>
226 template<
class Field>
227 static Field apply(
const Field& left,
const Field& right)
232 template<
class Field,
class LeftArg,
class RightArg,
class LocalFunction>
233 static void apply(
const Field& c,
const LeftArg& left,
const RightArg& right, LocalFunction& coeffs)
235 left.coefficients(c, coeffs);
236 right.coefficients(-c, coeffs);
240 static std::string leftName(
const Left& left)
245 template<
class Right>
246 static std::string rightName(
const Right& right)
253 struct BinaryFunctionalExpressionOperation<SMultiplyOperation>
255 template<
class Field>
256 static Field apply(
const Field& left,
const Field& right)
261 template<
class Field,
class LocalFunctional,
class LocalFunction>
262 static void apply(
const Field& c,
const Field& left,
const LocalFunctional& phiLoc, LocalFunction& coeffs)
264 phiLoc.coefficients(c * left, coeffs);
267 template<
class Field>
268 static std::string leftName(
const Field& left)
271 if (ParameterValue<Field>::isParameter) {
272 factorName =
"P(" + factorName +
")";
277 template<
class Right>
278 static std::string rightName(
const Right& right)
285 template<
class BinOp,
class LeftArg,
class RightArg>
288 BinaryLocalFunctionalExpression<BinOp, LeftArg, RightArg> >
294 template<
class BinOp,
class LeftArg,
class RightArg>
296 :
public DiscreteLinearFunctionalExpression<typename RightArg::DiscreteFunctionSpaceType,
297 BinaryFunctionalExpressionTraits<BinOp, LeftArg, RightArg> >
299 typedef BinOp OpType;
300 typedef BinaryFunctionalExpressionOperation<OpType> OperationType;
303 typedef typename RightArg::DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
306 typedef DiscreteLinearFunctionalExpression<DiscreteFunctionSpaceType, TraitsType> BaseType;
308 typedef LeftArg LeftExpressionType;
309 typedef RightArg RightExpressionType;
310 typedef typename TraitsType::LocalFunctionalType LocalFunctionalType;
311 typedef typename DiscreteFunctionSpaceType::GridPartType GridPartType;
312 typedef typename DiscreteFunctionSpaceType::EntityType EntityType;
313 typedef typename DiscreteFunctionSpaceType::RangeFieldType FieldType;
314 typedef FieldType RangeType;
317 : BaseType(right.space()), left_(left), right_(right)
320 using BaseType::operator();
321 using BaseType::coefficients;
322 using BaseType::space;
323 using BaseType::localFunctional;
325 const LeftExpressionType& leftExpression()
const
329 const RightExpressionType& rightExpression()
const
334 std::string name()
const
337 OperationType::leftName(left_())
341 OperationType::rightName(right_())
350 template<
class BinOp,
class LeftArg,
class RightArg>
351 class BinaryLocalFunctionalExpression
354 BinaryFunctionalExpressionTraits<BinOp, LeftArg, RightArg> >
356 typedef BinOp OpType;
357 typedef BinaryFunctionalExpressionOperation<OpType> OperationType;
358 typedef BinaryLocalFunctionalExpression ThisType;
360 typedef typename LeftArg::DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
362 typedef typename TraitsType::GlobalFunctionalType FunctionalType;
363 typedef typename TraitsType::LocalFunctionalType LocalFunctionalType;
367 typedef LeftArg LeftExpressionType;
368 typedef RightArg RightExpressionType;
369 typedef typename LeftArg::LocalFunctionalType LeftLocalFunctionalType;
370 typedef typename RightArg::LocalFunctionalType RightLocalFunctionalType;
372 typedef typename DiscreteFunctionSpaceType::EntityType EntityType;
373 typedef typename DiscreteFunctionSpaceType::RangeFieldType FieldType;
374 typedef FieldType RangeType;
376 BinaryLocalFunctionalExpression(
const FunctionalType& expr)
378 leftLocalFunctional_(expr.leftExpression()),
379 rightLocalFunctional_(expr.rightExpression())
382 BinaryLocalFunctionalExpression(
const EntityType& entity,
const FunctionalType& expr)
383 : BaseType(entity, expr),
384 leftLocalFunctional_(expr.leftExpression().localFunctional(entity)),
385 rightLocalFunctional_(expr.rightExpression().localFunctional(entity))
389 void init(
const EntityType& entity)
391 leftLocalFunctional_.init(entity);
392 rightLocalFunctional_.init(entity);
396 template<
class LocalFunction>
397 RangeType
operator()(
const LocalFunction& arg)
399 return OperationType::apply(leftLocalFunctional_(arg), rightLocalFunctional_(arg));
402 template<
class LocalFunction>
403 void coefficients(
const RangeType& c, LocalFunction& coeffs)
const
405 OperationType::apply(c, leftLocalFunctional_, rightLocalFunctional_, coeffs);
408 template<
class LocalFunction>
414 using BaseType::functional;
415 using BaseType::entity;
418 LeftLocalFunctionalType leftLocalFunctional_;
419 RightLocalFunctionalType rightLocalFunctional_;
434 template<
class LeftArg,
class RightArg>
438 BinaryFunctionalExpressionTraits<SMultiplyOperation, LeftArg, RightArg> >
441 typedef BinaryFunctionalExpressionOperation<OpType> OperationType;
442 typedef BinaryLocalFunctionalExpression ThisType;
444 typedef typename RightArg::DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
447 typedef typename TraitsType::LocalFunctionalType LocalFunctionalType;
451 typedef LeftArg LeftExpressionType;
452 typedef RightArg RightExpressionType;
453 typedef LeftExpressionType FactorType;
454 typedef typename RightArg::LocalFunctionalType SubLocalFunctionalType;
456 typedef typename DiscreteFunctionSpaceType::EntityType EntityType;
457 typedef typename DiscreteFunctionSpaceType::RangeFieldType FieldType;
458 typedef FieldType RangeType;
460 BinaryLocalFunctionalExpression(
const FunctionalType& expr)
462 scalar_(expr.leftExpression()),
463 localFunctional_(expr.rightExpression())
466 BinaryLocalFunctionalExpression(
const EntityType& entity,
const FunctionalType& expr)
468 scalar_(expr.leftExpression()),
469 localFunctional_(expr.rightExpression().localFunctional(entity))
473 void init(
const EntityType& entity)
475 localFunctional_.
init(entity);
479 template<
class LocalFunction>
480 RangeType operator()(
const LocalFunction& arg)
482 return OperationType::apply(RangeType(
parameterValue(scalar_)), localFunctional_(arg));
485 template<
class LocalFunction>
486 void coefficients(
const RangeType& c, LocalFunction& coeffs)
const
488 OperationType::apply(c, RangeType(
parameterValue(scalar_)), localFunctional_, coeffs);
491 template<
class LocalFunction>
492 void coefficients(LocalFunction& coeffs)
const
497 using BaseType::functional;
498 using BaseType::entity;
501 const FactorType& scalar_;
502 SubLocalFunctionalType localFunctional_;
513 template<
class DiscreteFunctionSpace,
class Traits>
514 UnaryFunctionalExpression<MinusOperation, typename Traits::GlobalFunctionalType>
517 typedef typename Traits::GlobalFunctionalType FunctionalType;
518 const FunctionalType& phi(
static_cast<const FunctionalType&
>(phi_));
521 UnaryFunctionalExpression<MinusOperation, FunctionalType>
524 return ExpressionType(phi);
528 template<
class DiscreteFunctionSpace,
class Traits>
529 UnaryFunctionalExpression<IdentityOperation, typename Traits::GlobalFunctionalType>
532 typedef typename Traits::GlobalFunctionalType FunctionalType;
533 const FunctionalType& phi(
static_cast<const FunctionalType&
>(phi_));
536 UnaryFunctionalExpression<IdentityOperation, FunctionalType>
539 return ExpressionType(phi);
545 template<
class DiscreteFunctionSpace,
class LeftTraits,
class RightTraits>
546 BinaryFunctionalExpression<PlusOperation,
547 typename LeftTraits::GlobalFunctionalType,
548 typename RightTraits::GlobalFunctionalType>
552 typedef typename LeftTraits::GlobalFunctionalType LeftType;
553 typedef typename RightTraits::GlobalFunctionalType RightType;
555 const LeftType& left(
static_cast<const LeftType&
>(left_));
556 const RightType& right(
static_cast<const RightType&
>(right_));
562 return ExpressionType(left, right);
566 template<
class DiscreteFunctionSpace,
class LeftTraits,
class RightTraits>
567 BinaryFunctionalExpression<MinusOperation,
568 typename LeftTraits::GlobalFunctionalType,
569 typename RightTraits::GlobalFunctionalType>
573 typedef typename LeftTraits::GlobalFunctionalType LeftType;
574 typedef typename RightTraits::GlobalFunctionalType RightType;
576 const LeftType& left(
static_cast<const LeftType&
>(left_));
577 const RightType& right(
static_cast<const RightType&
>(right_));
583 return ExpressionType(left, right);
587 template<
class DiscreteFunctionSpace,
class LeftTraits,
class Functional>
590 const UnaryFunctionalExpression<MinusOperation, Functional>& right_)
591 ->
decltype(
asImp(left_) + right_.containedExpression())
593 return asImp(left_) + right_.containedExpression();
597 template<
class DiscreteFunctionSpace,
class Functional,
class RightTraits>
599 operator+(
const UnaryFunctionalExpression<MinusOperation, Functional>& left_,
601 ->
decltype(
asImp(right_) - left_.containedExpression())
603 return asImp(right_) - left_.containedExpression();
607 template<
class DiscreteFunctionSpace,
class LeftTraits,
class Functional>
610 const UnaryFunctionalExpression<MinusOperation, Functional>& right_)
611 ->
decltype(
asImp(left_) - right_.containedExpression())
613 return asImp(left_) - right_.containedExpression();
617 template<
class Left,
class Right>
619 operator+(
const UnaryFunctionalExpression<MinusOperation, Left>& left_,
620 const UnaryFunctionalExpression<MinusOperation, Right>& right_)
621 ->
decltype(-(left_.containedExpression() + right_.containedExpression()))
623 return left_.containedExpression() + right_.containedExpression();
631 template<
class DiscreteFunctionSpace,
class Traits>
632 BinaryFunctionalExpression<SMultiplyOperation,
633 const typename DiscreteFunctionSpace::RangeFieldType,
634 typename Traits::GlobalFunctionalType>
635 operator*(
const typename DiscreteFunctionSpace::RangeFieldType& left_,
638 typedef typename Traits::GlobalFunctionalType FunctionalType;
639 typedef typename DiscreteFunctionSpace::RangeFieldType ScalarType;
647 const FunctionalType& right(
static_cast<const FunctionalType&
>(right_));
649 return ExpressionType(left_, right);
653 template<
class DiscreteFunctionSpace,
class Traits>
656 const typename DiscreteFunctionSpace::RangeFieldType& right_)
657 ->
decltype(right_ *
asImp(left_))
659 return right_ *
asImp(left_);
663 template<
class DiscreteFunctionSpace,
class Traits>
666 const typename DiscreteFunctionSpace::RangeFieldType& right_)
667 ->
decltype(
asImp(left_) * (1.0/right_))
669 return asImp(left_) * (1.0/right_);
673 template<
class Parameter,
class DiscreteFunctionSpace,
class Traits>
674 BinaryFunctionalExpression<SMultiplyOperation, Parameter, typename Traits::GlobalFunctionalType>
678 typedef typename Traits::GlobalFunctionalType FunctionalType;
679 typedef Parameter ScalarType;
685 const ScalarType& left(
static_cast<const ScalarType&
>(left_));
686 const FunctionalType& right(
static_cast<const FunctionalType&
>(right_));
688 return ExpressionType(left, right);
692 template<
class DiscreteFunctionSpace,
class Traits,
class Parameter>
709 template<
class Field,
class Functional>
713 ->
decltype((s * psi.leftExpression()) * psi.rightExpression())
715 return (s * psi.leftExpression()) * psi.rightExpression();
719 template<
class Parameter,
class Field,
class Functional>
723 ->
decltype(psi.leftExpression() * (
asImp(p_) * psi.rightExpression()))
725 return psi.leftExpression() * (
asImp(p_) * psi.rightExpression());
729 template<
class Field,
class Parameter,
class DiscreteFunctionSpace,
class Traits>
731 auto operator*(
const BinaryParameterExpression<SMultiplyOperation, Field, Parameter>& p_,
733 ->
decltype(p_.left() * (p_.right() *
asImp(psi_)))
735 return p_.left() * (p_.right() *
asImp(psi_));
739 template<
class Parameter,
class DiscreteFunctionSpace,
class ZeroTraits>
743 BinaryParameterExpression<SMultiplyOperation, typename DiscreteFunctionSpace::RangeFieldType, Parameter>& p,
744 const ZeroFunctionalExpression<DiscreteFunctionSpace, ZeroTraits>& phi_)
751 template<
class DiscreteFunctionSpace,
class Traits>
752 typename Traits::GlobalFunctionalType
753 operator*(
const DiscreteLinearFunctionalExpression<DiscreteFunctionSpace, Traits>& phi_)
755 return phi_.expression();
765 template<
class Functional>
767 operator-(
const UnaryFunctionalExpression<MinusOperation, Functional>& phi_)
768 ->
decltype(*phi_.containedExpression())
770 return *phi_.containedExpression();
774 template<
class DiscreteFunctionSpace,
class Traits>
776 operator-(
const ZeroFunctionalExpression<DiscreteFunctionSpace, Traits>& phi_)
783 template<
class DiscreteFunctionSpace,
class Traits,
class ZeroTraits>
786 const ZeroFunctionalExpression<DiscreteFunctionSpace, ZeroTraits>& z_)
787 ->
decltype(*
asImp(phi_))
793 template<
class DiscreteFunctionSpace,
class Traits,
class ZeroTraits>
795 operator+(
const ZeroFunctionalExpression<DiscreteFunctionSpace, ZeroTraits>& z_,
797 ->
decltype(*
asImp(phi_))
803 template<
class DiscreteFunctionSpace,
class ZeroTraits1,
class ZeroTraits2>
804 ZeroFunctional<DiscreteFunctionSpace>
805 operator+(
const ZeroFunctionalExpression<DiscreteFunctionSpace, ZeroTraits1>& left_,
806 const ZeroFunctionalExpression<DiscreteFunctionSpace, ZeroTraits2>& right_)
812 template<
class DiscreteFunctionSpace,
class Traits,
class ZeroTraits>
815 const ZeroFunctionalExpression<DiscreteFunctionSpace, ZeroTraits>& z_)
816 ->
decltype(*
asImp(phi_))
822 template<
class DiscreteFunctionSpace,
class Traits,
class ZeroTraits>
824 operator-(
const ZeroFunctionalExpression<DiscreteFunctionSpace, ZeroTraits>& z_,
826 ->
decltype(-
asImp(phi_))
832 template<
class DiscreteFunctionSpace,
class ZeroTraits1,
class ZeroTraits2>
833 ZeroFunctional<DiscreteFunctionSpace>
834 operator-(
const ZeroFunctionalExpression<DiscreteFunctionSpace, ZeroTraits1>& left_,
835 const ZeroFunctionalExpression<DiscreteFunctionSpace, ZeroTraits2>& right_)
841 template<
class DiscreteFunctionSpace,
class ZeroTraits>
843 operator*(
const typename DiscreteFunctionSpace::RangeFieldType& s,
844 const ZeroFunctionalExpression<DiscreteFunctionSpace, ZeroTraits>& z)
851 template<
class DiscreteFunctionSpace,
class ZeroTraits>
853 operator*(
const ZeroFunctionalExpression<DiscreteFunctionSpace, ZeroTraits>& z,
854 const typename DiscreteFunctionSpace::RangeFieldType& s)
861 template<
class Parameter,
class DiscreteFunctionSpace,
class ZeroTraits>
864 const ZeroFunctionalExpression<DiscreteFunctionSpace, ZeroTraits>& z)
871 template<
class Parameter,
class DiscreteFunctionSpace,
class ZeroTraits>
873 operator*(
const ZeroFunctionalExpression<DiscreteFunctionSpace, ZeroTraits>& z,
Binary functional expression.
Definition: functionalexpression.hh:298
Interface class for a discrete linear functional.
Definition: linearfunctional.hh:52
Default implementation for LocalLinearFunctional.
Definition: linearfunctional.hh:362
void coefficients(const RangeType &c, LocalFunction &coeffs) const
Definition: linearfunctional.hh:443
void coefficients(LocalFunction &coeffs) const
Compute the basis representation, which means: do the assembling stuff.
Definition: linearfunctional.hh:436
void init(const EntityType &entity)
Bind to an entity.
Definition: linearfunctional.hh:403
RangeType operator()(const LocalFunction &arg) const
Compute the value.
Definition: linearfunctional.hh:410
Parameters are quasi-constant quantities, like the time-step size in one time-step when solving trans...
Definition: parameterinterface.hh:80
This is the famous "do-nothing" functional.
Definition: zerofunctional.hh:42
static auto operator/(const Fem::Function< typename Left::FunctionSpaceType, Left > &f_, const BoundarySupportedFunction< Right, RightInd > &g_) -> decltype(asBndryFct(asEssBndryFct(f_/asExprArg(g_))))
f / Wrapped(g) = Wrapped(f / g)
Definition: boundaryfunctionexpression.hh:657
const Implementation & asImp(const Fem::BartonNackmanInterface< Interface, Implementation > &arg)
Up-cast to the implementation for any Fem::BartonNackmanInterface.
Definition: expressionoperations.hh:71
ParameterValue< Value >::ResultType parameterValue(const Value &value)
Return the unaltered argument for non-parameters and otherwise the parameter value.
Definition: parameterinterface.hh:263
BinaryParameterExpression< MultiplyOperation, Left, Right > operator*(const ParameterInterface< Left > &left, const ParameterInterface< Right > &right)
Scalar product between parameters.
Definition: parameterexpression.hh:321
"No-storage", traits, stuff lives on the stack
Definition: functionalexpression.hh:289
Default traits were the local objects are not cached, but created on the fly.
Definition: linearfunctional.hh:38
Multiplication by scalars from the left.
Definition: expressionoperations.hh:257
"No-storage", traits, stuff lives on the stack
Definition: functionalexpression.hh:75