1 #ifndef __OPERATORPARTSEXPRESSION_HH__
2 #define __OPERATORPARTSEXPRESSION_HH__
4 #include "operatorparts.hh"
5 #include "operatorpartsexpressionbase.hh"
6 #include "operatorpartsoperations.hh"
7 #include "zerooperatorparts.hh"
28 template<
class BinOp,
class LeftOperand,
class RightOperand>
29 class BinaryOperatorPartsExpression;
32 template<
class UnOp,
class Operand>
36 template<
class Operand>
38 :
public OperatorPartsExpression<UnaryOperatorPartsExpression<IdentityOperation, Operand> >
40 typedef Operand OperandType;
43 typedef OperatorPartsExpression<ThisType> BaseType;
60 typedef typename InterfaceType::RangeType
RangeType ;
66 enum { dimDomain = FunctionSpaceType::dimDomain, dimRange = FunctionSpaceType::dimRange };
76 UnaryOperatorPartsExpression(
const ThisType &other)
77 : operand_( other.operand_ )
81 template<
class Entity>
84 operand_().setEntity(entity);
88 template<
class Intersection>
91 return operand_().setIntersection(intersection);
97 return OpType::name() +
"(" + operand_().name() +
")";
101 template<
class Entity,
class Po
int>
102 void flux(
const Entity& entity,
104 const RangeType &value,
105 const JacobianRangeType &jacobian,
106 JacobianRangeType &flux )
const
108 if (!OperandType::hasFlux) {
112 operand_().flux(entity, x, value, jacobian, flux);
116 template<
class Entity,
class Po
int>
118 const JacobianRangeType& DuBar,
119 const Entity& entity,
121 const RangeType &value,
122 const JacobianRangeType &jacobian,
123 JacobianRangeType &flux)
const
125 if (!OperandType::hasFlux) {
129 operand_().linearizedFlux(uBar, DuBar, entity, x, value, jacobian, flux);
133 template<
class Entity,
class Po
int>
136 const RangeType &value,
137 const JacobianRangeType &jacobian,
138 RangeType &result)
const
140 if (!OperandType::hasSources) {
144 operand_().source(entity, x, value, jacobian, result);
148 template<
class Entity,
class Po
int>
150 const JacobianRangeType& DuBar,
151 const Entity& entity,
153 const RangeType &value,
154 const JacobianRangeType &jacobian,
155 RangeType &result)
const
157 if (!OperandType::hasSources) {
161 operand_().linearizedSource(uBar, DuBar, entity, x, value, jacobian, result);
165 template<
class Intersection,
class Po
int>
168 const DomainType& unitOuterNormal,
169 const RangeType& value,
170 RangeType& result)
const
172 if (!OperandType::hasRobinFlux) {
176 operand_().robinFlux(intersection, x, unitOuterNormal, value, result);
180 template<
class Intersection,
class Po
int>
182 const Intersection& intersection,
184 const DomainType& unitOuterNormal,
185 const RangeType& value,
186 RangeType& result)
const
188 if (!OperandType::hasRobinFlux) {
192 operand_().linearizedRobinFlux(uBar, intersection, x, unitOuterNormal, value, result);
196 template<
class Entity,
class Po
int>
199 const RangeType &value,
200 const JacobianRangeType &jacobian,
201 const HessianRangeType &hessian,
202 RangeType &result)
const
204 if (!OperandType::hasFlux) {
208 operand_().fluxDivergence(entity, x, value, jacobian, hessian, result);
211 const ContainedExpressionType& containedExpression()
const
217 ExpressionStorage<OperandType> operand_;
221 template<
class Operand>
222 struct OperatorPartsTraits<UnaryOperatorPartsExpression<IdentityOperation, Operand> >
223 :
public DefaultOperatorPartsTraits<typename Operand::FunctionSpaceType>
226 typedef Operand OperandType;
228 enum StructureFlags {
229 isLinear = OperandType::isLinear,
230 isSymmetric = OperandType::isSymmetric,
231 isSemiDefinite = OperandType::isSemiDefinite
234 enum ConstituentFlags {
235 hasFlux = OperandType::hasFlux,
236 hasSources = OperandType::hasSources,
237 hasRobinFlux = OperandType::hasRobinFlux
242 template<
class Operand>
244 :
public OperatorPartsExpression<UnaryOperatorPartsExpression<MinusOperation, Operand> >
246 typedef Operand OperandType;
249 typedef OperatorPartsExpression<ThisType> BaseType;
272 enum { dimDomain = FunctionSpaceType::dimDomain, dimRange = FunctionSpaceType::dimRange };
282 UnaryOperatorPartsExpression(
const ThisType &other)
283 : operand_( other.operand_ )
288 template<
class Entity>
291 operand_().setEntity(entity);
295 template<
class Intersection>
298 return operand_().setIntersection(intersection);
304 return OpType::name() +
"(" + operand_().name() +
")";
308 template<
class Entity,
class Po
int>
309 void flux(
const Entity& entity,
311 const RangeType &value,
312 const JacobianRangeType &jacobian,
313 JacobianRangeType &flux)
const
315 if (!OperandType::hasFlux) {
319 operand_().flux(entity, x, value, jacobian, flux);
324 template<
class Entity,
class Po
int>
326 const JacobianRangeType& DuBar,
327 const Entity& entity,
329 const RangeType &value,
330 const JacobianRangeType &jacobian,
331 JacobianRangeType &flux )
const
333 if (!OperandType::hasFlux) {
337 operand_().linearizedFlux(uBar, DuBar, entity, x, value, jacobian, flux);
342 template<
class Entity,
class Po
int>
345 const RangeType &value,
346 const JacobianRangeType &jacobian,
347 RangeType &result)
const
349 if (!OperandType::hasSources) {
353 operand_().source(entity, x, value, jacobian, result);
358 template<
class Entity,
class Po
int>
360 const JacobianRangeType& DuBar,
361 const Entity& entity,
363 const RangeType &value,
364 const JacobianRangeType &jacobian,
365 RangeType &result)
const
367 if (!OperandType::hasSources) {
371 operand_().linearizedSource(uBar, DuBar, entity, x, value, jacobian, result);
376 template<
class Intersection,
class Po
int>
379 const DomainType& unitOuterNormal,
380 const RangeType& value,
381 RangeType& result)
const
383 if (!OperandType::hasRobinFlux) {
387 operand_().robinFlux(intersection, x, unitOuterNormal, value, result);
392 template<
class Intersection,
class Po
int>
394 const Intersection& intersection,
396 const DomainType& unitOuterNormal,
397 const RangeType& value,
398 RangeType& result)
const
400 if (!OperandType::hasRobinFlux) {
404 operand_().linearizedRobinFlux(uBar, intersection, x, unitOuterNormal, value, result);
409 template<
class Entity,
class Po
int>
412 const RangeType &value,
413 const JacobianRangeType &jacobian,
414 const HessianRangeType &hessian,
415 RangeType &result)
const
417 if (!OperandType::hasFlux) {
421 operand_().fluxDivergence(entity, x, value, jacobian, hessian, result);
425 const ContainedExpressionType& containedExpression()
const
431 ExpressionStorage<OperandType> operand_;
435 template<
class Operand>
436 struct OperatorPartsTraits<UnaryOperatorPartsExpression<MinusOperation, Operand> >
437 :
public DefaultOperatorPartsTraits<typename Operand::FunctionSpaceType>
440 typedef Operand OperandType;
442 enum StructureFlags {
443 isLinear = OperandType::isLinear,
444 isSymmetric = OperandType::isSymmetric,
445 isSemiDefinite = OperandType::isSemiDefinite
448 enum ConstituentFlags {
449 hasFlux = OperandType::hasFlux,
450 hasSources = OperandType::hasSources,
451 hasRobinFlux = OperandType::hasRobinFlux
454 typedef typename OperandType::FunctionSpaceType FunctionSpaceType;
463 template<
class BinOp,
class LeftOperand,
class RightOperand>
465 :
public OperatorPartsExpression<BinaryOperatorPartsExpression<BinOp, LeftOperand, RightOperand> >
467 typedef BinOp BinOpType;
469 typedef OperatorPartsExpression<ThisType> BaseType;
471 typedef BinaryOperatorPartsExpressionOperation<BinOpType> OperationType;
490 enum { dimDomain = FunctionSpaceType::dimDomain, dimRange = FunctionSpaceType::dimRange };
496 const RightOperand &g)
497 : leftOperand_( f ), rightOperand_( g )
501 BinaryOperatorPartsExpression(
const ThisType &other )
502 : leftOperand_( other.leftOperand_ ),
503 rightOperand_( other.rightOperand_ )
507 template<
class Entity>
510 leftOperand_().setEntity(entity);
511 rightOperand_().setEntity(entity);
515 template<
class Intersection>
522 bool leftRobin = leftOperand_().setIntersection(intersection);
523 bool rightRobin = rightOperand_().setIntersection(intersection);
525 return leftRobin || rightRobin;
531 return "(" + leftOperand_().name() +
" " + BinOpType::name() +
" " + rightOperand_().name() +
")";
535 template<
class Entity,
class Po
int>
536 void flux(
const Entity& entity,
538 const RangeType &value,
539 const JacobianRangeType &jacobian,
540 JacobianRangeType &
flux )
const
542 OperationType::flux(leftOperand_(), rightOperand_(), entity, x, value, jacobian,
flux);
546 template<
class Entity,
class Po
int>
548 const JacobianRangeType& DuBar,
549 const Entity& entity,
551 const RangeType &value,
552 const JacobianRangeType &jacobian,
553 JacobianRangeType &
flux )
const
555 OperationType::linearizedFlux(leftOperand_(), rightOperand_(), uBar, DuBar, entity, x, value, jacobian,
flux);
559 template<
class Entity,
class Po
int>
562 const RangeType &value,
563 const JacobianRangeType &jacobian,
564 RangeType &result)
const
566 OperationType::source(leftOperand_(), rightOperand_(), entity, x, value, jacobian, result);
570 template<
class Entity,
class Po
int>
572 const JacobianRangeType& DuBar,
573 const Entity& entity,
575 const RangeType &value,
576 const JacobianRangeType &jacobian,
577 RangeType &result)
const
579 OperationType::linearizedSource(leftOperand_(), rightOperand_(), uBar, DuBar, entity, x, value, jacobian, result);
583 template<
class Intersection,
class Po
int>
586 const DomainType& unitOuterNormal,
587 const RangeType& value,
588 RangeType& result)
const
590 OperationType::robinFlux(leftOperand_(), rightOperand_(), intersection, x, unitOuterNormal, value, result);
594 template<
class Intersection,
class Po
int>
596 const Intersection& intersection,
598 const DomainType& unitOuterNormal,
599 const RangeType& value,
600 RangeType& result)
const
602 OperationType::linearizedRobinFlux(leftOperand_(), rightOperand_(), uBar, intersection, x, unitOuterNormal, value, result);
606 template<
class Entity,
class Po
int>
609 const RangeType &value,
610 const JacobianRangeType &jacobian,
611 const HessianRangeType &hessian,
612 RangeType &result)
const
614 OperationType::fluxDivergence(leftOperand_(), rightOperand_(), entity, x, value, jacobian, hessian, result);
625 template<
class BinOp,
class LeftOperand,
class RightOperand>
630 typedef LeftOperand LeftOperandType;
631 typedef RightOperand RightOperandType;
632 typedef typename LeftOperand::FunctionSpaceType LeftFunctionSpaceType;
633 typedef typename RightOperandType::FunctionSpaceType RightFunctionSpaceType;
637 static_assert((std::is_same<LeftFunctionSpaceType, RightFunctionSpaceType>::value),
638 "Function spaces must agree, cannot combine them");
640 enum StructureFlags {
641 isLinear = LeftOperandType::isLinear && RightOperandType::isLinear,
642 isSymmetric = LeftOperandType::isSymmetric && RightOperandType::isSymmetric,
643 isSemiDefinite = LeftOperandType::isSemiDefinite && RightOperandType::isSemiDefinite
646 enum ConstituentFlags {
647 hasFlux = LeftOperandType::hasFlux || RightOperandType::hasFlux,
648 hasSources = LeftOperandType::hasSources || RightOperandType::hasSources,
649 hasRobinFlux = LeftOperandType::hasRobinFlux || RightOperandType::hasRobinFlux,
652 typedef LeftFunctionSpaceType FunctionSpaceType;
660 template<
class LeftOperand,
class RightOperand>
665 const LeftOperand& f(
static_cast<const LeftOperand&
>(f_));
666 const RightOperand& g(
static_cast<const RightOperand&
>(g_));
670 return ExpressionType(f, g);
679 template<
class LeftOperand,
class RightOperand>
680 BinaryOperatorPartsExpression<MinusOperation, LeftOperand, RightOperand>
684 const LeftOperand& f(
static_cast<const LeftOperand&
>(f_));
685 const RightOperand& g(
static_cast<const RightOperand&
>(g_));
689 return ExpressionType(f, g);
707 template<
class Factor,
class OperandType>
709 :
public OperatorPartsExpression<BinaryOperatorPartsExpression<SMultiplyOperation, Factor, OperandType> >
713 typedef OperatorPartsExpression<ThisType> BaseType;
717 typedef Factor FactorType;
735 enum { dimDomain = FunctionSpaceType::dimDomain, dimRange = FunctionSpaceType::dimRange };
741 : scalar_(s), operand_(f)
745 BinaryOperatorPartsExpression(
const ThisType &other)
746 : scalar_( other.scalar_ ), operand_( other.operand_ )
750 template<
class Entity>
753 operand_().setEntity(entity);
757 template<
class Intersection>
760 return operand_().setIntersection(intersection);
766 return "(" + std::to_string(
parameterValue(scalar_())) +
" " + BinOpType::name() +
" " + operand_().name() +
")";
770 template<
class Entity,
class Po
int>
771 void flux(
const Entity& entity,
773 const RangeType &value,
774 const JacobianRangeType &jacobian,
775 JacobianRangeType &
flux)
const
777 if (!OperandType::hasFlux) {
781 operand_().flux(entity, x, value, jacobian,
flux);
786 template<
class Entity,
class Po
int>
788 const JacobianRangeType& DuBar,
789 const Entity& entity,
791 const RangeType &value,
792 const JacobianRangeType &jacobian,
793 JacobianRangeType &
flux)
const
795 if (!OperandType::hasFlux) {
799 operand_().linearizedFlux(uBar, DuBar, entity, x, value, jacobian,
flux);
804 template<
class Entity,
class Po
int>
807 const RangeType &value,
808 const JacobianRangeType &jacobian,
809 RangeType &result)
const
811 if (!OperandType::hasSources) {
815 operand_().source(entity, x, value, jacobian, result);
820 template<
class Entity,
class Po
int>
822 const JacobianRangeType& DuBar,
823 const Entity& entity,
825 const RangeType &value,
826 const JacobianRangeType &jacobian,
827 RangeType &result)
const
829 if (!OperandType::hasSources) {
833 operand_().linearizedSource(uBar, DuBar, entity, x, value, jacobian, result);
838 template<
class Intersection,
class Po
int>
841 const DomainType& unitOuterNormal,
842 const RangeType& value,
843 RangeType& result)
const
845 if (!OperandType::hasRobinFlux) {
849 operand_().robinFlux(intersection, x, unitOuterNormal, value, result);
854 template<
class Intersection,
class Po
int>
856 const Intersection& intersection,
858 const DomainType& unitOuterNormal,
859 const RangeType& value,
860 RangeType& result)
const
862 if (!OperandType::hasRobinFlux) {
866 operand_().linearizedRobinFlux(uBar, intersection, x, unitOuterNormal, value, result);
871 template<
class Entity,
class Po
int>
874 const RangeType &value,
875 const JacobianRangeType &jacobian,
876 const HessianRangeType &hessian,
877 RangeType &result)
const
879 if (!OperandType::hasFlux) {
883 operand_().fluxDivergence(entity, x, value, jacobian, hessian, result);
888 const FactorType& scalar()
const {
return scalar_(); }
889 const OperandType& operand()
const {
return operand_(); }
891 ExpressionStorage<FactorType> scalar_;
892 ExpressionStorage<OperandType> operand_;
896 template<
class Factor,
class Operand>
897 struct OperatorPartsTraits<BinaryOperatorPartsExpression<SMultiplyOperation, Factor, Operand> >
898 :
public DefaultOperatorPartsTraits<typename Operand::FunctionSpaceType>
901 typedef Operand OperandType;
902 typedef Factor FactorType;
903 typedef typename OperandType::FunctionSpaceType::ScalarFunctionSpaceType ScalarFunctionSpaceType;
905 enum StructureFlags {
906 isLinear = OperandType::isLinear,
907 isSymmetric = OperandType::isSymmetric,
908 isSemiDefinite = OperandType::isSemiDefinite
911 enum ConstituentFlags {
912 hasFlux = OperandType::hasFlux,
913 hasSources = OperandType::hasSources
916 typedef SMultiplyOperation BinOpType;
917 typedef typename OperandType::FunctionSpaceType FunctionSpaceType;
922 template<
class OperandType>
923 BinaryOperatorPartsExpression<SMultiplyOperation, typename OperandType::RangeFieldType, OperandType>
924 operator*(
const typename OperandType::RangeFieldType& s_,
927 typedef typename OperandType::RangeFieldType RangeFieldType;
928 const OperandType& f(
static_cast<const OperandType&
>(f_));
932 return ExpressionType(s_, f);
936 template<
class OperandType>
938 const typename OperandType::RangeFieldType& s_)
939 -> decltype(s_ *
asImp(op_))
941 return s_ *
asImp(op_);
945 template<
class Parameter,
class OperandType>
946 BinaryOperatorPartsExpression<SMultiplyOperation, Parameter, OperandType>
950 typedef Parameter ParameterType;
952 const ParameterType& s(
static_cast<const ParameterType&
>(s_));
953 const OperandType& f(
static_cast<const OperandType&
>(f_));
957 return ExpressionType(s, f);
961 template<
class Parameter,
class OperandType>
972 template<
class OperandType>
973 BinaryOperatorPartsExpression<SMultiplyOperation, typename OperandType::RangeFieldType, OperandType>
974 operator*(
const OperatorPartsInterface<OperandType>& f_)
976 typedef typename OperandType::RangeFieldType RangeFieldType;
977 const OperandType& f(
static_cast<const OperandType&
>(f_));
979 typedef BinaryOperatorPartsExpression<SMultiplyOperation, RangeFieldType, OperandType> ExpressionType;
981 return ExpressionType(-1.0, f);
1003 template<
class FactorFunction,
class OperandType>
1005 :
public OperatorPartsExpression<BinaryOperatorPartsExpression<MultiplyOperation, FactorFunction, OperandType> >
1009 typedef OperatorPartsExpression<ThisType> BaseType;
1012 typedef FactorFunction FactorFunctionType;
1013 typedef typename FactorFunctionType::LocalFunctionType FactorLocalFunctionType;
1014 typedef typename FactorFunctionType::RangeType FactorRangeType;
1015 typedef typename FactorFunctionType::JacobianRangeType FactorJacobianRangeType;
1034 enum { dimDomain = FunctionSpaceType::dimDomain, dimRange = FunctionSpaceType::dimRange };
1035 enum {
isLinear = TraitsType::isLinear,
1043 BinaryOperatorPartsExpression(
const FactorFunctionType& f,
const OperandType& op)
1044 : factor_(f), operand_(op), localFactor_(factor_())
1048 BinaryOperatorPartsExpression(
const ThisType &other)
1049 : factor_(other.factor_), operand_(other.operand_), localFactor_(factor_())
1053 template<
class Entity>
1056 operand_().setEntity(entity);
1057 localFactor_.init(entity);
1061 template<
class Intersection>
1071 return operand_().setIntersection(intersection);
1077 return "(" + factor_().name() +
" " + BinOpType::name() +
" " + operand_().name() +
")";
1081 template<
class Entity,
class Po
int>
1084 const RangeType &value,
1085 const JacobianRangeType &jacobian,
1086 JacobianRangeType &result)
const
1088 assert(&entity == &localFactor_.entity());
1090 if (!OperandType::hasFlux) {
1094 operand_().flux(entity, x, value, jacobian, result);
1096 FactorRangeType factorValue;
1097 localFactor_.evaluate(x, factorValue);
1099 result *= factorValue;
1103 template<
class Entity,
class Po
int>
1105 const JacobianRangeType& DuBar,
1106 const Entity& entity,
1108 const RangeType &value,
1109 const JacobianRangeType &jacobian,
1110 JacobianRangeType &result)
const
1112 assert(&entity == &localFactor_.entity());
1114 if (!OperandType::hasFlux) {
1119 operand_().linearizedFlux(uBar, DuBar, entity, x, value, jacobian, result);
1121 FactorRangeType factorValue;
1122 localFactor_.evaluate(x, factorValue);
1124 result *= factorValue;
1128 template<
class Entity,
class Po
int>
1131 const RangeType &value,
1132 const JacobianRangeType &jacobian,
1133 RangeType &result)
const
1135 assert(&entity == &localFactor_.entity());
1137 if (!OperandType::hasSources) {
1142 operand_().source(entity, x, value, jacobian, result);
1144 FactorRangeType factorValue;
1145 localFactor_.evaluate(x, factorValue);
1147 result *= factorValue;
1151 template<
class Entity,
class Po
int>
1153 const JacobianRangeType& DuBar,
1154 const Entity& entity,
1156 const RangeType &value,
1157 const JacobianRangeType &jacobian,
1158 RangeType &result)
const
1160 assert(&entity == &localFactor_.entity());
1162 if (!OperandType::hasSources) {
1167 operand_().linearizedSource(uBar, DuBar, entity, x, value, jacobian, result);
1169 FactorRangeType factorValue;
1170 localFactor_.evaluate(x, factorValue);
1172 result *= factorValue;
1176 template<
class Intersection,
class Po
int>
1179 const DomainType& unitOuterNormal,
1180 const RangeType& value,
1181 RangeType& result)
const
1183 if (!OperandType::hasRobinFlux) {
1188 operand_().robinFlux(intersection, x, unitOuterNormal, value, result);
1190 FactorRangeType factorValue;
1191 localFactor_.evaluate(x, factorValue);
1193 result *= factorValue;
1197 template<
class Intersection,
class Po
int>
1199 const Intersection& intersection,
1201 const DomainType& unitOuterNormal,
1202 const RangeType& value,
1203 RangeType& result)
const
1205 if (!OperandType::hasRobinFlux) {
1210 operand_().linearizedRobinFlux(uBar, intersection, x, unitOuterNormal, value, result);
1212 FactorRangeType factorValue;
1213 localFactor_.evaluate(x, factorValue);
1215 result *= factorValue;
1219 template<
class Entity,
class Po
int>
1222 const RangeType &value,
1223 const JacobianRangeType &jacobian,
1224 const HessianRangeType &hessian,
1225 RangeType &result)
const
1227 if (!OperandType::hasFlux) {
1234 operand_().fluxDivergence(entity, x, value, jacobian, hessian, result);
1236 FactorRangeType factorValue;
1237 localFactor_.evaluate(x, factorValue);
1239 JacobianRangeType fluxValue;
1240 FactorJacobianRangeType factorJacobian;
1242 operand_().flux(entity, x, value, jacobian, fluxValue);
1243 localFactor_.jacobian(x, factorJacobian);
1245 for (
int i = 0; i < dimRange; ++i) {
1246 result += factorJacobian[i] * fluxValue[i];
1253 mutable FactorLocalFunctionType localFactor_;
1257 template<
class FactorFunction,
class Operand>
1258 struct OperatorPartsTraits<BinaryOperatorPartsExpression<MultiplyOperation, FactorFunction, Operand> >
1259 :
public DefaultOperatorPartsTraits<typename Operand::FunctionSpaceType>
1262 typedef MultiplyOperation BinOpType;
1263 typedef FactorFunction FactorFunctionType;
1264 typedef Operand FactorOperandType;
1270 isLinear = FactorOperandType::isLinear,
1271 isSymmetric = FactorOperandType::isSymmetric,
1272 isSemiDefinite = FactorOperandType::isSemiDefinite
1275 enum ConstituentFlags {
1276 hasFlux = FactorOperandType::hasFlux,
1277 hasSources = FactorOperandType::hasSources,
1278 hasRobinFlux = FactorOperandType::hasRobinFlux
1281 typedef typename FactorOperandType::FunctionSpaceType FunctionSpaceType;
1286 template<
class FactorFunction,
class OperandType>
1287 BinaryOperatorPartsExpression<MultiplyOperation, FactorFunction, OperandType>
1288 operator*(
const Fem::Function<typename FactorFunction::FunctionSpaceType::ScalarFunctionSpaceType, FactorFunction>& f_,
1291 const FactorFunction& f(
static_cast<const FactorFunction&
>(f_));
1292 const OperandType& op(
static_cast<const OperandType&
>(op_));
1296 return ExpressionType(f, op);
1300 template<
class FactorFunction,
class OperandType>
1301 BinaryOperatorPartsExpression<MultiplyOperation, FactorFunction, OperandType>
1303 const Fem::Function<typename FactorFunction::FunctionSpaceType::ScalarFunctionSpaceType, FactorFunction>& f_)
1305 const FactorFunction& f(
static_cast<const FactorFunction&
>(f_));
1306 const OperandType& op(
static_cast<const OperandType&
>(op_));
1312 template<
class Operand>
1313 class UnaryOperatorPartsExpression<MinusOperation, Operand>
1314 operator-(const OperatorPartsInterface<Operand>& op_)
1316 const Operand& op(
static_cast<const Operand&
>(op_));
1318 typedef UnaryOperatorPartsExpression<MinusOperation, Operand> ExpressionType;
1320 return ExpressionType(op);
1328 template<
class Operand>
1329 class UnaryOperatorPartsExpression<IdentityOperation, Operand>
1330 operator*(
const OperatorPartsInterface<Operand>& op_)
1332 const Operand& op(
static_cast<const Operand&
>(op_));
1334 typedef UnaryOperatorPartsExpression<IdentityOperation, Operand> ExpressionType;
1336 return ExpressionType(op);
1340 template<
class Operand>
1356 template<
class Expression>
1360 return op_.expression();
1364 template<
class Operand>
1368 -> decltype((s_ * op_.scalar()) * op_.operand())
1370 return (s_ * op_.scalar()) * op_.operand();
1375 template<
class Parameter,
class Field,
class Operand>
1377 auto operator*(
const ParameterInterface<Parameter>& p_,
1378 const BinaryOperatorPartsExpression<SMultiplyOperation, Field, Operand>& op_)
1379 -> decltype(op_.scalar() * (
asImp(p_) * op_.operand()))
1381 return op_.scalar() * (
asImp(p_) * op_.operand());
1385 template<
class Parameter,
class Operand>
1396 template<
class Field,
class Parameter,
class Operand>
1398 auto operator*(
const BinaryParameterExpression<SMultiplyOperation, Field, Parameter>& p_,
1400 -> decltype(p_.left() * (p_.right() *
asImp(op_)))
1402 return p_.left() * (p_.right() *
asImp(op_));
1406 template<
class Function,
class Field,
class Operand>
1408 auto operator*(
const Fem::Function<typename Function::FunctionSpaceType, Function>& f_,
1410 -> decltype(op_.scalar() * (
asImp(f_) * op_.operand()))
1412 return op_.scalar() * (
asImp(f_) * op_.operand());
1416 template<
class Field,
class Function,
class Operand>
1420 -> decltype(f_.scalar() * (f_.function() *
asImp(op_)))
1422 return f_.scalar() * (f_.function() *
asImp(op_));
1432 template<
class Operand>
1435 -> decltype(*op_.containedExpression())
1437 return *op_.containedExpression();
1441 template<
class Operand>
1445 -> decltype(*
asImp(op))
1451 template<
class Operand>
1455 -> decltype(*
asImp(op))
1461 template<
class FunctionSpace>
1471 template<
class Operand>
1475 -> decltype(*
asImp(op))
1481 template<
class Operand>
1491 template<
class FunctionSpace>
1501 template<
class FunctionSpace>
1511 template<
class FunctionSpace>
1514 const typename FunctionSpace::RangeFieldType& s)
1521 template<
class Parameter,
class FunctionSpace>
1531 template<
class Parameter,
class FunctionSpace>
1541 template<
class Function,
class ScalarSpace,
class FunctionSpace>
1547 static_assert(std::is_same<ScalarSpace, typename FunctionSpace::ScalarFunctionSpaceType>::value,
1548 "Incompatible function spaces.");
1553 template<
class Function,
class ScalarSpace,
class FunctionSpace>
1556 const Fem::Function<ScalarSpace, Function>& f)
1559 static_assert(std::is_same<ScalarSpace, typename FunctionSpace::ScalarFunctionSpaceType>::value,
1560 "Incompatible function spaces.");
BinaryGridFunctionExpression implements point-wise vector-space operations for GridFunction-types.
Definition: gridfunctionexpression.hh:423
Multiplication with grid-functions.
Definition: operatorpartsexpression.hh:1006
InterfaceType::DomainType DomainType
domain type (from function space)
Definition: operatorpartsexpression.hh:1026
void linearizedRobinFlux(const RangeType &uBar, const Intersection &intersection, const Point &x, const DomainType &unitOuterNormal, const RangeType &value, RangeType &result) const
Definition: operatorpartsexpression.hh:1198
InterfaceType::JacobianRangeType JacobianRangeType
jacobian type (from function space)
Definition: operatorpartsexpression.hh:1030
void fluxDivergence(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, const HessianRangeType &hessian, RangeType &result) const
fluxDivergence for estimator
Definition: operatorpartsexpression.hh:1220
void linearizedSource(const RangeType &uBar, const JacobianRangeType &DuBar, const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, RangeType &result) const
linearized source term
Definition: operatorpartsexpression.hh:1152
InterfaceType::DomainFieldType DomainFieldType
domain type (from function space)
Definition: operatorpartsexpression.hh:1022
void linearizedFlux(const RangeType &uBar, const JacobianRangeType &DuBar, const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, JacobianRangeType &result) const
linearizedflux
Definition: operatorpartsexpression.hh:1104
void setEntity(const Entity &entity) const
Definition: operatorpartsexpression.hh:1054
bool setIntersection(const Intersection &intersection) const
Definition: operatorpartsexpression.hh:1062
void flux(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, JacobianRangeType &result) const
flux on local coordinate local
Definition: operatorpartsexpression.hh:1082
InterfaceType::RangeFieldType RangeFieldType
range type (from function space)
Definition: operatorpartsexpression.hh:1024
InterfaceType::HessianRangeType HessianRangeType
hessian type (from function space)
Definition: operatorpartsexpression.hh:1032
std::string name() const
Definition: operatorpartsexpression.hh:1075
void source(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, RangeType &result) const
source term
Definition: operatorpartsexpression.hh:1129
void robinFlux(const Intersection &intersection, const Point &x, const DomainType &unitOuterNormal, const RangeType &value, RangeType &result) const
Definition: operatorpartsexpression.hh:1177
InterfaceType::RangeType RangeType
range type (from function space)
Definition: operatorpartsexpression.hh:1028
InterfaceType::FunctionSpaceType FunctionSpaceType
type of discrete function space
Definition: operatorpartsexpression.hh:1019
void fluxDivergence(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, const HessianRangeType &hessian, RangeType &result) const
fluxDivergence for estimator
Definition: operatorpartsexpression.hh:872
void source(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, RangeType &result) const
source term
Definition: operatorpartsexpression.hh:805
InterfaceType::HessianRangeType HessianRangeType
hessian type (from function space)
Definition: operatorpartsexpression.hh:733
void linearizedFlux(const RangeType &uBar, const JacobianRangeType &DuBar, const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, JacobianRangeType &flux) const
linearizedflux
Definition: operatorpartsexpression.hh:787
void linearizedSource(const RangeType &uBar, const JacobianRangeType &DuBar, const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, RangeType &result) const
linearized source term
Definition: operatorpartsexpression.hh:821
InterfaceType::DomainType DomainType
domain type (from function space)
Definition: operatorpartsexpression.hh:727
InterfaceType::DomainFieldType DomainFieldType
domain type (from function space)
Definition: operatorpartsexpression.hh:723
void setEntity(const Entity &entity) const
Definition: operatorpartsexpression.hh:751
void linearizedRobinFlux(const RangeType &uBar, const Intersection &intersection, const Point &x, const DomainType &unitOuterNormal, const RangeType &value, RangeType &result) const
Definition: operatorpartsexpression.hh:855
void robinFlux(const Intersection &intersection, const Point &x, const DomainType &unitOuterNormal, const RangeType &value, RangeType &result) const
Definition: operatorpartsexpression.hh:839
void flux(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, JacobianRangeType &flux) const
flux on local coordinate local
Definition: operatorpartsexpression.hh:771
InterfaceType::JacobianRangeType JacobianRangeType
jacobian type (from function space)
Definition: operatorpartsexpression.hh:731
bool setIntersection(const Intersection &intersection) const
Definition: operatorpartsexpression.hh:758
InterfaceType::RangeType RangeType
range type (from function space)
Definition: operatorpartsexpression.hh:729
InterfaceType::FunctionSpaceType FunctionSpaceType
type of discrete function space
Definition: operatorpartsexpression.hh:720
InterfaceType::RangeFieldType RangeFieldType
range type (from function space)
Definition: operatorpartsexpression.hh:725
std::string name() const
Definition: operatorpartsexpression.hh:764
Template for binary operations.
Definition: operatorpartsexpression.hh:466
void setEntity(const Entity &entity) const
Definition: operatorpartsexpression.hh:508
void linearizedSource(const RangeType &uBar, const JacobianRangeType &DuBar, const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, RangeType &result) const
linearized source term
Definition: operatorpartsexpression.hh:571
void robinFlux(const Intersection &intersection, const Point &x, const DomainType &unitOuterNormal, const RangeType &value, RangeType &result) const
Definition: operatorpartsexpression.hh:584
void flux(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, JacobianRangeType &flux) const
flux on local coordinate local
Definition: operatorpartsexpression.hh:536
InterfaceType::RangeFieldType RangeFieldType
range type (from function space)
Definition: operatorpartsexpression.hh:480
InterfaceType::JacobianRangeType JacobianRangeType
jacobian type (from function space)
Definition: operatorpartsexpression.hh:486
void linearizedRobinFlux(const RangeType &uBar, const Intersection &intersection, const Point &x, const DomainType &unitOuterNormal, const RangeType &value, RangeType &result) const
Definition: operatorpartsexpression.hh:595
InterfaceType::DomainFieldType DomainFieldType
domain type (from function space)
Definition: operatorpartsexpression.hh:478
InterfaceType::DomainType DomainType
domain type (from function space)
Definition: operatorpartsexpression.hh:482
void source(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, RangeType &result) const
source term
Definition: operatorpartsexpression.hh:560
void linearizedFlux(const RangeType &uBar, const JacobianRangeType &DuBar, const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, JacobianRangeType &flux) const
linearizedflux
Definition: operatorpartsexpression.hh:547
InterfaceType::HessianRangeType HessianRangeType
hessian type (from function space)
Definition: operatorpartsexpression.hh:488
bool setIntersection(const Intersection &intersection) const
Definition: operatorpartsexpression.hh:516
void fluxDivergence(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, const HessianRangeType &hessian, RangeType &result) const
fluxDivergence for estimator
Definition: operatorpartsexpression.hh:607
std::string name() const
Definition: operatorpartsexpression.hh:529
InterfaceType::FunctionSpaceType FunctionSpaceType
type of discrete function space
Definition: operatorpartsexpression.hh:475
InterfaceType::RangeType RangeType
range type (from function space)
Definition: operatorpartsexpression.hh:484
@ isSemiDefinite
Definition: operatorparts.hh:416
@ isLinear
Definition: operatorparts.hh:414
@ isSymmetric
Definition: operatorparts.hh:415
Interface class for second order elliptic models.
Definition: operatorparts.hh:92
Parameters are quasi-constant quantities, like the time-step size in one time-step when solving trans...
Definition: parameterinterface.hh:80
OperandType ContainedExpressionType
type of the contained expression
Definition: operatorpartsexpression.hh:48
InterfaceType::RangeType RangeType
range type (from function space)
Definition: operatorpartsexpression.hh:60
InterfaceType::HessianRangeType HessianRangeType
hessian type (from function space)
Definition: operatorpartsexpression.hh:64
std::string name() const
Definition: operatorpartsexpression.hh:95
void setEntity(const Entity &entity) const
Definition: operatorpartsexpression.hh:82
InterfaceType::JacobianRangeType JacobianRangeType
jacobian type (from function space)
Definition: operatorpartsexpression.hh:62
InterfaceType::FunctionSpaceType FunctionSpaceType
type of discrete function space
Definition: operatorpartsexpression.hh:51
void linearizedSource(const RangeType &uBar, const JacobianRangeType &DuBar, const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, RangeType &result) const
linearized source term
Definition: operatorpartsexpression.hh:149
bool setIntersection(const Intersection &intersection) const
Definition: operatorpartsexpression.hh:89
void robinFlux(const Intersection &intersection, const Point &x, const DomainType &unitOuterNormal, const RangeType &value, RangeType &result) const
Definition: operatorpartsexpression.hh:166
void flux(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, JacobianRangeType &flux) const
flux on local coordinate local
Definition: operatorpartsexpression.hh:102
void source(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, RangeType &result) const
source term
Definition: operatorpartsexpression.hh:134
void fluxDivergence(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, const HessianRangeType &hessian, RangeType &result) const
fluxDivergence for estimator
Definition: operatorpartsexpression.hh:197
InterfaceType::RangeFieldType RangeFieldType
range type (from function space)
Definition: operatorpartsexpression.hh:56
void linearizedRobinFlux(const RangeType &uBar, const Intersection &intersection, const Point &x, const DomainType &unitOuterNormal, const RangeType &value, RangeType &result) const
Definition: operatorpartsexpression.hh:181
InterfaceType::DomainType DomainType
domain type (from function space)
Definition: operatorpartsexpression.hh:58
void linearizedFlux(const RangeType &uBar, const JacobianRangeType &DuBar, const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, JacobianRangeType &flux) const
linearizedflux
Definition: operatorpartsexpression.hh:117
InterfaceType::DomainFieldType DomainFieldType
domain type (from function space)
Definition: operatorpartsexpression.hh:54
Unary minus.
Definition: operatorpartsexpression.hh:245
void flux(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, JacobianRangeType &flux) const
flux on local coordinate local
Definition: operatorpartsexpression.hh:309
OperandType ContainedExpressionType
type of the contained expression
Definition: operatorpartsexpression.hh:254
bool setIntersection(const Intersection &intersection) const
Definition: operatorpartsexpression.hh:296
InterfaceType::FunctionSpaceType FunctionSpaceType
type of discrete function space
Definition: operatorpartsexpression.hh:257
void fluxDivergence(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, const HessianRangeType &hessian, RangeType &result) const
fluxDivergence for estimator
Definition: operatorpartsexpression.hh:410
InterfaceType::RangeFieldType RangeFieldType
range type (from function space)
Definition: operatorpartsexpression.hh:262
std::string name() const
Definition: operatorpartsexpression.hh:302
InterfaceType::DomainFieldType DomainFieldType
domain type (from function space)
Definition: operatorpartsexpression.hh:260
void linearizedFlux(const RangeType &uBar, const JacobianRangeType &DuBar, const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, JacobianRangeType &flux) const
linearizedflux
Definition: operatorpartsexpression.hh:325
void linearizedRobinFlux(const RangeType &uBar, const Intersection &intersection, const Point &x, const DomainType &unitOuterNormal, const RangeType &value, RangeType &result) const
Definition: operatorpartsexpression.hh:393
InterfaceType::RangeType RangeType
range type (from function space)
Definition: operatorpartsexpression.hh:266
InterfaceType::HessianRangeType HessianRangeType
hessian type (from function space)
Definition: operatorpartsexpression.hh:270
void source(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, RangeType &result) const
source term
Definition: operatorpartsexpression.hh:343
void linearizedSource(const RangeType &uBar, const JacobianRangeType &DuBar, const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, RangeType &result) const
linearized source term
Definition: operatorpartsexpression.hh:359
InterfaceType::DomainType DomainType
domain type (from function space)
Definition: operatorpartsexpression.hh:264
void setEntity(const Entity &entity) const
Definition: operatorpartsexpression.hh:289
void robinFlux(const Intersection &intersection, const Point &x, const DomainType &unitOuterNormal, const RangeType &value, RangeType &result) const
Definition: operatorpartsexpression.hh:377
InterfaceType::JacobianRangeType JacobianRangeType
jacobian type (from function space)
Definition: operatorpartsexpression.hh:268
Template for unary operations.
Definition: operatorpartsexpression.hh:33
Define a simple zero model to optimize expression templates.
Definition: zerooperatorparts.hh:31
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
auto operator+(const ZeroOperatorParts< FunctionSpace > &z1, const ZeroOperatorParts< FunctionSpace > &z2) -> decltype(*z1)
Zero + Zero = Zero.
Definition: operatorpartsexpression.hh:1463
auto operator-(const ZeroOperatorParts< FunctionSpace > &z1, const ZeroOperatorParts< FunctionSpace > &z2) -> decltype(*z1)
Zero - Zero = Zero.
Definition: operatorpartsexpression.hh:1493
BinaryParameterExpression< MultiplyOperation, Left, Right > operator*(const ParameterInterface< Left > &left, const ParameterInterface< Right > &right)
Scalar product between parameters.
Definition: parameterexpression.hh:321
A structure defining some trivial default values for the template structure OperatorPartsTraits<Parts...
Definition: operatorparts.hh:45
Identity, i.e. just wrap the object.
Definition: expressionoperations.hh:284
Subtraction of two objects and unary minus.
Definition: expressionoperations.hh:239
Multiplication of two objects.
Definition: expressionoperations.hh:248
Traits-template which has to be specialized for each individual model.
Definition: operatorparts.hh:36
Multiplication by scalars from the left.
Definition: expressionoperations.hh:257