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 <array>
11#include <cstddef>
12#include <tuple>
13#include <type_traits>
14#include <utility>
15
23
26
27
28
44
45
46 struct AssignOp {
47
48 template<class X, class Y>
49 requires requires(X& x, const Y& y) { x = y; }
50 void operator()(X& x, const Y& y) const
51 {
52 x = y;
53 }
54
55 template<class... Xi, class Y>
57 void operator()(std::tuple<Xi...>& x, const Y& y) const
58 {
59 return std::apply([&](auto&... xi) {
60 ((xi = y),...);
61 }, x);
62 }
63
64 };
65
66 struct SumOp {
67
68 template<class K1, class K2>
69 requires requires(K1 x, const K2 y) { x += y; }
70 static void addTo(K1& x, const K2& y)
71 {
72 x += y;
73 }
74
75 template<class K1, class K2, int n>
77 {
78 x += y;
79 }
80
81 template<class K1, class K2, int n, int m>
83 {
84 x += y;
85 }
86
87 template<class K1, class K2, int n>
89 {
90 x.scalar() += y.scalar();
91 }
92
93 template<class K1, class K2, int n>
95 {
96 for(std::size_t i=0; i<n; ++i)
97 x[i][i] += y.scalar();
98 }
99
100 template<class K1, class K2, int n>
102 {
103 for(std::size_t i=0; i<n; ++i)
104 x[i][0] += y[i];
105 }
106
107 template<class K1, class K2, int n>
109 {
110 for(std::size_t i=0; i<n; ++i)
111 x[0][i] += y[i];
112 }
113
114 template<class K1, class K2, int n>
116 {
117 for(std::size_t i=0; i<n; ++i)
118 x[i] += y[i][0];
119 }
120
121 template<class K1, class K2, int n>
123 {
124 for(std::size_t i=0; i<n; ++i)
125 x[i] += y[0][i];
126 }
127
128 template<class... Xi, class... Yi>
129 requires(sizeof...(Xi) == sizeof...(Yi))
130 static void addTo(std::tuple<Xi...>& x, const std::tuple<Yi...>& y)
131 {
132 constexpr auto indices = std::index_sequence_for<Xi...>{};
133 Dune::unpackIntegerSequence([&](auto... i) {
134 ((std::get<i>(x) += std::get<i>(y)),...);
135 }, indices);
136 }
137
138 template<class K1, class K2>
139 requires requires(const K1& x, const K2& y) { x + y; }
140 auto operator()(const K1& x, const K2& y) const
141 {
142 return x + y;
143 }
144
145 template<class K1, class K2, int n>
147 {
148 return x + y;
149 }
150
151 template<class K1, class K2, int n, int m>
153 {
154 return x + y;
155 }
156
157 template<class K1, class K2, int n>
163
164 template<class K1, class K2, int n>
166 {
168 auto z = Dune::FieldMatrix<K,n,1>(x);
169 for(std::size_t i=0; i<n; ++i)
170 z[i][0] += y[i];
171 return z;
172 }
173
174 template<class K1, class K2, int n>
176 {
178 auto z = Dune::FieldMatrix<K,1,n>(x);
179 for(std::size_t i=0; i<n; ++i)
180 z[0][i] += y[i];
181 return z;
182 }
183
184 template<class K1, class K2, int n>
186 {
187 return (*this)(y,x);
188 }
189
190 template<class K1, class K2, int n>
192 {
193 return (*this)(y,x);
194 }
195
196 template<class K1, class K2, int n>
198 {
200 auto z = Dune::FieldMatrix<K,n,n>(x);
201 addTo(z, y);
202 return z;
203 }
204
205 template<class K1, class K2, int n>
207 {
208 return (*this)(y,x);
209 }
210
211 template<class T1>
212 auto operator()(const T1& x0) const
213 {
214 return x0;
215 }
216
217 template<class T1, class T2, class T3, class... Ts>
218 requires requires(SumOp sumOp, const T1 x1, const T2 x2, const T3 x3, const Ts... xs) { sumOp( sumOp(x1, x2), x3, xs...); }
219 auto operator()(const T1& x1, const T2& x2, const T3& x3, const Ts&... xs) const
220 {
221 return (*this)( (*this)(x1, x2), x3, xs...);
222 }
223
224 template<class... L, class... R>
225 requires(sizeof...(L) == sizeof...(R))
226 auto operator()(const Dune::MultiTypeBlockVector<L...>& x, const Dune::MultiTypeBlockVector<R...>& y) const
227 {
228 constexpr auto indices = std::index_sequence_for<L...>{};
230 return Dune::unpackIntegerSequence([&](auto... i) {
231 return Z((*this)(x[i],y[i]) ...);
232 }, indices);
233 }
234
235 template<class... Xi, class... Yi>
236 requires(sizeof...(Xi) == sizeof...(Yi))
237 auto operator()(const Dune::TupleVector<Xi...>& x, const Dune::TupleVector<Yi...>& y) const
238 {
239 constexpr auto indices = std::index_sequence_for<Xi...>{};
241 return Dune::unpackIntegerSequence([&](auto... i) {
242 return Z((*this)(x[i],y[i]) ...);
243 }, indices);
244 }
245
246 };
247
248
249
250 struct DotOp {
251
252 template<class K1, class K2, int n>
254 {
256 auto result = K(0);
257 for(std::size_t i=0; i<n; ++i)
258 result += x[i]*y[i];
259 return result;
260 }
261
262 template<class K1, class K2, int n, int m>
264 {
266 auto result = K(0);
267 for(std::size_t i=0; i<n; ++i)
268 for(std::size_t j=0; j<m; ++j)
269 result += x[i][j]*y[i][j];
270 return result;
271 }
272
273 template<class K1, class K2, int n, int m>
275 {
277 auto result = Dune::FieldVector<K,m>(0);
278 for(std::size_t i=0; i<n; ++i)
279 result += x[i]*y[i];
280 return result;
281 }
282
283 template<class K1, class K2, int n, int m>
285 {
287 auto result = Dune::FieldVector<K,m>(0);
288 for(std::size_t i=0; i<n; ++i)
289 result += y[i]*x[i];
290 return result;
291 }
292
293 template<class K1, class K2, int n>
295 {
297 auto result = K(0);
298 for(std::size_t i=0; i<x.N(); ++i)
299 result += y[i][i];
300 return x.scalar()*result;
301 }
302
303 template<class K1, class K2, int n>
305 {
307 auto result = K(0);
308 for(std::size_t i=0; i<x.N(); ++i)
309 result += x[i][i];
310 return result*y.scalar();
311 }
312
313 template<class K1, class K2, int n>
315 {
316 return n*x.scalar()*y.scalar();
317 }
318
319 template<class L, class R, long unsigned int n>
320 auto operator()(const std::array<L, n>& x, const std::array<R, n>& y) const
321 {
322 auto result = DotOp()(x[0], y[0]);
323 for(std::size_t i=1; i<n; ++i)
324 result += DotOp()(x[i], y[i]);
325 return result;
326 }
327
328 template<class... L, class... R>
329 requires(sizeof...(L) == sizeof...(R))
330 auto operator()(const std::tuple<L...>& x, const std::tuple<R...>& y) const
331 {
332 constexpr auto indices = std::index_sequence_for<L...>{};
333 return Dune::unpackIntegerSequence([&](auto... i) {
334 auto dot = DotOp();
335 return (dot(std::get<i>(x), std::get<i>(y)) + ...);
336 }, indices);
337 }
338
339 };
340
341 struct MultOp {
342
343 template<class X, class Y>
344 requires requires(const X x, const Y y) { x*y; }
345 auto operator()(const X& x, const Y& y) const
346 {
347 return x*y;
348 }
349
350 template<class K1, class K2, int n, int m>
352 {
355 x.mv(y, result);
356 return result;
357 }
358
359 template<class K, class Y>
360 auto operator()(const Dune::FieldMatrix<K,1,1>& x, const Y& y) const
361 {
362 return x*y;
363 }
364
365 template<class K, class Y>
366 auto operator()(const Dune::FieldVector<K,1>& x, const Y& y) const
367 {
368 return x*y;
369 }
370
371 template<class X, class... Yi>
373 auto operator()(const X& x, const Dune::TupleVector<Yi...>& y) const
374 {
375 constexpr auto indices = std::index_sequence_for<Yi...>{};
377 return Dune::unpackIntegerSequence([&](auto... i) {
378 return Z(x*y[i] ...);
379 }, indices);
380 }
381
382 template<class... Xi, class Y>
384 auto operator()(const Dune::TupleVector<Xi...>& x, const Y& y) const
385 {
386 constexpr auto indices = std::index_sequence_for<Xi...>{};
388 return Dune::unpackIntegerSequence([&](auto... i) {
389 return Z(x[i]*y ...);
390 }, indices);
391 }
392
393 template<class X, class... Yi>
395 auto operator()(const X& x, const Dune::MultiTypeBlockVector<Yi...>& y) const
396 {
397 constexpr auto indices = std::index_sequence_for<Yi...>{};
399 return Dune::unpackIntegerSequence([&](auto... i) {
400 return Z(x*y[i] ...);
401 }, indices);
402 }
403
404 template<class... Xi, class Y>
406 auto operator()(const Dune::MultiTypeBlockVector<Xi...>& x, const Y& y) const
407 {
408 constexpr auto indices = std::index_sequence_for<Xi...>{};
410 return Dune::unpackIntegerSequence([&](auto... i) {
411 return Z(x[i]*y ...);
412 }, indices);
413 }
414
415 };
416
417
418
419 struct TransposeOp {
420 template<class K, int n, int m>
422 {
424 for(std::size_t i=0; i<x.N(); ++i)
425 for(std::size_t j=0; j<x.M(); ++j)
426 y[j][i] = x[i][j];
427 return y;
428 }
429 };
430
431
432
434 template<class K, int n>
436 {
437 if constexpr (n==2)
438 return Dune::FieldVector<K, 1>(J[1][0] - J[0][1]);
439 if constexpr (n==3)
440 return Dune::FieldVector<K, 3>({J[2][1] - J[1][2], J[0][2] - J[2][0], J[1][0] - J[0][1]});
441 }
442 };
443
444
445
446 struct SymOp {
447 template<class Matrix>
448 auto operator()(const Matrix& M) const
449 {
450 return 0.5*(M + M.transposed());
451 }
452 };
453
454
455
456 struct TraceOp {
457 template<class Matrix>
458 auto operator()(const Matrix& M) const
459 {
460 using T = std::decay_t<decltype(M[0][0])>;
461 T tr = 0;
462 for (auto k : Dune::range(M.N()))
463 tr += M[k][k];
464 return tr;
465 }
466 };
467
468
469
470 struct InvertOp {
471 template<class T>
472 requires requires(const T t) { 1./t; }
473 auto operator()(const T& t) const
474 {
475 return 1./t;
476 }
477 };
478
479
480
481 template<class Op>
483 {
484 public:
485 TransposedBinaryOp(const Op& op) : op_(op) {}
486
487 template<class X, class Y>
488 decltype(auto) operator()(X&& x, Y&& y) const
489 {
490 return op_(std::forward<Y>(y), std::forward<X>(x));
491 }
492
493 private:
494 Op op_;
495 };
496
497
498
499 template<class... Ops>
501
502 template<class OuterOp, class InnerOp>
503 class ComposedOp<OuterOp, InnerOp>
504 {
505 public:
506 ComposedOp(const OuterOp& outerOp, const InnerOp& innerOp) :
507 outerOp_(outerOp),
508 innerOp_(innerOp)
509 {}
510
511 template<class... Args>
512 decltype(auto) operator()(Args&&... args) const
513 {
514 return outerOp_(innerOp_(std::forward<Args>(args)...));
515 }
516
517 private:
518 OuterOp outerOp_;
519 InnerOp innerOp_;
520 };
521
522 template<class OuterOp, class InnerOp0, class InnerOp1, class... InnerOps>
523 class ComposedOp<OuterOp, InnerOp0, InnerOp1, InnerOps...>
524 {
525 using ComposedInnerOps = ComposedOp<InnerOp0, InnerOp1, InnerOps...>;
526 public:
527 ComposedOp(const OuterOp& outerOp, const InnerOp0& innerOp0, const InnerOp1& innerOp1, const InnerOps&... innerOps) :
528 outerOp_(outerOp),
529 innerOps_(innerOp0, innerOp1, innerOps...)
530 {}
531
532 ComposedOp(const OuterOp& outerOp, const ComposedInnerOps& innerOps) :
533 outerOp_(outerOp),
534 innerOps_(innerOps)
535 {}
536 template<class... Args>
537 decltype(auto) operator()(Args&&... args) const
538 {
539 return outerOp_(innerOps_(std::forward<Args>(args)...));
540 }
541
542 private:
543 OuterOp outerOp_;
544 ComposedInnerOps innerOps_;
545 };
546
547
548 template<class OuterOp, class InnerOp>
549 auto localCompose(const OuterOp& outerOp, const InnerOp& innerOp)
550 {
551 return ComposedOp<OuterOp, InnerOp>(outerOp, innerOp);
552 }
553
554 template<class OuterOp, class... InnerOps>
555 auto localCompose(const OuterOp& outerOp, const ComposedOp<InnerOps...>& innerOp)
556 {
557 return ComposedOp<OuterOp, InnerOps...>(outerOp, innerOp);
558 }
559
560 auto localCompose(const TraceOp& outerOp, const SymOp& innerOp)
561 {
562 return outerOp;
563 }
564
565 auto localCompose(const SymOp& outerOp, const TransposeOp& innerOp)
566 {
567 return outerOp;
568 }
569
570 auto localCompose(const TransposeOp& outerOp, const SymOp& innerOp)
571 {
572 return innerOp;
573 }
574
575
576
577
578} // namespace Dune::Fufem::Forms::LocalOperators
579
580
581
582#endif // DUNE_FUFEM_FORMS_LOCALOPERATORS_HH
static constexpr IntegralRange< T > range(T from, T to) noexcept
decltype(auto) constexpr unpackIntegerSequence(F &&f, std::integer_sequence< I, i... > sequence)
static constexpr size_type M()
auto dot(const L &l, const R &r)
Exterior product of two multilinear operators based on pointwise dot-product.
Definition userfunctions.hh:458
Namespace containing algebraic operator implementations.
Definition localoperators.hh:43
auto localCompose(const OuterOp &outerOp, const InnerOp &innerOp)
Definition localoperators.hh:549
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:46
void operator()(X &x, const Y &y) const
Definition localoperators.hh:50
Definition localoperators.hh:66
static void addTo(Dune::FieldMatrix< K1, n, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y)
Definition localoperators.hh:94
static void addTo(Dune::FieldVector< K1, n > &x, const Dune::FieldVector< K2, n > &y)
Definition localoperators.hh:76
auto operator()(const T1 &x1, const T2 &x2, const T3 &x3, const Ts &... xs) const
Definition localoperators.hh:219
auto operator()(const Dune::FieldVector< K1, n > &x, const Dune::FieldVector< K2, n > &y) const
Definition localoperators.hh:146
auto operator()(const Dune::FieldMatrix< K1, n, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y) const
Definition localoperators.hh:197
static void addTo(std::tuple< Xi... > &x, const std::tuple< Yi... > &y)
Definition localoperators.hh:130
static void addTo(Dune::FieldMatrix< K1, n, m > &x, const Dune::FieldMatrix< K2, n, m > &y)
Definition localoperators.hh:82
static void addTo(Dune::ScaledIdentityMatrix< K1, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y)
Definition localoperators.hh:88
auto operator()(const K1 &x, const K2 &y) const
Definition localoperators.hh:140
static void addTo(Dune::FieldMatrix< K1, n, 1 > &x, const Dune::FieldVector< K2, n > &y)
Definition localoperators.hh:101
auto operator()(const Dune::FieldVector< K1, n > &x, const Dune::FieldMatrix< K2, n, 1 > &y) const
Definition localoperators.hh:185
static void addTo(Dune::FieldMatrix< K1, 1, n > &x, const Dune::FieldVector< K2, n > &y)
Definition localoperators.hh:108
auto operator()(const Dune::FieldMatrix< K1, n, m > &x, const Dune::FieldMatrix< K2, n, m > &y) const
Definition localoperators.hh:152
auto operator()(const T1 &x0) const
Definition localoperators.hh:212
auto operator()(const Dune::FieldMatrix< K1, n, 1 > &x, const Dune::FieldVector< K2, n > &y) const
Definition localoperators.hh:165
auto operator()(const Dune::FieldVector< K1, n > &x, const Dune::FieldMatrix< K2, 1, n > &y) const
Definition localoperators.hh:191
static void addTo(Dune::FieldVector< K1, n > &x, const Dune::FieldMatrix< K2, 1, n > &y)
Definition localoperators.hh:122
auto operator()(const Dune::ScaledIdentityMatrix< K1, n > &x, const Dune::FieldMatrix< K2, n, n > &y) const
Definition localoperators.hh:206
static void addTo(K1 &x, const K2 &y)
Definition localoperators.hh:70
static void addTo(Dune::FieldVector< K1, n > &x, const Dune::FieldMatrix< K2, n, 1 > &y)
Definition localoperators.hh:115
auto operator()(const Dune::FieldMatrix< K1, 1, n > &x, const Dune::FieldVector< K2, n > &y) const
Definition localoperators.hh:175
auto operator()(const Dune::ScaledIdentityMatrix< K1, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y) const
Definition localoperators.hh:158
Definition localoperators.hh:250
auto operator()(const Dune::FieldVector< K1, n > &x, const Dune::FieldVector< K2, n > &y) const
Definition localoperators.hh:253
auto operator()(const Dune::ScaledIdentityMatrix< K1, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y) const
Definition localoperators.hh:314
auto operator()(const Dune::FieldMatrix< K1, n, m > &x, const Dune::FieldMatrix< K2, n, m > &y) const
Definition localoperators.hh:263
auto operator()(const Dune::FieldMatrix< K1, n, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y) const
Definition localoperators.hh:304
auto operator()(const std::array< L, n > &x, const std::array< R, n > &y) const
Definition localoperators.hh:320
auto operator()(const Dune::ScaledIdentityMatrix< K1, n > &x, const Dune::FieldMatrix< K2, n, n > &y) const
Definition localoperators.hh:294
auto operator()(const Dune::FieldMatrix< K1, n, m > &x, const Dune::FieldVector< K2, n > &y) const
Definition localoperators.hh:274
auto operator()(const Dune::FieldVector< K1, n > &x, const Dune::FieldMatrix< K2, n, m > &y) const
Definition localoperators.hh:284
Definition localoperators.hh:341
auto operator()(const Dune::FieldVector< K, 1 > &x, const Y &y) const
Definition localoperators.hh:366
auto operator()(const Dune::FieldMatrix< K1, n, m > &x, const Dune::FieldVector< K2, m > &y) const
Definition localoperators.hh:351
auto operator()(const Dune::FieldMatrix< K, 1, 1 > &x, const Y &y) const
Definition localoperators.hh:360
auto operator()(const X &x, const Y &y) const
Definition localoperators.hh:345
Definition localoperators.hh:419
auto operator()(const Dune::FieldMatrix< K, n, m > &x) const
Definition localoperators.hh:421
auto operator()(const Dune::FieldMatrix< K, n, n > &J) const
Definition localoperators.hh:435
Definition localoperators.hh:446
auto operator()(const Matrix &M) const
Definition localoperators.hh:448
Definition localoperators.hh:456
auto operator()(const Matrix &M) const
Definition localoperators.hh:458
Definition localoperators.hh:470
auto operator()(const T &t) const
Definition localoperators.hh:473
TransposedBinaryOp(const Op &op)
Definition localoperators.hh:485
Definition localoperators.hh:500
ComposedOp(const OuterOp &outerOp, const InnerOp &innerOp)
Definition localoperators.hh:506
ComposedOp(const OuterOp &outerOp, const InnerOp0 &innerOp0, const InnerOp1 &innerOp1, const InnerOps &... innerOps)
Definition localoperators.hh:527
ComposedOp(const OuterOp &outerOp, const ComposedInnerOps &innerOps)
Definition localoperators.hh:532
T apply(T... args)
T forward(T... args)