DUNE-ACFEM (2.5.1)

functionexpression.hh
1 #ifndef __DUNE_ACFEM_FUNCTIONEXPRESSION_HH__
2 #define __DUNE_ACFEM_FUNCTIONEXPRESSION_HH__
3 
4 #include <dune/fem/version.hh>
5 #include <dune/fem/function/common/function.hh>
6 
7 #include "../functions/constantfunction.hh"
8 #include "../functions/parameterfunction.hh"
9 #include "../functions/functionoperations.hh"
10 #include "../expressions/parameterinterface.hh"
11 
12 namespace Dune
13 {
14 
15  namespace ACFem
16  {
17 
36  template<class FunctionSpaceImp, class ExpressionImp>
38  : public Fem::Function<FunctionSpaceImp, ExpressionImp>,
39  public ExpressionTemplate<ExpressionImp>
40  {};
41 
43  template<class UnOp, class FunctionType>
45 
47  template<class BinOp, class LeftFunctionType, class RightFunctionType>
49 
51 
56  /******************************************************************************
57  *
58  * Traits and helpers
59  *
60  */
61 
62  /* Determine the resulting function space */
63  template<class LeftSpace, class RightSpace>
64  struct FunctionMultiplicationResultTraits
65  {
66  typedef LeftSpace LeftFunctionSpaceType;
67  typedef RightSpace RightFunctionSpaceType;
68 
69  typedef typename LeftFunctionSpaceType::ScalarFunctionSpaceType LeftScalarSpaceType;
70  typedef typename RightFunctionSpaceType::ScalarFunctionSpaceType RightScalarSpaceType;
71 
72  static_assert(std::is_same<LeftScalarSpaceType, RightScalarSpaceType>::value,
73  "Scalar functions spaces do not coincide");
74 
75  enum {
76  sameSpace = std::is_same<LeftFunctionSpaceType, RightFunctionSpaceType>::value,
77  leftScalar = std::is_same<LeftFunctionSpaceType, LeftScalarSpaceType>::value,
78  rightScalar = std::is_same<RightFunctionSpaceType, RightScalarSpaceType>::value
79  };
80 
81  static_assert(sameSpace || leftScalar || rightScalar,
82  "Only S-multiplication and scalar products are supported");
83 
84  // Scalar products result in scalars, s-mult results in vectors/
85  typedef typename
86  std::conditional<sameSpace,
87  LeftScalarSpaceType,
88  typename std::conditional<leftScalar,
89  RightFunctionSpaceType,
90  LeftFunctionSpaceType>::type>::type
91  FunctionSpaceType;
92  };
93 
95  template<class BinOp, class LeftFunctionType, class RightFunctionType>
97 
98  template<class LeftFunction, class RightFunction>
99  struct BinaryFunctionExpressionTraits<MultiplyOperation, LeftFunction, RightFunction>
100  {
101  typedef LeftFunction LeftFunctionType;
102  typedef RightFunction RightFunctionType;
103  typedef typename LeftFunctionType::FunctionSpaceType LeftFunctionSpaceType;
104  typedef typename RightFunctionType::FunctionSpaceType RightFunctionSpaceType;
105 
106  typedef typename
107  FunctionMultiplicationResultTraits<LeftFunctionSpaceType, RightFunctionSpaceType>::FunctionSpaceType
108  FunctionSpaceType;
109  };
110 
112  template<class Factor, class Function>
114  {
115  typedef Function FunctionType;
116  typedef Factor FactorType;
117  typedef typename FunctionType::FunctionSpaceType FunctionSpaceType;
118  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;
119  typedef typename FunctionSpaceType::DomainFieldType DomainFieldType;
120  typedef typename FunctionSpaceType::RangeType RangeType;
121  typedef typename FunctionSpaceType::DomainType DomainType;
122  typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;
123  typedef typename FunctionSpaceType::HessianRangeType HessianRangeType;
124  };
125 
127  template<class LeftFunction, class RightFunction>
128  struct BinaryFunctionExpressionTraits<PlusOperation, LeftFunction, RightFunction>
129  {
130  typedef LeftFunction LeftFunctionType;
131  typedef RightFunction RightFunctionType;
132  typedef typename LeftFunctionType::FunctionSpaceType LeftFunctionSpaceType;
133  typedef typename RightFunctionType::FunctionSpaceType RightFunctionSpaceType;
134 
135  static_assert(std::is_same<LeftFunctionSpaceType, RightFunctionSpaceType>::value,
136  "Function spaces must agree, cannot combine them");
137 
138  typedef LeftFunctionSpaceType FunctionSpaceType;
139  };
140 
142  template<class LeftFunction, class RightFunction>
143  struct BinaryFunctionExpressionTraits<MinusOperation, LeftFunction, RightFunction>
144  : public BinaryFunctionExpressionTraits<PlusOperation, LeftFunction, RightFunction>
145  {};
146 
147  // BinaryFunctionExpression
148  // -------------------
149 
153  template<class BinOp, class LeftFunction, class RightFunction>
155  : public FunctionExpression<typename
156  BinaryFunctionExpressionTraits<BinOp, LeftFunction, RightFunction>::FunctionSpaceType,
157  BinaryFunctionExpression<BinOp, LeftFunction, RightFunction> >
158  {
159  typedef LeftFunction LeftFunctionType;
160  typedef RightFunction RightFunctionType;
161  public:
164  private:
166  typedef Fem::Function<typename TraitsType::FunctionSpaceType, ThisType> BaseType;
167  typedef BinOp OperationTagType;
168  typedef BinaryFunctionExpressionOperation<BinOp> OperationType;
169  public:
170  // type of discrete function space
171  typedef typename TraitsType::FunctionSpaceType FunctionSpaceType;
172 
174  typedef typename FunctionSpaceType::DomainFieldType DomainFieldType;
176  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;
178  typedef typename FunctionSpaceType::DomainType DomainType;
180  typedef typename FunctionSpaceType::RangeType RangeType;
182  typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;
184  typedef typename FunctionSpaceType::HessianRangeType HessianRangeType;
185 
186  public:
187  // reference to function this local belongs to
188  BinaryFunctionExpression(const LeftFunctionType &f,
189  const RightFunctionType &g)
190  : leftFunction_(f), rightFunction_(g)
191  {}
192 
193  // We DO allow copying
194  BinaryFunctionExpression(const ThisType &other)
195  : leftFunction_(other.leftFunction_),
196  rightFunction_(other.rightFunction_)
197  {}
198 
200  void evaluate(const DomainType &global, RangeType &result) const
201  {
202  OperationType::evaluate(leftFunction_(), rightFunction_(), global, result);
203  }
204 
206  void jacobian(const DomainType &global, JacobianRangeType &result) const
207  {
208  OperationType::jacobian(leftFunction_(), rightFunction_(), global, result);
209  }
210 
212  void hessian(const DomainType &global, HessianRangeType &result) const
213  {
214  OperationType::jacobian(leftFunction_(), rightFunction_(), global, result);
215  }
216 
217  public:
218  const LeftFunctionType& leftFunction() const { return leftFunction_(); }
219  const RightFunctionType& rightFunction() const { return rightFunction_(); }
220 
221  private:
222  ExpressionStorage<LeftFunctionType> leftFunction_;
223  ExpressionStorage<RightFunctionType> rightFunction_;
224  };
225 
226  // BinaryFunctionExpression
227  // -------------------
228 
230  template<class FactorType, class FunctionType>
231  class BinaryFunctionExpression<SMultiplyOperation, FactorType, FunctionType>
232  : public FunctionExpression<typename FunctionType::FunctionSpaceType,
233  BinaryFunctionExpression<SMultiplyOperation, FactorType, FunctionType> >
234  {
236  typedef Fem::Function<typename FunctionType::FunctionSpaceType, ThisType> BaseType;
239  public:
242 
243  // type of discrete function space
244  typedef typename TraitsType::FunctionSpaceType FunctionSpaceType;
245 
247  typedef typename FunctionSpaceType::DomainFieldType DomainFieldType;
249  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;
251  typedef typename FunctionSpaceType::DomainType DomainType;
253  typedef typename FunctionSpaceType::RangeType RangeType;
255  typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;
257  typedef typename FunctionSpaceType::HessianRangeType HessianRangeType;
258 
259  public:
260  // reference to function this local belongs to
261  BinaryFunctionExpression(const FactorType &s, const FunctionType &f)
262  : scalar_(s),
263  function_(f)
264  {}
265 
266  // We DO allow copying of expressions
267  BinaryFunctionExpression(const ThisType &other)
268  : scalar_(other.scalar_),
269  function_(other.function_)
270  {}
271 
273  void evaluate(const DomainType &global, RangeType &result) const
274  {
275  function_().evaluate(global, result);
276  result *= parameterValue(scalar_());
277  }
278 
280  void jacobian(const DomainType &global, JacobianRangeType &result) const
281  {
282  function_().jacobian(global, result);
283  result *= parameterValue(scalar_());
284  }
285 
287  void hessian(const DomainType &global, HessianRangeType &result) const
288  {
289  function_().hessian(global, result);
290  result *= parameterValue(scalar_());
291  }
292 
293  public:
294  const FactorType& scalar() const { return scalar_(); }
295  const FunctionType& function() const { return function_(); }
296 
297  protected:
298  ExpressionStorage<FactorType> scalar_;
299  ExpressionStorage<FunctionType> function_;
300  };
301 
303  //
304  // Unary expressions
305 
306  // The result space may depend on the operation. The default is to
307  // have the result space equal to the function space (inversion,
308  // negation etc.)
309  template<class UnOp, class FunctionType>
310  struct UnaryFunctionOperationTraits
311  {
312  typedef typename FunctionType::FunctionSpaceType FunctionSpaceType;
313  };
314 
315  template<class FunctionType>
316  struct UnaryFunctionOperationTraits<SquareOperation, FunctionType>
317  {
318  typedef typename FunctionType::FunctionSpaceType::ScalarFunctionSpaceType FunctionSpaceType;
319  };
320 
322  template <class UnOp, class FunctionType>
324  {
325  typedef UnaryFunctionOperationTraits<UnOp, FunctionType> OperationTraitsType;
326  typedef typename OperationTraitsType::FunctionSpaceType FunctionSpaceType;
327 
328  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;
329  typedef typename FunctionSpaceType::DomainFieldType DomainFieldType;
330  typedef typename FunctionSpaceType::RangeType RangeType;
331  typedef typename FunctionSpaceType::DomainType DomainType;
332  typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;
333  };
334 
335  // UnaryFunctionExpression
336  // -------------------
337 
341  template<class UnOp, class FunctionType>
343  : public FunctionExpression<typename UnaryFunctionExpressionTraits<UnOp, FunctionType>::FunctionSpaceType,
344  UnaryFunctionExpression<UnOp, FunctionType> >
345  {
346  public:
349  private:
351  typedef Fem::Function<typename TraitsType::FunctionSpaceType, ThisType> BaseType;
352  typedef UnOp OperationTagType;
353  typedef UnaryFunctionExpressionOperation<UnOp> OperationType;
354  public:
355  // type of discrete function space
356  typedef typename TraitsType::FunctionSpaceType FunctionSpaceType;
357 
359  typedef typename FunctionSpaceType::DomainFieldType DomainFieldType;
361  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;
363  typedef typename FunctionSpaceType::DomainType DomainType;
365  typedef typename FunctionSpaceType::RangeType RangeType;
367  typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;
369  typedef typename FunctionSpaceType::HessianRangeType HessianRangeType;
370 
371  // reference to function this local belongs to
372  UnaryFunctionExpression(const FunctionType &f)
373  : function_(f)
374  {}
375 
376  // reference to function this local belongs to
377  UnaryFunctionExpression(const ThisType &other)
378  : function_(other.function_)
379  {}
380 
382  void evaluate(const DomainType &global, RangeType &result) const
383  {
384  OperationType::evaluate(function_(), global, result);
385  }
386 
388  void jacobian(const DomainType &global, JacobianRangeType &result) const
389  {
390  OperationType::jacobian(function_(), global, result);
391  }
392 
394  void hessian(const DomainType &global, HessianRangeType &result) const
395  {
396  OperationType::hessian(function_(), global, result);
397  }
398 
399  public:
400  const FunctionType& function() const { return function_(); }
401 
402  private:
403  ExpressionStorage<FunctionType> function_;
404  };
405 
406  // UnaryFunctionExpression<IdentityOperation>
407  // -------------------
408 
411  template<class FunctionType>
413  : public FunctionExpression<typename FunctionType::FunctionSpaceType,
414  UnaryFunctionExpression<IdentityOperation, FunctionType> >
415  {
417  typedef Fem::Function<typename FunctionType::FunctionSpaceType, ThisType> BaseType;
419  typedef UnaryFunctionExpressionOperation<OperationTagType> OperationType;
420  public:
423 
425  typedef typename TraitsType::FunctionSpaceType FunctionSpaceType;
426 
428  typedef typename FunctionSpaceType::DomainFieldType DomainFieldType;
430  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;
432  typedef typename FunctionSpaceType::DomainType DomainType;
434  typedef typename FunctionSpaceType::RangeType RangeType;
436  typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;
438  typedef typename FunctionSpaceType::HessianRangeType HessianRangeType;
439 
440  // reference to function this local belongs to
441  UnaryFunctionExpression(const FunctionType &f)
442  : function_(f)
443  {}
444 
445  // reference to function this local belongs to
446  UnaryFunctionExpression(const ThisType &other)
447  : function_(other.function_)
448  {}
449 
451  void evaluate(const DomainType &global, RangeType &result) const
452  {
453  function_().evaluate(global, result);
454  }
455 
457  void jacobian(const DomainType &global, JacobianRangeType &result) const
458  {
459  function_().jacobian(global, result);
460  }
461 
463  void hessian(const DomainType &global, HessianRangeType &result) const
464  {
465  function_().hessian(global, result);
466  }
467  private:
469  };
470 
472 
474 
475  } // namespace ACFem
476 
477 } // namespace Dune
478 
479 
480 #endif // #ifndef __DUNE_ACFEM_FUNCTIONEXPRESSION_HH__
481 
482 
S-multiplication with RangeFieldType scalars.
Definition: functionexpression.hh:234
FunctionSpaceType::RangeFieldType RangeFieldType
range type (from function space)
Definition: functionexpression.hh:249
FunctionSpaceType::HessianRangeType HessianRangeType
hessian type (from function space)
Definition: functionexpression.hh:257
void hessian(const DomainType &global, HessianRangeType &result) const
global hessian
Definition: functionexpression.hh:287
FunctionSpaceType::DomainFieldType DomainFieldType
domain type (from function space)
Definition: functionexpression.hh:247
FunctionSpaceType::JacobianRangeType JacobianRangeType
jacobian type (from function space)
Definition: functionexpression.hh:255
BinaryFunctionExpressionTraits< SMultiplyOperation, FactorType, FunctionType > TraitsType
type of traits
Definition: functionexpression.hh:241
void evaluate(const DomainType &global, RangeType &result) const
global evaluate
Definition: functionexpression.hh:273
FunctionSpaceType::RangeType RangeType
range type (from function space)
Definition: functionexpression.hh:253
void jacobian(const DomainType &global, JacobianRangeType &result) const
global jacobian
Definition: functionexpression.hh:280
FunctionSpaceType::DomainType DomainType
domain type (from function space)
Definition: functionexpression.hh:251
Unary expressions.
Definition: functionexpression.hh:158
FunctionSpaceType::DomainFieldType DomainFieldType
domain type (from function space)
Definition: functionexpression.hh:174
BinaryFunctionExpressionTraits< BinOp, LeftFunctionType, RightFunctionType > TraitsType
type of traits
Definition: functionexpression.hh:163
FunctionSpaceType::RangeFieldType RangeFieldType
range type (from function space)
Definition: functionexpression.hh:176
FunctionSpaceType::HessianRangeType HessianRangeType
hessian type (from function space)
Definition: functionexpression.hh:184
void evaluate(const DomainType &global, RangeType &result) const
global evaluate
Definition: functionexpression.hh:200
FunctionSpaceType::DomainType DomainType
domain type (from function space)
Definition: functionexpression.hh:178
void jacobian(const DomainType &global, JacobianRangeType &result) const
global jacobian
Definition: functionexpression.hh:206
FunctionSpaceType::RangeType RangeType
range type (from function space)
Definition: functionexpression.hh:180
void hessian(const DomainType &global, HessianRangeType &result) const
global hessian
Definition: functionexpression.hh:212
FunctionSpaceType::JacobianRangeType JacobianRangeType
jacobian type (from function space)
Definition: functionexpression.hh:182
Underlying tag-structure.
Definition: functionexpression.hh:40
Specialize for the identity wrapper operation.
Definition: functionexpression.hh:415
void hessian(const DomainType &global, HessianRangeType &result) const
evaluate function on local coordinate local
Definition: functionexpression.hh:463
FunctionSpaceType::JacobianRangeType JacobianRangeType
jacobian type (from function space)
Definition: functionexpression.hh:436
TraitsType::FunctionSpaceType FunctionSpaceType
type of function space
Definition: functionexpression.hh:425
void evaluate(const DomainType &global, RangeType &result) const
evaluate function on local coordinate local
Definition: functionexpression.hh:451
FunctionSpaceType::HessianRangeType HessianRangeType
hessian type (from function space)
Definition: functionexpression.hh:438
FunctionSpaceType::RangeFieldType RangeFieldType
range type (from function space)
Definition: functionexpression.hh:430
void jacobian(const DomainType &global, JacobianRangeType &result) const
evaluate function on local coordinate local
Definition: functionexpression.hh:457
UnaryFunctionExpressionTraits< OperationTagType, FunctionType > TraitsType
type of traits
Definition: functionexpression.hh:422
FunctionSpaceType::DomainType DomainType
domain type (from function space)
Definition: functionexpression.hh:432
FunctionSpaceType::RangeType RangeType
range type (from function space)
Definition: functionexpression.hh:434
FunctionSpaceType::DomainFieldType DomainFieldType
domain type (from function space)
Definition: functionexpression.hh:428
Binary expressions.
Definition: functionexpression.hh:345
FunctionSpaceType::JacobianRangeType JacobianRangeType
jacobian type (from function space)
Definition: functionexpression.hh:367
void jacobian(const DomainType &global, JacobianRangeType &result) const
evaluate function on local coordinate local
Definition: functionexpression.hh:388
FunctionSpaceType::DomainType DomainType
domain type (from function space)
Definition: functionexpression.hh:363
void hessian(const DomainType &global, HessianRangeType &result) const
evaluate function on local coordinate local
Definition: functionexpression.hh:394
FunctionSpaceType::HessianRangeType HessianRangeType
hessian type (from function space)
Definition: functionexpression.hh:369
FunctionSpaceType::RangeType RangeType
range type (from function space)
Definition: functionexpression.hh:365
void evaluate(const DomainType &global, RangeType &result) const
evaluate function on local coordinate local
Definition: functionexpression.hh:382
UnaryFunctionExpressionTraits< UnOp, FunctionType > TraitsType
type of traits
Definition: functionexpression.hh:348
FunctionSpaceType::RangeFieldType RangeFieldType
range type (from function space)
Definition: functionexpression.hh:361
FunctionSpaceType::DomainFieldType DomainFieldType
domain type (from function space)
Definition: functionexpression.hh:359
ParameterValue< Value >::ResultType parameterValue(const Value &value)
Return the unaltered argument for non-parameters and otherwise the parameter value.
Definition: parameterinterface.hh:263
Multiplication from the left by a scalar constant.
Definition: functionoperations.hh:567
traits of BinaryFunctionExpression
Definition: functionexpression.hh:96
Provide up-cast functionality for expression templates.
Definition: expressionoperations.hh:37
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
Addition of two objects.
Definition: expressionoperations.hh:230
Multiplication by scalars from the left.
Definition: expressionoperations.hh:257
traits of UnaryFunctionExpression
Definition: functionexpression.hh:324
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)