1#ifndef __DUNE_ACFEM_BOUNDARYFUNCTIONEXPRESSION_HH__
2#define __DUNE_ACFEM_BOUNDARYFUNCTIONEXPRESSION_HH__
4#include "../functions/boundarysupportedfunction.hh"
5#include "../functions/gridfunctionexpression.hh"
6#include "../expressions/parameterinterface.hh"
7#include "../expressions/parameterexpression.hh"
51 BoundarySupportedFunction<F>
52 asBndryFct(
const Fem::Function<typename F::FunctionSpaceType, F>& f_)
54 return BoundarySupportedFunction<F>(f_, EntireBoundaryIndicatorType());
58 template<
class F,
class FInd>
59 BoundarySupportedFunction<F>
60 asBndryFct(
const BoundarySupportedFunction<F, EntireBoundaryIndicatorType>& f_)
67 auto asBndryFct(
const BoundarySupportedFunction<F, EmptyBoundaryIndicatorType>& f_)
68 -> BoundarySupportedFunction<
decltype(
zeroFunction(f_)), EmptyBoundaryIndicatorType>
71 BoundarySupportedFunction<
decltype(
zeroFunction(f_)), EmptyBoundaryIndicatorType>
74 return ResultType(
zeroFunction(f_), EmptyBoundaryIndicatorType());
82 template<
class Gr
idFunction>
85 typedef GridFunction Type;
86 static const Type& construct(
const Type& arg)
92 template<
class Gr
idFunction,
class Indicator>
93 struct EssBndryFct<BoundarySupportedFunction<GridFunction, Indicator> >
95 typedef BoundarySupportedFunction<GridFunction, Indicator> Type;
96 static const Type& construct(
const Type& arg)
103 template<
class Gr
idFunction>
104 struct EssBndryFct<BoundarySupportedFunction<GridFunction, EntireBoundaryIndicatorType> >
106 typedef BoundarySupportedFunction<GridFunction, EntireBoundaryIndicatorType> BndryFctType;
107 typedef GridFunction Type;
108 static const Type& construct(
const BndryFctType& arg)
110 return arg.function();
116 template<
class Gr
idFunction>
117 struct EssBndryFct<BoundarySupportedFunction<GridFunction, EmptyBoundaryIndicatorType> >
119 typedef BoundarySupportedFunction<GridFunction, EmptyBoundaryIndicatorType> BndryFctType;
120 typedef ZeroGridFunction<
typename GridFunction::FunctionSpaceType,
121 typename GridFunction::GridPartType> Type;
122 static Type construct(
const BndryFctType& arg)
124 return Type(arg.gridPart());
129 template<
class Gr
idFunction>
130 auto asEssBndryFct(
const GridFunction& arg)
131 ->
decltype(EssBndryFct<GridFunction>::construct(arg))
133 return EssBndryFct<GridFunction>::construct(arg);
138 template<
class Gr
idFunction,
class Indicator>
140 asExprArg(
const BoundarySupportedFunction<GridFunction, Indicator>& arg)
149 template<
class Gr
idFunction>
151 asExprArg(
const BoundarySupportedFunction<GridFunction, EmptyBoundaryIndicatorType>& arg)
152 ->
decltype(asEssBndryFct(arg))
154 return asEssBndryFct(arg);
160 template<
class Function,
class Indicator>
165 typedef decltype(-f_.function()) InnerExpressionType;
168 return ExpressionType(-f_.function(), f_.outerIndicator());
172 template<
class Function,
class Indicator>
180 template<
class Left,
class Right,
class LeftInd,
class RightInd>
182 auto operator+(
const BoundarySupportedFunction<Left, LeftInd>& f_,
183 const BoundarySupportedFunction<Right, RightInd>& g_)
184 ->
decltype(asBndryFct(asExprArg(f_) + asExprArg(g_)))
186 return asBndryFct(asExprArg(f_) + asExprArg(g_));
190 template<
class Left,
class Right,
class LeftInd>
193 const Fem::Function<typename Right::FunctionSpaceType, Right>& g_)
194 ->
decltype(asBndryFct(asExprArg(f_) + g_))
196 return asBndryFct(asExprArg(f_) + g_);
200 template<
class Left,
class Right,
class RightInd>
202 auto operator+(
const Fem::Function<typename Left::FunctionSpaceType, Left>& f_,
204 ->
decltype(asBndryFct(f_ + asExprArg(g_)))
206 return asBndryFct(f_ + asExprArg(g_));
214 template<
class ZeroExpression,
class Left,
class LeftInd>
218 ->
decltype(asBndryFct(asExprArg(f_) + g_))
220 return asBndryFct(asExprArg(f_) + g_);
228 template<
class ZeroExpression,
class Right,
class RightInd>
232 ->
decltype(asBndryFct(f_ + asExprArg(g_)))
234 return asBndryFct(f_ + asExprArg(g_));
238 template<
class F,
class FC,
class Z>
248 template<
class F,
class FC,
class Z>
258 template<
class Z1,
class Z2>
260 BoundarySupportedFunction<ZeroGridFunction<
typename Z1::FunctionSpaceType,
261 typename Z1::GridPartType>,
262 EmptyBoundaryIndicatorType>
274 return ResultType(ZeroFunction(z1_.gridPart()), EmptyBoundaryIndicatorType());
278 template<
class Left,
class Right,
class LeftInd,
class RightInd>
282 ->
decltype(asBndryFct(asExprArg(f_) - asExprArg(g_)))
284 return asBndryFct(asExprArg(f_) - asExprArg(g_));
288 template<
class Left,
class Right,
class LeftInd>
291 const Fem::Function<typename Right::FunctionSpaceType, Right>& g_)
292 ->
decltype(asBndryFct(asExprArg(f_) - g_))
294 return asBndryFct(asExprArg(f_) - g_);
298 template<
class Left,
class Right,
class RightInd>
300 auto operator-(
const Fem::Function<typename Left::FunctionSpaceType, Left>& f_,
302 ->
decltype(asBndryFct(f_ - asExprArg(g_)))
304 return asBndryFct(f_ - asExprArg(g_));
308 template<
class F,
class FC,
class Z>
318 template<
class F,
class FC,
class Z>
328 template<
class Z1,
class Z2>
330 BoundarySupportedFunction<ZeroGridFunction<
typename Z1::FunctionSpaceType,
331 typename Z1::GridPartType>,
332 EmptyBoundaryIndicatorType>
344 return ResultType(ZeroFunction(z1_.gridPart()), EmptyBoundaryIndicatorType());
348 template<
class Function,
class Indicator>
350 auto operator*(
const typename Function::RangeFieldType& s_,
352 ->
decltype(asBndryFct(asEssBndryFct(s_ * asExprArg(f_))))
354 return asBndryFct(asEssBndryFct(s_ * asExprArg(f_)));
358 template<
class Function>
360 BoundarySupportedFunction<ZeroGridFunction<
typename Function::FunctionSpaceType,
361 typename Function::GridPartType>,
362 EmptyBoundaryIndicatorType>
368 typename Function::GridPartType>
370 typedef EmptyBoundaryIndicatorType IndicatorType;
373 return ExpressionType(ZeroType(f_.gridPart()), IndicatorType());
377 template<
class Function,
class Indicator>
380 const typename Function::RangeFieldType& s_)
387 template<
class Parameter,
class Function,
class Indicator>
391 ->
decltype(asBndryFct(asEssBndryFct(
asImp(p_) * asExprArg(f_))))
393 return asBndryFct(asEssBndryFct(
asImp(p_) * asExprArg(f_)));
397 template<
class Parameter,
class Function>
399 BoundarySupportedFunction<ZeroGridFunction<
typename Function::FunctionSpaceType,
400 typename Function::GridPartType>,
401 EmptyBoundaryIndicatorType>
407 typename Function::GridPartType>
409 typedef EmptyBoundaryIndicatorType IndicatorType;
412 return ExpressionType(ZeroType(f_.gridPart()), IndicatorType());
415 template<
class Parameter,
class Function,
class Indicator>
417 auto operator*(
const BoundarySupportedFunction<Function, Indicator>& f_,
418 const ParameterInterface<Parameter>& p_)
419 ->
decltype(
asImp(p_) * f_)
421 return asImp(p_) * f_;
425 template<
class Field,
class Parameter,
class Function,
class Indicator>
427 auto operator*(
const BinaryParameterExpression<SMultiplyOperation, Field, Parameter>& p_,
429 ->
decltype(p_.left() * (p_.right() * f_))
431 return p_.left() * (p_.right() * f_);
435 template<
class Left,
class Right,
class LeftInd,
class RightInd>
439 ->
decltype(asBndryFct(asEssBndryFct(asExprArg(f_) * asExprArg(g_))))
441 return asBndryFct(asEssBndryFct(asExprArg(f_) * asExprArg(g_)));
448 template<
class Zero,
class F,
class FInd>
454 typedef decltype(
zeroProduct(z_, f_)) InnerExpressionType;
455 typedef EmptyBoundaryIndicatorType IndicatorType;
458 return ExpressionType(
zeroProduct(z_, f_), IndicatorType());
465 template<
class F,
class Zero,
class FInd>
471 typedef decltype(
zeroProduct(z_, f_)) InnerExpressionType;
472 typedef EmptyBoundaryIndicatorType IndicatorType;
475 return ExpressionType(
zeroProduct(f_, z_), IndicatorType());
482 template<
class Left,
class Right>
488 typedef decltype(
zeroProduct(z1_, z2_)) InnerExpressionType;
489 typedef EmptyBoundaryIndicatorType IndicatorType;
492 return ExpressionType(
zeroProduct(z1_, z2_), IndicatorType());
502 template<
class Left,
class Right,
class RightInd>
504 auto operator*(
const Fem::Function<typename Left::FunctionSpaceType, Left>& f_,
509 typedef EssBndryFct<
decltype(
asImp(f_) * g_.function())> EssBndryTraits;
510 typedef typename EssBndryTraits::Type InnerExpressionType;
516 return ExpressionType(asEssBndryFct(
asImp(f_) * g_.function()), g_.indicator());
520 template<
class Left,
class Right>
522 auto operator*(
const Fem::Function<typename Left::FunctionSpaceType, Left>& f_,
527 typedef EmptyBoundaryIndicatorType IndicatorType;
530 return ExpressionType(InnerExpressionType(g_.gridPart()), IndicatorType());
534 template<
class ZeroExpression,
class Function,
class Indicator>
541 typedef decltype(
zeroProduct(*z_, b_)) InnerExpressionType;
545 return ExpressionType(*z_, b_.indicator());
549 template<
class ZeroExpression,
class Right>
555 typedef decltype(
zeroProduct(*f_, g_)) InnerExpressionType;
556 typedef EmptyBoundaryIndicatorType IndicatorType;
559 return ExpressionType(InnerExpressionType((*f_).gridPart()), IndicatorType());
569 template<
class Function,
class Wrapped,
class Indicator>
572 const Fem::Function<typename Function::FunctionSpaceType, Function>& f_)
576 typedef EssBndryFct<
decltype(b_.function() *
asImp(f_))> EssBndryTraits;
577 typedef typename EssBndryTraits::Type InnerExpressionType;
583 return ExpressionType(asEssBndryFct(b_.function() *
asImp(f_)), b_.indicator());
587 template<
class Function,
class Wrapped>
590 const Fem::Function<typename Function::FunctionSpaceType, Function>& f_)
594 typedef EmptyBoundaryIndicatorType IndicatorType;
597 return ExpressionType(InnerExpressionType(b_.gridPart()), IndicatorType());
601 template<
class ZeroExpression,
class Wrapped,
class Indicator>
608 typedef decltype(
zeroProduct(b_, *z_)) InnerExpressionType;
612 return ExpressionType(InnerExpressionType(b_.gridPart()), b_.indicator());
616 template<
class ZeroExpression,
class Wrapped>
622 typedef decltype(
zeroProduct(b_, *z_)) InnerExpressionType;
623 typedef EmptyBoundaryIndicatorType IndicatorType;
626 return ExpressionType(InnerExpressionType(b_.gridPart()), IndicatorType());
635 template<
class Function,
class Indicator>
637 BoundarySupportedFunction<Function, Indicator>
645 template<
class Function,
class Indicator>
647 BoundarySupportedFunction<Function, Indicator>
649 const decltype(
oneFunction(std::declval<Function>()))& one)
655 template<
class Left,
class Right,
class RightInd>
657 auto operator/(
const Fem::Function<typename Left::FunctionSpaceType, Left>& f_,
659 ->
decltype(asBndryFct(asEssBndryFct(f_ / asExprArg(g_))))
661 return asBndryFct(asEssBndryFct(f_ / asExprArg(g_)));
665 template<
class Function,
class Indicator>
667 auto operator/(
const typename Function::RangeFieldType& s_,
669 ->
decltype(asBndryFct(asEssBndryFct(s_ / asExprArg(f_))))
671 return asBndryFct(asEssBndryFct(s_ / asExprArg(f_)));
675 template<
class Parameter,
class Function,
class Indicator>
679 ->
decltype(asBndryFct(asEssBndryFct(
asImp(p_) / asExprArg(f_))))
681 return asBndryFct(asEssBndryFct(
asImp(p_) / asExprArg(f_)));
689 template<
class Function,
class Gr
idPart>
691 GridFunctionWrapper<UnaryFunctionExpression<ExpOperation, Function>, GridPart>
692 exp(
const GridFunctionWrapper<Function, GridPart>& f)
695 UnaryBoundaryFunctionExpressionTraits<ExpOperation, Function, GridPart>
698 return TraitsType::wrap(f);
702 template<
class Function,
class Gr
idPart>
704 GridFunctionWrapper<UnaryFunctionExpression<LogOperation, Function>, GridPart>
705 log(
const GridFunctionWrapper<Function, GridPart>& f)
708 UnaryBoundaryFunctionExpressionTraits<LogOperation, Function, GridPart>
711 return TraitsType::wrap(f);
715 template<
class Function,
class Gr
idPart>
717 GridFunctionWrapper<UnaryFunctionExpression<SqrtOperation, Function>, GridPart>
718 sqrt(
const GridFunctionWrapper<Function, GridPart>& f)
721 UnaryBoundaryFunctionExpressionTraits<SqrtOperation, Function, GridPart>
724 return TraitsType::wrap(f);
728 template<
class Function,
class Gr
idPart>
730 GridFunctionWrapper<UnaryFunctionExpression<SquareOperation, Function>, GridPart>
731 sqr(
const GridFunctionWrapper<Function, GridPart>& f)
734 UnaryBoundaryFunctionExpressionTraits<SquareOperation, Function, GridPart>
737 return TraitsType::wrap(f);
741 template<
class Function,
class Gr
idPart>
743 GridFunctionWrapper<UnaryFunctionExpression<SinOperation, Function>, GridPart>
744 sin(
const GridFunctionWrapper<Function, GridPart>& f)
747 UnaryBoundaryFunctionExpressionTraits<SinOperation, Function, GridPart>
750 return TraitsType::wrap(f);
754 template<
class Function,
class Gr
idPart>
756 GridFunctionWrapper<UnaryFunctionExpression<CosOperation, Function>, GridPart>
757 cos(
const GridFunctionWrapper<Function, GridPart>& f)
760 UnaryBoundaryFunctionExpressionTraits<CosOperation, Function, GridPart>
763 return TraitsType::wrap(f);
767 template<
class Function,
class Gr
idPart>
769 GridFunctionWrapper<UnaryFunctionExpression<TanOperation, Function>, GridPart>
770 tan(
const GridFunctionWrapper<Function, GridPart>& f)
773 UnaryBoundaryFunctionExpressionTraits<TanOperation, Function, GridPart>
776 return TraitsType::wrap(f);
780 template<
class Function,
class Gr
idPart>
782 GridFunctionWrapper<UnaryFunctionExpression<AtanOperation, Function>, GridPart>
783 atan(
const GridFunctionWrapper<Function, GridPart>& f)
786 UnaryBoundaryFunctionExpressionTraits<AtanOperation, Function, GridPart>
789 return TraitsType::wrap(f);
793 template<
class Function,
class Gr
idPart>
795 GridFunctionWrapper<UnaryFunctionExpression<AsinOperation, Function>, GridPart>
796 asin(
const GridFunctionWrapper<Function, GridPart>& f)
799 UnaryBoundaryFunctionExpressionTraits<AsinOperation, Function, GridPart>
802 return TraitsType::wrap(f);
806 template<
class Function,
class Gr
idPart>
808 GridFunctionWrapper<UnaryFunctionExpression<AcosOperation, Function>, GridPart>
809 acos(
const GridFunctionWrapper<Function, GridPart>& f)
812 UnaryBoundaryFunctionExpressionTraits<AcosOperation, Function, GridPart>
815 return TraitsType::wrap(f);
836 template<
class Indicator,
class Function>
839 const Fem::Function<typename Function::FunctionSpaceType, Function>& f)
846 template<
class Indicator,
class Function>
848 auto operator*(
const Fem::Function<typename Function::FunctionSpaceType, Function>& f,
856 template<
class Function>
858 BoundarySupportedFunction<ZeroGridFunction<
typename Function::FunctionSpaceType,
859 typename Function::GridParType>,
860 EmptyBoundaryIndicatorType>
862 const Fem::Function<typename Function::FunctionSpaceType, Function>& f)
866 typename Function::GridParType>
872 return BoundaryFunction(ZeroFunction(f.gridPart), EmptyBoundaryIndicatorType());
876 template<
class Function,
class Indicator>
878 BoundarySupportedFunction<ZeroGridFunction<
typename Function::FunctionSpaceType,
879 typename Function::GridParType>,
880 EmptyBoundaryIndicatorType>
886 typename Function::GridParType>
892 return BoundaryFunction(ZeroFunction(f.gridPart), EmptyBoundaryIndicatorType());
896 template<
class Function,
class Indicator>
898 BoundarySupportedFunction<Function, Indicator>
914 using ACFem::operator+;
915 using ACFem::operator-;
916 using ACFem::operator*;
917 using ACFem::operator/;
A simple interface class for a boundary-indicator.
Definition: boundaryindicator.hh:41
A function with potentially partial support on the boundary.
Definition: boundarysupportedfunction.hh:234
Parameters are quasi-constant quantities, like the time-step size in one time-step when solving trans...
Definition: parameterinterface.hh:80
A base class for zero function expression.
Definition: gridfunctionexpressionbase.hh:110
A grid-function always returning 0.
Definition: constantfunction.hh:352
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
static ZeroGridFunction< typename FunctionMultiplicationResultTraits< typename F1::FunctionSpaceType, typename F2::FunctionSpaceType >::FunctionSpaceType, typename F1::GridPartType > zeroProduct(const F1 &f1, const F2 &f2)
Generate the proper zero-functions for products evaluating to zero.
Definition: gridfunctionexpression.hh:116
static UnaryGridFunctionExpression< LogOperation, Function > log(const Fem::Function< typename Function::FunctionSpaceType, Function > &f_)
Component-wise logarithm, log(f)(x) = [log(f(x)_0),...,log(f(x)_N].
Definition: gridfunctionexpression.hh:2844
static const Fem::Function< typename GridFunction::FunctionSpaceType, GridFunction > & asExprFunction(const GridFunction &arg)
Cast to the proper underlying expression class; for the generic case this is just the underlying Fem:...
Definition: gridfunctionexpression.hh:61
auto zeroFunction(const Fem::Function< typename F::FunctionSpaceType, F > &f_) -> ZeroGridFunction< typename F::FunctionSpaceType, typename F::GridPartType >
Generate a ZeroGridFunction on the same function space.
Definition: gridfunctionexpression.hh:183
FractionGridFunction< typename FunctionSpace::FunctionSpaceType::ScalarFunctionSpaceType, GridPart, 1L, 1UL > oneFunction(const FunctionSpace &space, const GridPart &gridPart)
Generate a proper constant-one function from the given Fem::FunctionSpace and Fem::GridPart.
Definition: gridfunctionexpression.hh:157
BoundarySupportedFunction< GridFunction, Indicator > boundarySupportedFunction(const Fem::Function< typename GridFunction::FunctionSpaceType, GridFunction > &f, const BoundaryIndicatorInterface< Indicator > &c=EntireBoundaryIndicatorType())
Generate a function with partial support on the boundary.
Definition: boundarysupportedfunction.hh:604
std::decay< decltype(*std::declval< Indicator >()&&*std::declval< InnerIndicatorType >())>::type IndicatorType
Resulting Boundary indicator type.
Definition: boundarysupportedfunction.hh:253
BinaryParameterExpression< MultiplyOperation, Left, Right > operator*(const ParameterInterface< Left > &left, const ParameterInterface< Right > &right)
Scalar product between parameters.
Definition: parameterexpression.hh:321