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
8namespace Dune
9{
10
11 namespace ACFem
12 {
13
35 template<class ExpressionImp>
37 {
39 typedef ExpressionImp ExpressionType;
40
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.111.3 (Aug 13, 22:30, 2024)