Dune-Fufem 2.11
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>
77 static void addTo(K1& x, const Dune::FieldVector<K2,1>& y)
78 {
79 x += y[0];
80 }
81
82 template<class K1, class K2>
84 static void addTo(Dune::FieldVector<K1,1>& x, const K2& y)
85 {
86 x[0] += y;
87 }
88
89 template<class K1, class K2, int n>
91 {
92 x += y;
93 }
94
95 template<class K1, class K2, int n, int m>
97 {
98 x += y;
99 }
100
101 template<class K1, class K2, int n>
103 {
104 x.scalar() += y.scalar();
105 }
106
107 template<class K1, class K2, int n>
109 {
110 for(std::size_t i=0; i<n; ++i)
111 x[i][i] += y.scalar();
112 }
113
114 template<class K1, class K2, int n>
116 {
117 for(std::size_t i=0; i<n; ++i)
118 x[i][0] += y[i];
119 }
120
121 template<class K1, class K2, int n>
123 {
124 for(std::size_t i=0; i<n; ++i)
125 x[0][i] += y[i];
126 }
127
128 template<class K1, class K2, int n>
130 {
131 for(std::size_t i=0; i<n; ++i)
132 x[i] += y[i][0];
133 }
134
135 template<class K1, class K2, int n>
137 {
138 for(std::size_t i=0; i<n; ++i)
139 x[i] += y[0][i];
140 }
141
142 template<class... Xi, class... Yi>
143 requires(sizeof...(Xi) == sizeof...(Yi))
144 static void addTo(std::tuple<Xi...>& x, const std::tuple<Yi...>& y)
145 {
146 constexpr auto indices = std::index_sequence_for<Xi...>{};
147 Dune::unpackIntegerSequence([&](auto... i) {
148 ((std::get<i>(x) += std::get<i>(y)),...);
149 }, indices);
150 }
151
152 template<class K1, class K2>
153 requires requires(const K1& x, const K2& y) { x + y; }
154 auto operator()(const K1& x, const K2& y) const
155 {
156 return x + y;
157 }
158
159 template<class K1, class K2>
161 auto operator()(const K1& x, const Dune::FieldVector<K2,1>& y) const
162 {
163 return x + y[0];
164 }
165
166 template<class K1, class K2>
168 auto operator()(const Dune::FieldVector<K1,1>& x, const K2& y) const
169 {
170 return x[0] + y;
171 }
172
173 template<class K1, class K2, int n>
175 {
176 return x + y;
177 }
178
179 template<class K1, class K2, int n, int m>
181 {
182 return x + y;
183 }
184
185 template<class K1, class K2, int n>
187 {
190 }
191
192 template<class K1, class K2, int n>
194 {
196 auto z = Dune::FieldMatrix<K,n,1>(x);
197 for(std::size_t i=0; i<n; ++i)
198 z[i][0] += y[i];
199 return z;
200 }
201
202 template<class K1, class K2, int n>
204 {
206 auto z = Dune::FieldMatrix<K,1,n>(x);
207 for(std::size_t i=0; i<n; ++i)
208 z[0][i] += y[i];
209 return z;
210 }
211
212 template<class K1, class K2, int n>
214 {
215 return (*this)(y,x);
216 }
217
218 template<class K1, class K2, int n>
220 {
221 return (*this)(y,x);
222 }
223
224 template<class K1, class K2, int n>
226 {
228 auto z = Dune::FieldMatrix<K,n,n>(x);
229 addTo(z, y);
230 return z;
231 }
232
233 template<class K1, class K2, int n>
235 {
236 return (*this)(y,x);
237 }
238
239 template<class T1>
240 auto operator()(const T1& x0) const
241 {
242 return x0;
243 }
244
245 template<class T1, class T2, class T3, class... Ts>
246 requires requires(SumOp sumOp, const T1 x1, const T2 x2, const T3 x3, const Ts... xs) { sumOp( sumOp(x1, x2), x3, xs...); }
247 auto operator()(const T1& x1, const T2& x2, const T3& x3, const Ts&... xs) const
248 {
249 return (*this)( (*this)(x1, x2), x3, xs...);
250 }
251
252 template<class... L, class... R>
253 requires(sizeof...(L) == sizeof...(R))
254 auto operator()(const Dune::MultiTypeBlockVector<L...>& x, const Dune::MultiTypeBlockVector<R...>& y) const
255 {
256 constexpr auto indices = std::index_sequence_for<L...>{};
258 return Dune::unpackIntegerSequence([&](auto... i) {
259 return Z((*this)(x[i],y[i]) ...);
260 }, indices);
261 }
262
263 template<class... Xi, class... Yi>
264 requires(sizeof...(Xi) == sizeof...(Yi))
265 auto operator()(const Dune::TupleVector<Xi...>& x, const Dune::TupleVector<Yi...>& y) const
266 {
267 constexpr auto indices = std::index_sequence_for<Xi...>{};
269 return Dune::unpackIntegerSequence([&](auto... i) {
270 return Z((*this)(x[i],y[i]) ...);
271 }, indices);
272 }
273
274 };
275
276
277
278 struct DotOp {
279
280 template<class K1, class K2>
282 auto operator()(const Dune::FieldVector<K1,1>& x, const K2& y) const
283 {
284 return x[0]*y;
285 }
286
287 template<class K1, class K2>
289 auto operator()(const K1& x, const Dune::FieldVector<K2,1>& y) const
290 {
291 return x*y[0];
292 }
293
294 template<class K1, class K2>
296 auto operator()(const Dune::FieldMatrix<K1,1,1>& x, const K2& y) const
297 {
298 return x[0][0]*y;
299 }
300
301 template<class K1, class K2>
303 auto operator()(const K1& x, const Dune::FieldMatrix<K2,1,1>& y) const
304 {
305 return x*y[0][0];
306 }
307
308 template<class K1, class K2, int n>
310 {
312 auto result = K(0);
313 for(std::size_t i=0; i<n; ++i)
314 result += x[i]*y[i];
315 return result;
316 }
317
318 template<class K1, class K2, int n, int m>
320 {
322 auto result = K(0);
323 for(std::size_t i=0; i<n; ++i)
324 for(std::size_t j=0; j<m; ++j)
325 result += x[i][j]*y[i][j];
326 return result;
327 }
328
329 template<class K1, class K2, int n, int m>
331 {
333 auto result = Dune::FieldVector<K,m>(0);
334 for(std::size_t i=0; i<n; ++i)
335 result += x[i]*y[i];
336 return result;
337 }
338
339 template<class K1, class K2, int n, int m>
341 {
343 auto result = Dune::FieldVector<K,m>(0);
344 for(std::size_t i=0; i<n; ++i)
345 result += y[i]*x[i];
346 return result;
347 }
348
349 template<class K1, class K2, int n>
351 {
353 auto result = K(0);
354 for(std::size_t i=0; i<x.N(); ++i)
355 result += y[i][i];
356 return x.scalar()*result;
357 }
358
359 template<class K1, class K2, int n>
361 {
363 auto result = K(0);
364 for(std::size_t i=0; i<x.N(); ++i)
365 result += x[i][i];
366 return result*y.scalar();
367 }
368
369 template<class K1, class K2, int n>
371 {
372 return n*x.scalar()*y.scalar();
373 }
374
375 template<class L, class R, long unsigned int n>
376 auto operator()(const std::array<L, n>& x, const std::array<R, n>& y) const
377 {
378 auto result = DotOp()(x[0], y[0]);
379 for(std::size_t i=1; i<n; ++i)
380 result += DotOp()(x[i], y[i]);
381 return result;
382 }
383
384 template<class... L, class... R>
385 requires(sizeof...(L) == sizeof...(R))
386 auto operator()(const std::tuple<L...>& x, const std::tuple<R...>& y) const
387 {
388 constexpr auto indices = std::index_sequence_for<L...>{};
389 return Dune::unpackIntegerSequence([&](auto... i) {
390 auto dot = DotOp();
391 return (dot(std::get<i>(x), std::get<i>(y)) + ...);
392 }, indices);
393 }
394
395 };
396
397 struct MultOp {
398
399 template<class X, class Y>
400 requires requires(const X x, const Y y) { x*y; }
401 auto operator()(const X& x, const Y& y) const
402 {
403 return x*y;
404 }
405
406 template<class K1, class K2, int n, int m>
408 {
411 x.mv(y, result);
412 return result;
413 }
414
415 template<class K, class Y>
416 auto operator()(const Dune::FieldVector<K,1>& x, const Y& y) const
417 {
418 return x[0]*y;
419 }
420
421 template<class X, class K>
422 auto operator()(const X& x, Dune::FieldVector<K,1>& y) const
423 {
424 return x*y[0];
425 }
426
427 template<class K, class Y>
428 auto operator()(const Dune::FieldMatrix<K,1,1>& x, const Y& y) const
429 {
430 return x[0][0]*y;
431 }
432
433 template<class X, class K>
434 auto operator()(const X& x, Dune::FieldMatrix<K,1,1>& y) const
435 {
436 return x*y[0][0];
437 }
438
439 template<class X, class... Yi>
441 auto operator()(const X& x, const Dune::TupleVector<Yi...>& y) const
442 {
443 constexpr auto indices = std::index_sequence_for<Yi...>{};
445 return Dune::unpackIntegerSequence([&](auto... i) {
446 return Z(x*y[i] ...);
447 }, indices);
448 }
449
450 template<class... Xi, class Y>
452 auto operator()(const Dune::TupleVector<Xi...>& x, const Y& y) const
453 {
454 constexpr auto indices = std::index_sequence_for<Xi...>{};
456 return Dune::unpackIntegerSequence([&](auto... i) {
457 return Z(x[i]*y ...);
458 }, indices);
459 }
460
461 template<class X, class... Yi>
463 auto operator()(const X& x, const Dune::MultiTypeBlockVector<Yi...>& y) const
464 {
465 constexpr auto indices = std::index_sequence_for<Yi...>{};
467 return Dune::unpackIntegerSequence([&](auto... i) {
468 return Z(x*y[i] ...);
469 }, indices);
470 }
471
472 template<class... Xi, class Y>
474 auto operator()(const Dune::MultiTypeBlockVector<Xi...>& x, const Y& y) const
475 {
476 constexpr auto indices = std::index_sequence_for<Xi...>{};
478 return Dune::unpackIntegerSequence([&](auto... i) {
479 return Z(x[i]*y ...);
480 }, indices);
481 }
482
483 };
484
485
486
487 struct TransposeOp {
488 template<class K, int n, int m>
490 {
492 for(std::size_t i=0; i<x.N(); ++i)
493 for(std::size_t j=0; j<x.M(); ++j)
494 y[j][i] = x[i][j];
495 return y;
496 }
497 };
498
499
500
502 template<class K, int n>
504 {
505 if constexpr (n==2)
506 return Dune::FieldVector<K, 1>(J[1][0] - J[0][1]);
507 if constexpr (n==3)
508 return Dune::FieldVector<K, 3>({J[2][1] - J[1][2], J[0][2] - J[2][0], J[1][0] - J[0][1]});
509 }
510 };
511
512
513
514 struct SymOp {
515 template<class Matrix>
516 auto operator()(const Matrix& M) const
517 {
518 return 0.5*(M + M.transposed());
519 }
520 };
521
522
523
524 struct TraceOp {
525 template<class Matrix>
526 auto operator()(const Matrix& M) const
527 {
528 using T = std::decay_t<decltype(M[0][0])>;
529 T tr = 0;
530 for (auto k : Dune::range(M.N()))
531 tr += M[k][k];
532 return tr;
533 }
534 };
535
536
537
538 struct InvertOp {
539 template<class T>
540 requires requires(const T t) { 1./t; }
541 auto operator()(const T& t) const
542 {
543 return 1./t;
544 }
545 };
546
547
548
549 template<class Op>
551 {
552 public:
553 TransposedBinaryOp(const Op& op) : op_(op) {}
554
555 template<class X, class Y>
556 decltype(auto) operator()(X&& x, Y&& y) const
557 {
558 return op_(std::forward<Y>(y), std::forward<X>(x));
559 }
560
561 private:
562 Op op_;
563 };
564
565
566
567 template<class... Ops>
569
570 template<class OuterOp, class InnerOp>
571 class ComposedOp<OuterOp, InnerOp>
572 {
573 public:
574 ComposedOp(const OuterOp& outerOp, const InnerOp& innerOp) :
575 outerOp_(outerOp),
576 innerOp_(innerOp)
577 {}
578
579 template<class... Args>
580 decltype(auto) operator()(Args&&... args) const
581 {
582 return outerOp_(innerOp_(std::forward<Args>(args)...));
583 }
584
585 private:
586 OuterOp outerOp_;
587 InnerOp innerOp_;
588 };
589
590 template<class OuterOp, class InnerOp0, class InnerOp1, class... InnerOps>
591 class ComposedOp<OuterOp, InnerOp0, InnerOp1, InnerOps...>
592 {
593 using ComposedInnerOps = ComposedOp<InnerOp0, InnerOp1, InnerOps...>;
594 public:
595 ComposedOp(const OuterOp& outerOp, const InnerOp0& innerOp0, const InnerOp1& innerOp1, const InnerOps&... innerOps) :
596 outerOp_(outerOp),
597 innerOps_(innerOp0, innerOp1, innerOps...)
598 {}
599
600 ComposedOp(const OuterOp& outerOp, const ComposedInnerOps& innerOps) :
601 outerOp_(outerOp),
602 innerOps_(innerOps)
603 {}
604 template<class... Args>
605 decltype(auto) operator()(Args&&... args) const
606 {
607 return outerOp_(innerOps_(std::forward<Args>(args)...));
608 }
609
610 private:
611 OuterOp outerOp_;
612 ComposedInnerOps innerOps_;
613 };
614
615
616 template<class OuterOp, class InnerOp>
617 auto localCompose(const OuterOp& outerOp, const InnerOp& innerOp)
618 {
619 return ComposedOp<OuterOp, InnerOp>(outerOp, innerOp);
620 }
621
622 template<class OuterOp, class... InnerOps>
623 auto localCompose(const OuterOp& outerOp, const ComposedOp<InnerOps...>& innerOp)
624 {
625 return ComposedOp<OuterOp, InnerOps...>(outerOp, innerOp);
626 }
627
628 auto localCompose(const TraceOp& outerOp, const SymOp& innerOp)
629 {
630 return outerOp;
631 }
632
633 auto localCompose(const SymOp& outerOp, const TransposeOp& innerOp)
634 {
635 return outerOp;
636 }
637
638 auto localCompose(const TransposeOp& outerOp, const SymOp& innerOp)
639 {
640 return innerOp;
641 }
642
643
644
645
646} // namespace Dune::Fufem::Forms::LocalOperators
647
648
649
650#endif // DUNE_FUFEM_FORMS_LOCALOPERATORS_HH
decltype(auto) constexpr unpackIntegerSequence(F &&f, std::integer_sequence< I, i... > sequence)
static constexpr IntegralRange< std::decay_t< T > > range(T &&from, U &&to) noexcept
static constexpr size_type M()
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
T apply(T... args)
ComposedOp(const OuterOp &outerOp, const InnerOp0 &innerOp0, const InnerOp1 &innerOp1, const InnerOps &... innerOps)
Definition localoperators.hh:595
ComposedOp(const OuterOp &outerOp, const ComposedInnerOps &innerOps)
Definition localoperators.hh:600
ComposedOp(const OuterOp &outerOp, const InnerOp &innerOp)
Definition localoperators.hh:574
Definition localoperators.hh:568
TransposedBinaryOp(const Op &op)
Definition localoperators.hh:553
T forward(T... args)
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:617
Definition localoperators.hh:46
void operator()(X &x, const Y &y) const
Definition localoperators.hh:50
auto operator()(const Dune::FieldMatrix< K, n, n > &J) const
Definition localoperators.hh:503
Definition localoperators.hh:278
auto operator()(const Dune::FieldVector< K1, n > &x, const Dune::FieldVector< K2, n > &y) const
Definition localoperators.hh:309
auto operator()(const Dune::ScaledIdentityMatrix< K1, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y) const
Definition localoperators.hh:370
auto operator()(const Dune::FieldMatrix< K1, n, m > &x, const Dune::FieldMatrix< K2, n, m > &y) const
Definition localoperators.hh:319
auto operator()(const Dune::FieldMatrix< K1, n, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y) const
Definition localoperators.hh:360
auto operator()(const std::array< L, n > &x, const std::array< R, n > &y) const
Definition localoperators.hh:376
auto operator()(const Dune::ScaledIdentityMatrix< K1, n > &x, const Dune::FieldMatrix< K2, n, n > &y) const
Definition localoperators.hh:350
auto operator()(const Dune::FieldMatrix< K1, n, m > &x, const Dune::FieldVector< K2, n > &y) const
Definition localoperators.hh:330
auto operator()(const Dune::FieldVector< K1, n > &x, const Dune::FieldMatrix< K2, n, m > &y) const
Definition localoperators.hh:340
Definition localoperators.hh:538
auto operator()(const T &t) const
Definition localoperators.hh:541
Definition localoperators.hh:397
auto operator()(const Dune::FieldVector< K, 1 > &x, const Y &y) const
Definition localoperators.hh:416
auto operator()(const Dune::FieldMatrix< K1, n, m > &x, const Dune::FieldVector< K2, m > &y) const
Definition localoperators.hh:407
auto operator()(const X &x, Dune::FieldMatrix< K, 1, 1 > &y) const
Definition localoperators.hh:434
auto operator()(const X &x, Dune::FieldVector< K, 1 > &y) const
Definition localoperators.hh:422
auto operator()(const Dune::FieldMatrix< K, 1, 1 > &x, const Y &y) const
Definition localoperators.hh:428
auto operator()(const X &x, const Y &y) const
Definition localoperators.hh:401
Definition localoperators.hh:66
static void addTo(Dune::FieldMatrix< K1, n, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y)
Definition localoperators.hh:108
static void addTo(Dune::FieldVector< K1, n > &x, const Dune::FieldVector< K2, n > &y)
Definition localoperators.hh:90
auto operator()(const T1 &x1, const T2 &x2, const T3 &x3, const Ts &... xs) const
Definition localoperators.hh:247
auto operator()(const Dune::FieldVector< K1, n > &x, const Dune::FieldVector< K2, n > &y) const
Definition localoperators.hh:174
auto operator()(const Dune::FieldMatrix< K1, n, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y) const
Definition localoperators.hh:225
static void addTo(std::tuple< Xi... > &x, const std::tuple< Yi... > &y)
Definition localoperators.hh:144
static void addTo(Dune::FieldMatrix< K1, n, m > &x, const Dune::FieldMatrix< K2, n, m > &y)
Definition localoperators.hh:96
static void addTo(Dune::ScaledIdentityMatrix< K1, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y)
Definition localoperators.hh:102
auto operator()(const K1 &x, const K2 &y) const
Definition localoperators.hh:154
static void addTo(K1 &x, const Dune::FieldVector< K2, 1 > &y)
Definition localoperators.hh:77
static void addTo(Dune::FieldMatrix< K1, n, 1 > &x, const Dune::FieldVector< K2, n > &y)
Definition localoperators.hh:115
auto operator()(const Dune::FieldVector< K1, n > &x, const Dune::FieldMatrix< K2, n, 1 > &y) const
Definition localoperators.hh:213
static void addTo(Dune::FieldMatrix< K1, 1, n > &x, const Dune::FieldVector< K2, n > &y)
Definition localoperators.hh:122
auto operator()(const Dune::FieldMatrix< K1, n, m > &x, const Dune::FieldMatrix< K2, n, m > &y) const
Definition localoperators.hh:180
auto operator()(const T1 &x0) const
Definition localoperators.hh:240
auto operator()(const Dune::FieldMatrix< K1, n, 1 > &x, const Dune::FieldVector< K2, n > &y) const
Definition localoperators.hh:193
auto operator()(const Dune::FieldVector< K1, n > &x, const Dune::FieldMatrix< K2, 1, n > &y) const
Definition localoperators.hh:219
static void addTo(Dune::FieldVector< K1, n > &x, const Dune::FieldMatrix< K2, 1, n > &y)
Definition localoperators.hh:136
auto operator()(const Dune::ScaledIdentityMatrix< K1, n > &x, const Dune::FieldMatrix< K2, n, n > &y) const
Definition localoperators.hh:234
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:129
static void addTo(Dune::FieldVector< K1, 1 > &x, const K2 &y)
Definition localoperators.hh:84
auto operator()(const Dune::FieldMatrix< K1, 1, n > &x, const Dune::FieldVector< K2, n > &y) const
Definition localoperators.hh:203
auto operator()(const Dune::ScaledIdentityMatrix< K1, n > &x, const Dune::ScaledIdentityMatrix< K2, n > &y) const
Definition localoperators.hh:186
Definition localoperators.hh:514
auto operator()(const Matrix &M) const
Definition localoperators.hh:516
Definition localoperators.hh:524
auto operator()(const Matrix &M) const
Definition localoperators.hh:526
Definition localoperators.hh:487
auto operator()(const Dune::FieldMatrix< K, n, m > &x) const
Definition localoperators.hh:489