DUNE-ACFEM (2.5.1)

expressionoperations.hh
Go to the documentation of this file.
1 
5 #ifndef __EXPRESSION_OPERATIONS_HH__
6 #define __EXPRESSION_OPERATIONS_HH__
7 
8 namespace Dune
9 {
10 
11  namespace ACFem
12  {
13 
35  template<class ExpressionImp>
37  {
39  typedef ExpressionImp ExpressionType;
40 
42  const ExpressionType& expression() const
43  {
44  return static_cast<const ExpressionType&>(*this);
45  }
46 
49  {
50  return static_cast<ExpressionType&>(*this);
51  }
52 
55  {
56  return expression();
57  }
58  };
59 
70  template<class Interface, class Implementation>
71  const Implementation& asImp(const Fem::BartonNackmanInterface<Interface, Implementation>& arg)
72  {
73  return static_cast<const Implementation&>(arg);
74  }
75 
98  template<class SomeThing>
100  {
101  typedef SomeThing ObjectType;
102 
103  ExpressionReferenceStorage(const ObjectType& thing)
104  : object_(thing)
105  {}
106 
107  template<class Other>
108  ExpressionReferenceStorage(const Other& other)
109  : object_(static_cast<const ObjectType&>(other)) {}
110 
112  : object_(0)
113  {}
114 
115  const ObjectType& operator()() const {
116  return object_;
117  }
118 
119  private:
120  const ObjectType& object_;
121  };
122 
126  template<class SomeThing>
128  {
129  typedef SomeThing ObjectType;
130 
131  ExpressionCopyStorage(const ObjectType& thing) : object_(thing) {}
132 
133  template<class Other>
134  ExpressionCopyStorage(const Other& other) : object_(static_cast<const ObjectType&>(other)) {}
135 
136  const ObjectType& operator()() const {
137  return object_;
138  }
139 
140  private:
141  ObjectType object_;
142  };
143 
156  template<class SomeThing>
158  : public std::conditional<std::is_base_of<ExpressionTemplate<SomeThing>, SomeThing>::value,
159  ExpressionCopyStorage<SomeThing>,
160  ExpressionReferenceStorage<SomeThing> >::type
161  {
162  typedef SomeThing ObjectType;
163  typedef typename
164  std::conditional<
165  std::is_base_of<ExpressionTemplate<ObjectType>, ObjectType>::value,
168  BaseType;
169 
170  // inherit the constructors from the base class.
171  using BaseType::BaseType;
172 
173  private:
174  // some potential to shoot yourself into your own feet, add some
175  // static asserts here in order to be sure that the things
176  // happen that we want to happen
177 
178  enum {
179  isExpression = std::is_base_of<ExpressionTemplate<ObjectType>, ObjectType>::value,
180  isCopyStorage = std::is_same<BaseType, ExpressionCopyStorage<ObjectType> >::value,
181  isReferenceStorage = std::is_same<BaseType, ExpressionReferenceStorage<ObjectType> >::value
182  };
183  // comment out in order to trigger an error for anything copied
184  //static_assert(isCopyStorage, "I am copied");
185  // comment out in order to trigger an error for anything not copied
186  //static_assert(isReferenceStorage, "I am copied");
187 
188  // do a consistency check
189  static_assert(!isExpression || isCopyStorage, "expressions should be stored as copies");
190  static_assert(isExpression || isReferenceStorage, "non-expressions should not be copied");
191  };
192 
193  template<>
194  struct ExpressionStorage<double>
195  : public ExpressionCopyStorage<double>
196  {
197  protected:
198  typedef ExpressionCopyStorage<double> BaseType;
199  public:
200  typedef double ObjectType;
201 
202  using BaseType::BaseType;
203  };
204 
205  template<>
206  struct ExpressionStorage<const double>
207  : public ExpressionCopyStorage<double>
208  {
209  protected:
210  typedef ExpressionCopyStorage<double> BaseType;
211  public:
212  typedef double ObjectType;
213 
214  using BaseType::BaseType;
215  };
216 
218 
230  {
231  static std::string name()
232  {
233  return "+";
234  }
235  };
236 
239  {
240  static std::string name()
241  {
242  return "-";
243  }
244  };
245 
248  {
249  static std::string name()
250  {
251  return "*";
252  }
253  };
254 
257  {
258  static std::string name()
259  {
260  return "*";
261  }
262  };
263 
266  {
267  static std::string name()
268  {
269  return "& *";
270  }
271  };
272 
275  {
276  static std::string name()
277  {
278  return "1.0/";
279  }
280  };
281 
284  {
285  static std::string name()
286  {
287  return "Id";
288  }
289  };
290 
293  {
294  static std::string name()
295  {
296  return "exp";
297  }
298  };
299 
302  {
303  static std::string name()
304  {
305  return "log";
306  }
307  };
308 
311  {
312  static std::string name()
313  {
314  return "sqrt";
315  }
316  };
317 
320  {
321  static std::string name()
322  {
323  return "sqr";
324  }
325  };
326 
329  {
330  static std::string name()
331  {
332  return "sin";
333  }
334  };
335 
338  {
339  static std::string name()
340  {
341  return "cos";
342  }
343  };
344 
347  {
348  static std::string name()
349  {
350  return "tan";
351  }
352  };
353 
356  {
357  static std::string name()
358  {
359  return "atan";
360  }
361  };
362 
365  {
366  static std::string name()
367  {
368  return "asin";
369  }
370  };
371 
374  {
375  static std::string name()
376  {
377  return "acos";
378  }
379  };
380 
381  template<class Op>
382  std::string operationName(const Op&, const std::string& arg)
383  {
384  return Op::name() + "(" + arg + ")";
385  }
386 
387  template<class Op>
388  std::string operationName(const Op&, const std::string& left, const std::string& right)
389  {
390  return "(" + left + " " + Op::name() + " " + right + ")";
391  }
392 
394 
427  template<class ExpressionImpl>
429  : public ExpressionTemplate<ExpressionImpl>
430  {};
431 
437  template<class ExpressionImpl>
439  : public ExpressionTemplate<ExpressionImpl>
440  {};
441 
446  template<class ExpressionImpl>
448  : public ExpressionTemplate<ExpressionImpl>
449  {};
450 
452  template<class ExpressionImpl>
454  {
455  typedef ExpressionImpl ExpressionType;
456  static const bool isZero = std::is_base_of<ZeroExpression<ExpressionType>, ExpressionType>::value;
457  static const bool isNonZero = std::is_base_of<NonZeroExpression<ExpressionType>, ExpressionType>::value;
458  static const bool isOne = std::is_base_of<OneExpression<ExpressionType>, ExpressionType>::value;
459  };
460 
462  template<class Expression>
464  : public DefaultExpressionTraits<Expression>
465  {};
466 
468  template<class Expression>
469  constexpr bool isZero(Expression&&)
470  {
472  }
473 
475  template<class UnOp, class LeftOperand, class RightOperand = void>
477 
478  template<class Operand>
479  struct ExpressionResult<MinusOperation, Operand>
480  {
481  typedef decltype(-std::declval<Operand>()) Type;
482  static auto apply(const Operand& arg) -> decltype(-arg)
483  {
484  return -arg;
485  }
486  };
487 
488  template<class Operand>
489  struct ExpressionResult<PlusOperation, Operand>
490  {
491  typedef decltype(+std::declval<Operand>()) Type;
492  static auto apply(const Operand& arg) -> decltype(+arg)
493  {
494  return +arg;
495  }
496  };
497 
498  template<class Operand>
499  struct ExpressionResult<IdentityOperation, Operand>
500  {
501  private:
502  typedef
503  typename std::remove_reference<typename std::remove_const<Operand>::type>::type
504  OperandType;
505  enum {
506  isExpression = std::is_base_of<ExpressionTemplate<OperandType>, OperandType>::value
507  };
508  template<class Object, bool expr>
509  struct ResultHelper;
510 
511  template<class Object>
512  struct ResultHelper<Object, true>
513  {
514  typedef decltype(*std::declval<Object>()) Type;
515  static auto apply(const Object& arg) -> decltype(*arg)
516  {
517  return *arg;
518  }
519  };
520 
521  template<class Object>
522  struct ResultHelper<Object, false>
523  {
524  typedef const Object& Type;
525  static Type apply(Type arg)
526  {
527  return arg;
528  }
529  };
530  public:
531  typedef typename ResultHelper<OperandType, isExpression>::Type Type;
532  static Type apply(const OperandType& arg)
533  {
534  return ResultHelper<OperandType, isExpression>::apply(arg);
535  }
536  };
537 
538  template<class Left, class Right>
539  struct ExpressionResult<MinusOperation, Left, Right>
540  {
541  typedef decltype(std::declval<Left>()-std::declval<Right>()) Type;
542  static auto apply(const Left& left, const Right& right) -> decltype(left-right)
543  {
544  return left-right;
545  }
546  };
547 
548  template<class Left, class Right>
549  struct ExpressionResult<PlusOperation, Left, Right>
550  {
551  typedef decltype(std::declval<Left>()+std::declval<Right>()) Type;
552  static auto apply(const Left& left, const Right& right) -> decltype(left+right)
553  {
554  return left+right;
555  }
556  };
557 
558  template<class Left, class Right>
559  struct ExpressionResult<MultiplyOperation, Left, Right>
560  {
561  typedef decltype(std::declval<Left>()*std::declval<Right>()) Type;
562  static auto apply(const Left& left, const Right& right) -> decltype(left*right)
563  {
564  return left*right;
565  }
566  };
567 
568  template<class Left, class Right>
569  struct ExpressionResult<SMultiplyOperation, Left, Right>
570  {
571  typedef decltype(std::declval<Left>()*std::declval<Right>()) Type;
572  static auto apply(const Left& left, const Right& right) -> decltype(left*right)
573  {
574  return left*right;
575  }
576  };
577 
578  template<class Op, class Left, class Right = void>
579  static inline
580  auto makeExpression(const Op, const Left& left, const Right& right)
581  -> decltype(ExpressionResult<Op, Left, Right>::apply(left, right))
582  {
583  return ExpressionResult<Op, Left, Right>::apply(left, right);
584  }
585 
587  template<class UnOp, class Value>
589  {
590  typedef void ResultType;
591  constexpr static unsigned polynomialOrder(unsigned oldOrder)
592  {
593  return 111;
594  }
595  };
596 
597  template<class Value>
599  {
600  typedef Value ResultType;
601  constexpr static unsigned polynomialOrder(unsigned oldOrder)
602  {
603  return oldOrder;
604  }
605  };
606 
607  template<class Value>
608  struct UnaryExpressionTraits<IdentityOperation, Value>
609  {
610  typedef Value ResultType;
611  constexpr static unsigned polynomialOrder(unsigned oldOrder)
612  {
613  return oldOrder;
614  }
615  };
616 
617  template<class Value>
618  struct UnaryExpressionTraits<SquareOperation, Value>
619  {
620  typedef typename FieldTraits<Value>::field_type ResultType;
621  constexpr static unsigned polynomialOrder(unsigned oldOrder)
622  {
623  return oldOrder*oldOrder;
624  }
625  };
626 
627  template<class Value>
628  struct UnaryExpressionTraits<CosOperation, Value>
629  {
630  typedef Value ResultType;
631  constexpr static unsigned polynomialOrder(unsigned oldOrder)
632  {
633  return oldOrder;
634  }
635  };
636 
637  template<class Value>
638  struct UnaryExpressionTraits<SinOperation, Value>
639  {
640  typedef Value ResultType;
641  constexpr static unsigned polynomialOrder(unsigned oldOrder)
642  {
643  return oldOrder;
644  }
645  };
646 
647  template<class Value>
648  struct UnaryExpressionTraits<TanOperation, Value>
649  {
650  typedef Value ResultType;
651  constexpr static unsigned polynomialOrder(unsigned oldOrder)
652  {
653  return oldOrder;
654  }
655  };
656 
657  template<class Value>
658  struct UnaryExpressionTraits<AtanOperation, Value>
659  {
660  typedef Value ResultType;
661  constexpr static unsigned polynomialOrder(unsigned oldOrder)
662  {
663  return oldOrder;
664  }
665  };
666 
667  template<class Value>
668  struct UnaryExpressionTraits<AcosOperation, Value>
669  {
670  typedef Value ResultType;
671  constexpr static unsigned polynomialOrder(unsigned oldOrder)
672  {
673  return oldOrder;
674  }
675  };
676 
677  template<class Value>
678  struct UnaryExpressionTraits<AsinOperation, Value>
679  {
680  typedef Value ResultType;
681  constexpr static unsigned polynomialOrder(unsigned oldOrder)
682  {
683  return oldOrder;
684  }
685  };
686 
687  template<class Value>
688  struct UnaryExpressionTraits<SqrtOperation, Value>
689  {
690  typedef Value ResultType;
691  constexpr static unsigned polynomialOrder(unsigned oldOrder)
692  {
693  return oldOrder;
694  }
695  };
696 
698  template<class BinOp, class LeftValue, class RightValue>
700  {
701  typedef void ResultType;
702  constexpr static unsigned polynomialOrder(unsigned order1, unsigned order2)
703  {
704  return 111;
705  }
706  };
707 
708  template<class Value>
709  struct BinaryExpressionTraits<PlusOperation, Value, Value>
710  {
711  typedef Value ResultType;
712  constexpr static unsigned polynomialOrder(unsigned order1, unsigned order2)
713  {
714  return std::max(order1, order2);
715  }
716  };
717 
718  template<class Value>
719  struct BinaryExpressionTraits<MinusOperation, Value, Value>
720  {
721  typedef Value ResultType;
722  constexpr static unsigned polynomialOrder(unsigned order1, unsigned order2)
723  {
724  return std::max(order1, order2);
725  }
726  };
727 
728  template<class Value>
729  struct BinaryExpressionTraits<MultiplyOperation, Value, Value>
730  {
731  typedef typename FieldTraits<Value>::field_type ResultType;
732  constexpr static unsigned polynomialOrder(unsigned order1, unsigned order2)
733  {
734  return order1 * order2;
735  }
736  };
737 
738  template<class Field>
739  struct BinaryExpressionTraits<SMultiplyOperation, Field, Field>
740  {
741  typedef FieldVector<Field, 1> ResultType;
742  constexpr static unsigned polynomialOrder(unsigned order1, unsigned order2)
743  {
744  return order1 * order2;
745  }
746  };
747 
748  template<class Field, int dimension>
749  struct BinaryExpressionTraits<SMultiplyOperation, typename FieldTraits<Field>::field_type, FieldVector<Field, dimension> >
750  {
751  typedef FieldVector<Field, dimension> ResultType;
752  constexpr static unsigned polynomialOrder(unsigned order1, unsigned order2)
753  {
754  return order1 * order2;
755  }
756  };
757 
758  template<class Field, int dimension>
759  struct BinaryExpressionTraits<SMultiplyOperation, FieldVector<Field, dimension>, typename FieldTraits<Field>::field_type>
760  {
761  typedef FieldVector<Field, dimension> ResultType;
762  constexpr static unsigned polynomialOrder(unsigned order1, unsigned order2)
763  {
764  return order1 * order2;
765  }
766  };
767 
768  template<class Field, int dimension>
769  struct BinaryExpressionTraits<SMultiplyOperation, FieldVector<Field, 1>, FieldVector<Field, dimension> >
770  {
771  typedef FieldVector<Field, dimension> ResultType;
772  constexpr static unsigned polynomialOrder(unsigned order1, unsigned order2)
773  {
774  return order1 * order2;
775  }
776  };
777 
778  template<class Field, int dimension>
779  struct BinaryExpressionTraits<SMultiplyOperation, FieldVector<Field, dimension>, FieldVector<Field, 1> >
780  {
781  typedef FieldVector<Field, dimension> ResultType;
782  constexpr static unsigned polynomialOrder(unsigned order1, unsigned order2)
783  {
784  return order1 * order2;
785  }
786  };
787 
789 
791 
792  } // ACFem
793 
794 } // Dune
795 
796 #endif
constexpr bool isZero(Expression &&)
Specialize to evaluate to true for zero expressions.
Definition: expressionoperations.hh:469
const Implementation & asImp(const Fem::BartonNackmanInterface< Interface, Implementation > &arg)
Up-cast to the implementation for any Fem::BartonNackmanInterface.
Definition: expressionoperations.hh:71
LocalFunctionWrapper< LocalMaxAdapter< GridFunction1, GridFunction2 >, typename GridFunction1::GridPartType > max(const Fem::Function< typename GridFunction1::FunctionSpaceType, GridFunction1 > &f1, const Fem::Function< typename GridFunction2::FunctionSpaceType, GridFunction2 > &f2, const std::string &name="")
Pointwise maximum of two given functions.
Definition: maxfunction.hh:121
Taking the cosine of an object.
Definition: expressionoperations.hh:374
Taking the cosine of an object.
Definition: expressionoperations.hh:365
Taking the cosine of an object.
Definition: expressionoperations.hh:356
The default result type is void in order to trigger compilation errors.
Definition: expressionoperations.hh:700
Taking the cosine of an object.
Definition: expressionoperations.hh:338
Default expressions traits.
Definition: expressionoperations.hh:454
Exponentiation of an object.
Definition: expressionoperations.hh:293
Store things as copy, serves as default implementation for the ExpressionStorage class.
Definition: expressionoperations.hh:128
Store things as reference, serves as default implementation for the ExpressionStorage class.
Definition: expressionoperations.hh:100
Automatically deduce the type by applying the respective operation.
Definition: expressionoperations.hh:476
An ExpressionStorage object stores either a copy or a reference of an object.
Definition: expressionoperations.hh:161
Provide up-cast functionality for expression templates.
Definition: expressionoperations.hh:37
const ExpressionType & expression() const
Return a const reference to the underlying expression.
Definition: expressionoperations.hh:42
ExpressionType operator*() const
Return a copy from of the underlying expression.
Definition: expressionoperations.hh:54
ExpressionImp ExpressionType
The type of the underlying expression.
Definition: expressionoperations.hh:39
ExpressionType & expression()
Return a mutable reference to the underlying expression.
Definition: expressionoperations.hh:48
A traits class in order to collect properties of expressions.
Definition: expressionoperations.hh:465
Identity, i.e. just wrap the object.
Definition: expressionoperations.hh:284
Inversion of an object.
Definition: expressionoperations.hh:275
Taking the logarithm of an object.
Definition: expressionoperations.hh:302
Subtraction of two objects and unary minus.
Definition: expressionoperations.hh:239
Multiplication of two objects.
Definition: expressionoperations.hh:248
Multiplication by mutable scalars from the left.
Definition: expressionoperations.hh:266
Complementary to ZeroExpression for use in std::conditional, for example, otherwise unused.
Definition: expressionoperations.hh:440
A tag structure which can be attached as base-class to expressions modelling a 1 (in a field,...
Definition: expressionoperations.hh:449
Addition of two objects.
Definition: expressionoperations.hh:230
Multiplication by scalars from the left.
Definition: expressionoperations.hh:257
Taking the sine of an object.
Definition: expressionoperations.hh:329
Taking the square root of an object.
Definition: expressionoperations.hh:311
Taking the square of an object.
Definition: expressionoperations.hh:320
Taking the cosine of an object.
Definition: expressionoperations.hh:347
The default result type is void in order to trigger compilation errors.
Definition: expressionoperations.hh:589
A tag structure which can be attached as base class to zero-expressions like the ZeroGridFunction,...
Definition: expressionoperations.hh:430
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 12, 22:29, 2024)