DUNE-ACFEM (2.5.1)

vectorexpression.hh
1#ifndef __DUNE_ACFEM_VECTOREXPRESSION_HH__
2#define __DUNE_ACFEM_VECTOREXPRESSION_HH__
3
5
6namespace 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])>
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])>
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 {
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 {
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 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
static UnaryVectorExpression< IdentityOperation, Vector > asExpr(const Vector &arg)
Catch all starting point.
Definition: vectorexpression.hh:384
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.111.3 (Nov 12, 23:30, 2024)