Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
localoperators.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3
4// SPDX-FileCopyrightText: Copyright © DUNE-FUFEM Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#ifndef DUNE_FUFEM_FORMS_LOCALOPERATORS_HH
8#define DUNE_FUFEM_FORMS_LOCALOPERATORS_HH
9
10#include <cstddef>
11#include <type_traits>
12#include <utility>
13#include <array>
14
19
21
22
23
24// This namespace contains implementations of several local operators.
25// Here 'local' means that these operators are applied poinwise to
26// numbers, vectors, matrices, ... . The operators are implemented as non-templated
27// imutable classes that provide a templated or overloaded operator().
28// Some of the operations could be implemented as plain lambda functions,
29// but using named callbacks makes the expression trees much more readable
30// in error messages and allows to detect certain operators to provide
31// shortcuts for special cases.
33
34
35
36 struct SumOp {
37
38 template<class K1, class K2>
39 requires requires(K1& x, const K2& y) { x += y; }
40 static void addTo(K1& x, const K2& y)
41 {
42 x += y;
43 }
44
45 template<class K1, class K2, int n>
47 {
48 x += y;
49 }
50
51 template<class K1, class K2, int n, int m>
53 {
54 x += y;
55 }
56
57 template<class K1, class K2, int n>
59 {
60 x.scalar() += y.scalar();
61 }
62
63 template<class K1, class K2, int n>
65 {
66 for(std::size_t i=0; i<n; ++i)
67 x[i][i] += y.scalar();
68 }
69
70 template<class K1, class K2, int n>
72 {
73 for(std::size_t i=0; i<n; ++i)
74 x[i][0] += y[i];
75 }
76
77 template<class K1, class K2, int n>
79 {
80 for(std::size_t i=0; i<n; ++i)
81 x[0][i] += y[i];
82 }
83
84 template<class K1, class K2, int n>
86 {
87 for(std::size_t i=0; i<n; ++i)
88 x[i] += y[i][0];
89 }
90
91 template<class K1, class K2, int n>
93 {
94 for(std::size_t i=0; i<n; ++i)
95 x[i] += y[0][i];
96 }
97
98 template<class K1, class K2>
99 requires requires(const K1& x, const K2& y) { x + y; }
100 auto operator()(const K1& x, const K2& y) const
101 {
102 return x + y;
103 }
104
105 template<class K1, class K2, int n>
107 {
108 return x + y;
109 }
110
111 template<class K1, class K2, int n, int m>
113 {
114 return x + y;
115 }
116
117 template<class K1, class K2, int n>
123
124 template<class K1, class K2, int n>
126 {
128 auto z = Dune::FieldMatrix<K,n,1>(x);
129 for(std::size_t i=0; i<n; ++i)
130 z[i][0] += y[i];
131 return z;
132 }
133
134 template<class K1, class K2, int n>
136 {
138 auto z = Dune::FieldMatrix<K,1,n>(x);
139 for(std::size_t i=0; i<n; ++i)
140 z[0][i] += y[i];
141 return z;
142 }
143
144 template<class K1, class K2, int n>
146 {
147 return (*this)(y,x);
148 }
149
150 template<class K1, class K2, int n>
152 {
153 return (*this)(y,x);
154 }
155
156 template<class K1, class K2, int n>
158 {
160 auto z = Dune::FieldMatrix<K,n,n>(x);
161 addTo(z, y);
162 return z;
163 }
164
165 template<class K1, class K2, int n>
167 {
168 return (*this)(y,x);
169 }
170
171 template<class T1>
172 auto operator()(const T1& x0) const
173 {
174 return x0;
175 }
176
177 template<class T1, class T2, class T3, class... Ts>
178 auto operator()(const T1& x0, const T2& x1, const T3& x3, const Ts&... xs) const
179 requires requires { (*this)( (*this)(x0, x1), x3, xs...); }
180 {
181 return (*this)( (*this)(x0, x1), x3, xs...);
182 }
183
184 };
185
186
187
188 struct DotOp {
189
190 template<class K1, class K2, int n>
192 {
194 auto result = K(0);
195 for(std::size_t i=0; i<n; ++i)
196 result += x[i]*y[i];
197 return result;
198 }
199
200 template<class K1, class K2, int n, int m>
202 {
204 auto result = K(0);
205 for(std::size_t i=0; i<n; ++i)
206 for(std::size_t j=0; j<m; ++j)
207 result += x[i][j]*y[i][j];
208 return result;
209 }
210
211 template<class K1, class K2, int n, int m>
213 {
215 auto result = Dune::FieldVector<K,m>(0);
216 for(std::size_t i=0; i<n; ++i)
217 result += x[i]*y[i];
218 return result;
219 }
220
221 template<class K1, class K2, int n, int m>
223 {
225 auto result = Dune::FieldVector<K,m>(0);
226 for(std::size_t i=0; i<n; ++i)
227 result += y[i]*x[i];
228 return result;
229 }
230
231 template<class K1, class K2, int n>
233 {
235 auto result = K(0);
236 for(std::size_t i=0; i<x.N(); ++i)
237 result += y[i][i];
238 return x.scalar()*result;
239 }
240
241 template<class K1, class K2, int n>
243 {
245 auto result = K(0);
246 for(std::size_t i=0; i<x.N(); ++i)
247 result += x[i][i];
248 return result*y.scalar();
249 }
250
251 template<class K1, class K2, int n>
253 {
254 return n*x.scalar()*y.scalar();
255 }
256
257 template<class L, class R, long unsigned int n>
258 auto operator()(const std::array<L, n>& x, const std::array<R, n>& y) const
259 {
260 auto result = DotOp()(x[0], y[0]);
261 for(std::size_t i=1; i<n; ++i)
262 result += DotOp()(x[i], y[i]);
263 return result;
264 }
265
266 };
267
268 struct MultOp {
269
270 template<class X, class Y,
272 auto operator()(const X& x, const Y& y) const
273 {
274 return x*y;
275 }
276
277 template<class K1, class K2, int n, int m>
279 {
282 x.mv(y, result);
283 return result;
284 }
285
286 template<class K, class Y>
287 auto operator()(const Dune::FieldMatrix<K,1,1>& x, const Y& y) const
288 {
289 return x[0][0]*y;
290 }
291
292 template<class K, class Y>
293 auto operator()(const Dune::FieldVector<K,1>& x, const Y& y) const
294 {
295 return x[0]*y;
296 }
297
298 };
299
300
301
302 struct TransposeOp {
303 template<class K, int n, int m>
305 {
307 for(std::size_t i=0; i<x.N(); ++i)
308 for(std::size_t j=0; j<x.M(); ++j)
309 y[j][i] = x[i][j];
310 return y;
311 }
312 };
313
314
315
317 template<class K, int n>
319 {
320 if constexpr (n==2)
321 return Dune::FieldVector<K, 1>(J[1][0] - J[0][1]);
322 if constexpr (n==3)
323 return Dune::FieldVector<K, 3>({J[2][1] - J[1][2], J[0][2] - J[2][0], J[1][0] - J[0][1]});
324 }
325 };
326
327
328
329 struct SymOp {
330 template<class Matrix>
331 auto operator()(const Matrix& M) const
332 {
333 return 0.5*(M + M.transposed());
334 }
335 };
336
337
338
339 struct TraceOp {
340 template<class Matrix>
341 auto operator()(const Matrix& M) const
342 {
343 using T = std::decay_t<decltype(M[0][0])>;
344 T tr = 0;
345 for (auto k : Dune::range(M.N()))
346 tr += M[k][k];
347 return tr;
348 }
349 };
350
351
352
353 struct InvertOp {
354 template<class T,
355 class = std::void_t<decltype(1./std::declval<T>())>>
356 auto operator()(const T& t) const
357 {
358 return 1./t;
359 }
360 };
361
362
363
364 template<class Op>
366 {
367 public:
368 TransposedBinaryOp(const Op& op) : op_(op) {}
369
370 template<class X, class Y>
371 decltype(auto) operator()(X&& x, Y&& y) const
372 {
373 return op_(std::forward<Y>(y), std::forward<X>(x));
374 }
375
376 private:
377 Op op_;
378 };
379
380
381
382 template<class... Ops>
384
385 template<class OuterOp, class InnerOp>
386 class ComposedOp<OuterOp, InnerOp>
387 {
388 public:
389 ComposedOp(const OuterOp& outerOp, const InnerOp& innerOp) :
390 outerOp_(outerOp),
391 innerOp_(innerOp)
392 {}
393
394 template<class... Args>
395 decltype(auto) operator()(Args&&... args) const
396 {
397 return outerOp_(innerOp_(std::forward<Args>(args)...));
398 }
399
400 private:
401 OuterOp outerOp_;
402 InnerOp innerOp_;
403 };
404
405 template<class OuterOp, class InnerOp0, class InnerOp1, class... InnerOps>
406 class ComposedOp<OuterOp, InnerOp0, InnerOp1, InnerOps...>
407 {
408 using ComposedInnerOps = ComposedOp<InnerOp0, InnerOp1, InnerOps...>;
409 public:
410 ComposedOp(const OuterOp& outerOp, const InnerOp0& innerOp0, const InnerOp1& innerOp1, const InnerOps&... innerOps) :
411 outerOp_(outerOp),
412 innerOps_(innerOp0, innerOp1, innerOps...)
413 {}
414
415 ComposedOp(const OuterOp& outerOp, const ComposedInnerOps& innerOps) :
416 outerOp_(outerOp),
417 innerOps_(innerOps)
418 {}
419 template<class... Args>
420 decltype(auto) operator()(Args&&... args) const
421 {
422 return outerOp_(innerOps_(std::forward<Args>(args)...));
423 }
424
425 private:
426 OuterOp outerOp_;
427 ComposedInnerOps innerOps_;
428 };
429
430
431 template<class OuterOp, class InnerOp>
432 auto localCompose(const OuterOp& outerOp, const InnerOp& innerOp)
433 {
434 return ComposedOp<OuterOp, InnerOp>(outerOp, innerOp);
435 }
436
437 template<class OuterOp, class... InnerOps>
438 auto localCompose(const OuterOp& outerOp, const ComposedOp<InnerOps...>& innerOp)
439 {
440 return ComposedOp<OuterOp, InnerOps...>(outerOp, innerOp);
441 }
442
443 auto localCompose(const TraceOp& outerOp, const SymOp& innerOp)
444 {
445 return outerOp;
446 }
447
448 auto localCompose(const SymOp& outerOp, const TransposeOp& innerOp)
449 {
450 return outerOp;
451 }
452
453 auto localCompose(const TransposeOp& outerOp, const SymOp& innerOp)
454 {
455 return innerOp;
456 }
457
458
459
460
461} // namespace Dune::Fufem::Forms::LocalOperators
462
463
464
465#endif // DUNE_FUFEM_FORMS_LOCALOPERATORS_HH
static constexpr IntegralRange< std::decay_t< T > > range(T &&from, U &&to) noexcept
static constexpr size_type M()
Definition localoperators.hh:32
auto localCompose(const OuterOp &outerOp, const InnerOp &innerOp)
Definition localoperators.hh:432
constexpr size_type M() const
constexpr void mv(const X &x, Y &y) const
constexpr size_type N() const
decltype(std::declval< T1 >()+std::declval< T2 >()) PromotedType
const K & scalar() const
Definition localoperators.hh:36
static void addTo(Dune::FieldMatrix< K1, n, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y)
Definition localoperators.hh:64
static void addTo(Dune::FieldVector< K1, n > &x, const Dune::FieldVector< K2, n > &y)
Definition localoperators.hh:46
auto operator()(const Dune::FieldVector< K1, n > &x, const Dune::FieldVector< K2, n > &y) const
Definition localoperators.hh:106
auto operator()(const Dune::FieldMatrix< K1, n, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y) const
Definition localoperators.hh:157
static void addTo(Dune::FieldMatrix< K1, n, m > &x, const Dune::FieldMatrix< K2, n, m > &y)
Definition localoperators.hh:52
static void addTo(Dune::ScaledIdentityMatrix< K1, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y)
Definition localoperators.hh:58
auto operator()(const K1 &x, const K2 &y) const
Definition localoperators.hh:100
static void addTo(Dune::FieldMatrix< K1, n, 1 > &x, const Dune::FieldVector< K2, n > &y)
Definition localoperators.hh:71
auto operator()(const Dune::FieldVector< K1, n > &x, const Dune::FieldMatrix< K2, n, 1 > &y) const
Definition localoperators.hh:145
static void addTo(Dune::FieldMatrix< K1, 1, n > &x, const Dune::FieldVector< K2, n > &y)
Definition localoperators.hh:78
auto operator()(const T1 &x0, const T2 &x1, const T3 &x3, const Ts &... xs) const
Definition localoperators.hh:178
auto operator()(const Dune::FieldMatrix< K1, n, m > &x, const Dune::FieldMatrix< K2, n, m > &y) const
Definition localoperators.hh:112
auto operator()(const T1 &x0) const
Definition localoperators.hh:172
auto operator()(const Dune::FieldMatrix< K1, n, 1 > &x, const Dune::FieldVector< K2, n > &y) const
Definition localoperators.hh:125
auto operator()(const Dune::FieldVector< K1, n > &x, const Dune::FieldMatrix< K2, 1, n > &y) const
Definition localoperators.hh:151
static void addTo(Dune::FieldVector< K1, n > &x, const Dune::FieldMatrix< K2, 1, n > &y)
Definition localoperators.hh:92
auto operator()(const Dune::ScaledIdentityMatrix< K1, n > &x, const Dune::FieldMatrix< K2, n, n > &y) const
Definition localoperators.hh:166
static void addTo(Dune::FieldVector< K1, n > &x, const Dune::FieldMatrix< K2, n, 1 > &y)
Definition localoperators.hh:85
static void addTo(K1 &x, const K2 &y)
Definition localoperators.hh:40
auto operator()(const Dune::FieldMatrix< K1, 1, n > &x, const Dune::FieldVector< K2, n > &y) const
Definition localoperators.hh:135
auto operator()(const Dune::ScaledIdentityMatrix< K1, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y) const
Definition localoperators.hh:118
Definition localoperators.hh:188
auto operator()(const Dune::FieldVector< K1, n > &x, const Dune::FieldVector< K2, n > &y) const
Definition localoperators.hh:191
auto operator()(const Dune::ScaledIdentityMatrix< K1, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y) const
Definition localoperators.hh:252
auto operator()(const Dune::FieldMatrix< K1, n, m > &x, const Dune::FieldMatrix< K2, n, m > &y) const
Definition localoperators.hh:201
auto operator()(const Dune::FieldMatrix< K1, n, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y) const
Definition localoperators.hh:242
auto operator()(const std::array< L, n > &x, const std::array< R, n > &y) const
Definition localoperators.hh:258
auto operator()(const Dune::ScaledIdentityMatrix< K1, n > &x, const Dune::FieldMatrix< K2, n, n > &y) const
Definition localoperators.hh:232
auto operator()(const Dune::FieldMatrix< K1, n, m > &x, const Dune::FieldVector< K2, n > &y) const
Definition localoperators.hh:212
auto operator()(const Dune::FieldVector< K1, n > &x, const Dune::FieldMatrix< K2, n, m > &y) const
Definition localoperators.hh:222
Definition localoperators.hh:268
auto operator()(const Dune::FieldVector< K, 1 > &x, const Y &y) const
Definition localoperators.hh:293
auto operator()(const Dune::FieldMatrix< K1, n, m > &x, const Dune::FieldVector< K2, m > &y) const
Definition localoperators.hh:278
auto operator()(const Dune::FieldMatrix< K, 1, 1 > &x, const Y &y) const
Definition localoperators.hh:287
Definition localoperators.hh:302
auto operator()(const Dune::FieldMatrix< K, n, m > &x) const
Definition localoperators.hh:304
auto operator()(const Dune::FieldMatrix< K, n, n > &J) const
Definition localoperators.hh:318
Definition localoperators.hh:329
auto operator()(const Matrix &M) const
Definition localoperators.hh:331
Definition localoperators.hh:339
auto operator()(const Matrix &M) const
Definition localoperators.hh:341
Definition localoperators.hh:353
TransposedBinaryOp(const Op &op)
Definition localoperators.hh:368
Definition localoperators.hh:383
ComposedOp(const OuterOp &outerOp, const InnerOp &innerOp)
Definition localoperators.hh:389
ComposedOp(const OuterOp &outerOp, const InnerOp0 &innerOp0, const InnerOp1 &innerOp1, const InnerOps &... innerOps)
Definition localoperators.hh:410
ComposedOp(const OuterOp &outerOp, const ComposedInnerOps &innerOps)
Definition localoperators.hh:415
T forward(T... args)