DUNE-ACFEM (2.5.1)

vectorexpression.hh
1 #ifndef __DUNE_ACFEM_VECTOREXPRESSION_HH__
2 #define __DUNE_ACFEM_VECTOREXPRESSION_HH__
3 
5 
6 namespace Dune
7 {
8 
9  namespace ACFem
10  {
11 
28  template<class ExpressionImp>
30  : public ExpressionTemplate<ExpressionImp>
31  {
32  };
33 
35  template<class BinOP, class Vector1, class Vector2>
37 
39  template<class OP, class Vector>
41 
46  template<class BinOp, class Vector1, class Vector2>
48  : public VectorExpression<BinaryVectorExpression<BinOp, Vector1, Vector2> >
49  {
50  typedef BinOp BinOpType;
51  typedef
52  ExpressionResult<BinOpType,
53  decltype(std::declval<Vector1>()[0]),
54  decltype(std::declval<Vector2>()[0])>
55  ResultType;
56  public:
57  static_assert(std::is_same<typename Vector1::FieldType, typename Vector2::FieldType>::value,
58  "Cannot combine vector expression over different fields.");
59 
60  typedef typename Vector1::FieldType FieldType;
61  typedef typename ResultType::Type ElementType;
62 
64  : vector1_(v1), vector2_(v2)
65  {};
66 
67  ElementType operator[](size_t index) const
68  {
69  return ResultType::apply(vector1_()[index], vector2_()[index]);
70  }
71 
72  size_t size() const {
73  assert(vector1_().size() == vector2_().size());
74  return vector1_().size();
75  }
76 
77  protected:
80  };
81 
83  template<class Scalar, class Vector>
85  : public VectorExpression<BinaryVectorExpression<SMultiplyOperation, Scalar, Vector> >
86  {
88  typedef
90  decltype(parameterValue(std::declval<Scalar>())),
91  decltype(std::declval<Vector>()[0])>
92  ResultType;
93  public:
94  typedef typename Vector::FieldType FieldType;
95  typedef typename ResultType::Type ElementType;
96 
97  BinaryVectorExpression(const Scalar& s, const VectorExpression<Vector>& v)
98  : scalar_(s), vector_(v)
99  {};
100 
101  ElementType operator[](size_t index) const
102  {
103  return ResultType::apply(parameterValue(scalar_()), vector_()[index]);
104  }
105 
106  size_t size() const {
107  return vector_().size();
108  }
109 
110  protected:
113  };
114 
116  template<class Op, class Vector>
118  : public VectorExpression<UnaryVectorExpression<Op, Vector> >
119  {
120  typedef Op OpType;
121  typedef
122  typename std::remove_reference<decltype(std::declval<Vector>()[0])>::type
123  ComponentType;
125  public:
126  typedef typename Vector::FieldType FieldType;
127  typedef typename ResultType::Type ElementType;
128 
129  UnaryVectorExpression(const Vector& v)
130  : vector_(v)
131  {};
132 
133  ElementType operator[](size_t index) const
134  {
135  return ResultType::apply(vector_()[index]);
136  }
137 
138  size_t size() const {
139  return vector_().size();
140  }
141 
142  protected:
144  };
145 
156  template<class Vector>
158  : public VectorExpression<UnaryVectorExpression<IdentityOperation, Vector> >
159  {
160  typedef IdentityOperation OpType;
161  typedef
162  typename std::remove_reference<decltype(std::declval<Vector>()[0])>::type
163  ComponentType;
164  public:
165  typedef typename FieldTraits<ComponentType>::field_type FieldType;
166  private:
167  enum {
168  hasFieldComponents = std::is_same<ComponentType, FieldType>::value
169  };
170  public:
171  typedef
172  typename std::conditional<hasFieldComponents,
173  FieldType,
175  ComponentType>
176  >::type
177  ElementType;
178 
179  UnaryVectorExpression(const Vector& v)
180  : vector_(v)
181  {};
182 
183  ElementType operator[](size_t index) const
184  {
185  return ElementType(vector_()[index]);
186  }
187 
188  size_t size() const {
189  return vector_().size();
190  }
191 
192  protected:
194  };
195 
197  template<class Field, int rows, int cols>
198  class UnaryVectorExpression<IdentityOperation, FieldMatrix<Field, rows, cols> >
199  : public
201  UnaryVectorExpression<IdentityOperation, FieldMatrix<Field, rows, cols> > >
202  {
203  typedef IdentityOperation OpType;
204  typedef FieldMatrix<Field, rows, cols> MatrixType;
205  typedef typename MatrixType::row_type RowType;
206  public:
207  typedef typename FieldTraits<Field>::field_type FieldType;
209 
210  UnaryVectorExpression(const MatrixType& m)
211  : matrix_(m)
212  {};
213 
214  ElementType operator[](size_t index) const
215  {
216  return ElementType(matrix_()[index]);
217  }
218 
219  size_t size() const {
220  return matrix_().size();
221  }
222 
223  protected:
225  };
226 
228  template<class Expr1, class Expr2>
229  static inline
231  operator+(const VectorExpression<Expr1>& e1, const VectorExpression<Expr2>& e2)
232  {
233  typedef
235  ExpressionType;
236 
237  return ExpressionType(e1, e2);
238  }
239 
241  template<class Expr1, class Expr2>
242  static inline
243  BinaryVectorExpression<MinusOperation, Expr1, Expr2>
244  operator-(const VectorExpression<Expr1>& e1, const VectorExpression<Expr2>& e2)
245  {
246  typedef
248  ExpressionType;
249 
250  return ExpressionType(e1, e2);
251  }
252 
253  namespace {
254  // Helper for scalar products. To find an end in this recursion
255  // operator*() evaluates to a Field element if the components of
256  // the expressions evaluate to a field element.
257  template<class Expr1, class Expr2>
258  struct InnerProductHelper
259  {
260  template<bool haveFieldVectors, class dummy = void>
261  struct ProductFactory;
262 
263  template<class dummy>
264  struct ProductFactory<true, dummy>
265  {
266  typedef typename Expr1::FieldType ResultType;
267 
268  static ResultType apply(const Expr1& l, const Expr2& r)
269  {
270  typename Expr1::FieldType res(0);
271 
272  for (unsigned i = 0; i < l.size(); ++i) {
273  res += l[i] * r[i];
274  }
275 
276  return res;
277  };
278  };
279 
280  template<class dummy>
281  struct ProductFactory<false, dummy>
282  {
283  typedef
284  BinaryVectorExpression<MultiplyOperation, Expr1, Expr2>
285  ResultType;
286 
287  static ResultType apply(const Expr1& l, const Expr2& r)
288  {
289  return ResultType(l, r);
290  };
291  };
292 
293  enum {
294  sameElements = std::is_same<typename Expr1::ElementType, typename Expr2::ElementType>::value,
295  fieldVectors = (sameElements &&
296  std::is_same<typename Expr1::FieldType, typename Expr1::ElementType>::value)
297  };
298 
299  typedef typename ProductFactory<fieldVectors>::ResultType ResultType;
300  static ResultType apply(const Expr1& l, const Expr2& r)
301  {
302  return ProductFactory<fieldVectors>::apply(l, r);
303  }
304  };
305 
306  }
307 
315  template<class Expr1, class Expr2>
316  static inline
317  typename InnerProductHelper<Expr1, Expr2>::ResultType
319  {
320  return InnerProductHelper<Expr1, Expr2>::apply(e1.expression(), e2.expression());
321  }
322 
324  template<class Expr>
325  static inline
326  BinaryVectorExpression<SMultiplyOperation, typename Expr::FieldType, Expr>
327  operator*(const typename Expr::FieldType& s, const VectorExpression<Expr>& e)
328  {
329  typedef typename Expr::FieldType FieldType;
331 
332  return ExpressionType(s, e);
333  }
334 
336  template<class Expr>
337  static inline
338  auto
339  operator*(const VectorExpression<Expr>& e, const typename Expr::FieldType& s)
340  -> decltype(s * e)
341  {
342  return s * e;
343  }
344 
346  template<class Expr>
347  static inline
348  BinaryVectorExpression<SMultiplyOperation, typename Expr::FieldType, Expr>
349  operator*(const FieldVector<typename Expr::FieldType, 1>& s, const VectorExpression<Expr>& e)
350  {
351  typedef typename Expr::FieldType FieldType;
353 
354  return ExpressionType(s[0], e);
355  }
356 
358  template<class Expr>
359  static inline
360  BinaryVectorExpression<SMultiplyOperation, typename Expr::FieldType, Expr>
361  operator*(const VectorExpression<Expr>& e, const FieldVector<typename Expr::FieldType, 1>& s)
362  {
363  typedef typename Expr::FieldType FieldType;
365 
366  return ExpressionType(s[0], e);
367  }
368 
370  template<class Expr>
371  static inline
372  UnaryVectorExpression<MinusOperation, Expr>
373  operator-(const VectorExpression<Expr>& arg)
374  {
375  typedef UnaryVectorExpression<MinusOperation, Expr> ExpressionType;
376 
377  return ExpressionType(arg);
378  }
379 
381  template<class Vector>
382  static inline
383  UnaryVectorExpression<IdentityOperation, Vector>
384  asExpr(const Vector& arg)
385  {
387  }
388 
390  template<class Field, int rows, int cols>
391  static inline
392  UnaryVectorExpression<IdentityOperation, FieldMatrix<Field, rows, cols> >
393  asExpr(const FieldMatrix<Field, rows, cols>& arg)
394  {
396  }
397 
402  template<class Op, class Expr>
403  static inline
404  UnaryVectorExpression<Op, Expr>
406  {
407  return arg.expression();
408  }
409 
414  template<class Op, class Expr1, class Expr2>
415  static inline
416  BinaryVectorExpression<Op, Expr1, Expr2>
418  {
419  return arg.expression();
420  }
421 
423  template<class Vector, class Op, class Expr1, class Expr2>
424  static inline
425  Vector& operator+=(Vector& v,
427  {
428  for (unsigned i = 0; i < v.size(); ++i) {
429  v[i] += e[i];
430  }
431 
432  return v;
433  }
434 
436  template<class Vector, class Op, class Expr>
437  static inline
438  Vector& operator+=(Vector& v,
440  {
441  for (unsigned i = 0; i < v.size(); ++i) {
442  v[i] += e[i];
443  }
444 
445  return v;
446  }
447 
449  template<class Vector, class Op, class Expr1, class Expr2>
450  static inline
451  Vector& operator-=(Vector& v,
453  {
454  for (unsigned i = 0; i < v.size(); ++i) {
455  v[i] -= e[i];
456  }
457 
458  return v;
459  }
460 
462  template<class Vector, class Op, class Expr>
463  static inline
464  Vector& operator-=(Vector& v,
466  {
467  for (unsigned i = 0; i < v.size(); ++i) {
468  v[i] -= e[i];
469  }
470 
471  return v;
472  }
473 
475  namespace {
476  // assignment helper
477 
478  template<bool hasFieldElements, class Dummy = void>
479  struct VectorAssignHelper;
480 
481  template<>
482  struct VectorAssignHelper<true>
483  {
484  template<class To, class From>
485  static void doAssign(To& to, const From& from)
486  {
487  to = from;
488  }
489  };
490 
491  template<>
492  struct VectorAssignHelper<false>
493  {
494  template<class To, class From>
495  static void doAssign(To& to, const From& from)
496  {
497  assign(to, from); // recurse
498  }
499  };
500  }
502 
503  template<class Vector, class Expr>
504  static inline
505  Vector& assign(Vector& v, const VectorExpression<Expr>& e_)
506  {
507  const Expr& e(e_.expression());
508  enum {
509  hasFieldElements =
510  std::is_same<typename Expr::ElementType, typename Expr::FieldType>::value
511  };
512 
513  for (unsigned i = 0; i < v.size(); ++i) {
514  VectorAssignHelper<hasFieldElements>::doAssign(v[i], e[i]);
515  }
516 
517  return v;
518  }
519 
521 
523 
524  } // namespace ACFem
525 
526 } // namespace Dune
527 
528 #endif // __DUNE_ACFEM_VECTOREXPRESSION_HH__
Binary vector expressions.
Definition: vectorexpression.hh:49
This is the only allowed starting point for vector-expressions: here we allow vectors to be wrapped i...
Definition: vectorexpression.hh:159
Unary vector expressions.
Definition: vectorexpression.hh:119
Tag structure, flag all these as ExpressionTemplates.
Definition: vectorexpression.hh:31
A list of supported expression operations as class-tags.
ParameterValue< Value >::ResultType parameterValue(const Value &value)
Return the unaltered argument for non-parameters and otherwise the parameter value.
Definition: parameterinterface.hh:263
BinaryParameterExpression< MultiplyOperation, Left, Right > operator*(const ParameterInterface< Left > &left, const ParameterInterface< Right > &right)
Scalar product between parameters.
Definition: parameterexpression.hh:321
static UnaryVectorExpression< IdentityOperation, Vector > asExpr(const Vector &arg)
Catch all starting point.
Definition: vectorexpression.hh:384
static Vector & operator-=(Vector &v, const BinaryVectorExpression< Op, Expr1, Expr2 > &e)
Minus-assignment to result vector.
Definition: vectorexpression.hh:451
static Vector & operator+=(Vector &v, const BinaryVectorExpression< Op, Expr1, Expr2 > &e)
Add-assignment to result vector.
Definition: vectorexpression.hh:425
Automatically deduce the type by applying the respective operation.
Definition: expressionoperations.hh:476
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
Identity, i.e. just wrap the object.
Definition: expressionoperations.hh:284
Multiplication by scalars from the left.
Definition: expressionoperations.hh:257
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)