dune-istl 2.12-git
Loading...
Searching...
No Matches
gsetc.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4// vi: set et ts=4 sw=2 sts=2:
5#ifndef DUNE_ISTL_GSETC_HH
6#define DUNE_ISTL_GSETC_HH
7
8#include <cmath>
9#include <complex>
10#include <iostream>
11#include <iomanip>
12#include <string>
13
15
18
19#include "istlexception.hh"
20
21
27namespace Dune {
28
39 //============================================================
40 // parameter types
41 //============================================================
42
44 template<int l>
45 struct BL {
46 enum {recursion_level = l};
47 };
48
53
58
59 //============================================================
60 // generic triangular solves
61 // consider block decomposition A = L + D + U
62 // we can invert L, L+D, U, U+D
63 // we can apply relaxation or not
64 // we can recurse over a fixed number of levels
65 //============================================================
66
67 // template meta program for triangular solves
68 template<int I, WithDiagType diag, WithRelaxType relax>
70 template<class M, class X, class Y, class K>
71 static void bltsolve (const M& A, X& v, const Y& d, const K& w)
72 {
73 // iterator types
74 typedef typename M::ConstRowIterator rowiterator;
75 typedef typename M::ConstColIterator coliterator;
76 typedef typename Y::block_type bblock;
77
78 // local solve at each block and immediate update
79 rowiterator endi=A.end();
80 for (rowiterator i=A.begin(); i!=endi; ++i)
81 {
82 bblock rhs(d[i.index()]);
83 coliterator j;
84 for (j=(*i).begin(); j.index()<i.index(); ++j)
85 (*j).mmv(v[j.index()],rhs);
86 algmeta_btsolve<I-1,diag,relax>::bltsolve(*j,v[i.index()],rhs,w);
87 }
88 }
89 template<class M, class X, class Y, class K>
90 static void butsolve (const M& A, X& v, const Y& d, const K& w)
91 {
92 // iterator types
95 typedef typename Y::block_type bblock;
96
97 // local solve at each block and immediate update
98 rrowiterator rbegin{A.begin()};
99 auto rindex = [](const auto& it) { return std::prev(it.base()).index(); };
100 for (rrowiterator i = rrowiterator{A.end()}; i!=rbegin; ++i)
101 {
102 auto row = rindex(i);
103 bblock rhs(d[row]);
104 rcoliterator j;
105 for (j=rcoliterator{(*i).end()}; rindex(j)>row; ++j)
106 (*j).mmv(v[rindex(j)],rhs);
108 }
109 }
110 };
111
112 // recursion end ...
113 template<>
115 template<class M, class X, class Y, class K>
116 static void bltsolve (const M& A, X& v, const Y& d, const K& w)
117 {
118 A.solve(v,d);
119 v *= w;
120 }
121 template<class M, class X, class Y, class K>
122 static void butsolve (const M& A, X& v, const Y& d, const K& w)
123 {
124 A.solve(v,d);
125 v *= w;
126 }
127 };
128 template<>
130 template<class M, class X, class Y, class K>
131 static void bltsolve (const M& A, X& v, const Y& d, const K& /*w*/)
132 {
133 A.solve(v,d);
134 }
135 template<class M, class X, class Y, class K>
136 static void butsolve (const M& A, X& v, const Y& d, const K& /*w*/)
137 {
138 A.solve(v,d);
139 }
140 };
141 template<>
143 template<class M, class X, class Y, class K>
144 static void bltsolve (const M& /*A*/, X& v, const Y& d, const K& w)
145 {
146 v = d;
147 v *= w;
148 }
149 template<class M, class X, class Y, class K>
150 static void butsolve (const M& /*A*/, X& v, const Y& d, const K& w)
151 {
152 v = d;
153 v *= w;
154 }
155 };
156 template<>
158 template<class M, class X, class Y, class K>
159 static void bltsolve (const M& /*A*/, X& v, const Y& d, const K& /*w*/)
160 {
161 v = d;
162 }
163 template<class M, class X, class Y, class K>
164 static void butsolve (const M& /*A*/, X& v, const Y& d, const K& /*w*/)
165 {
166 v = d;
167 }
168 };
169
170
171 // user calls
172
173 // default block recursion level = 1
174
176 template<class M, class X, class Y>
177 void bltsolve (const M& A, X& v, const Y& d)
178 {
179 typename X::field_type w=1;
181 }
183 template<class M, class X, class Y, class K>
184 void bltsolve (const M& A, X& v, const Y& d, const K& w)
185 {
187 }
189 template<class M, class X, class Y>
190 void ubltsolve (const M& A, X& v, const Y& d)
191 {
192 typename X::field_type w=1;
194 }
196 template<class M, class X, class Y, class K>
197 void ubltsolve (const M& A, X& v, const Y& d, const K& w)
198 {
200 }
201
203 template<class M, class X, class Y>
204 void butsolve (const M& A, X& v, const Y& d)
205 {
206 typename X::field_type w=1;
208 }
210 template<class M, class X, class Y, class K>
211 void butsolve (const M& A, X& v, const Y& d, const K& w)
212 {
214 }
216 template<class M, class X, class Y>
217 void ubutsolve (const M& A, X& v, const Y& d)
218 {
219 typename X::field_type w=1;
221 }
223 template<class M, class X, class Y, class K>
224 void ubutsolve (const M& A, X& v, const Y& d, const K& w)
225 {
227 }
228
229 // general block recursion level >= 0
230
232 template<class M, class X, class Y, int l>
233 void bltsolve (const M& A, X& v, const Y& d, BL<l> /*bl*/)
234 {
235 typename X::field_type w=1;
237 }
239 template<class M, class X, class Y, class K, int l>
240 void bltsolve (const M& A, X& v, const Y& d, const K& w, BL<l> /*bl*/)
241 {
243 }
245 template<class M, class X, class Y, int l>
246 void ubltsolve (const M& A, X& v, const Y& d, BL<l> /*bl*/)
247 {
248 typename X::field_type w=1;
250 }
252 template<class M, class X, class Y, class K, int l>
253 void ubltsolve (const M& A, X& v, const Y& d, const K& w, BL<l> /*bl*/)
254 {
256 }
257
259 template<class M, class X, class Y, int l>
260 void butsolve (const M& A, X& v, const Y& d, BL<l> /*bl*/)
261 {
262 typename X::field_type w=1;
264 }
266 template<class M, class X, class Y, class K, int l>
267 void butsolve (const M& A, X& v, const Y& d, const K& w, BL<l> /*bl*/)
268 {
270 }
272 template<class M, class X, class Y, int l>
273 void ubutsolve (const M& A, X& v, const Y& d, BL<l> /*bl*/)
274 {
275 typename X::field_type w=1;
277 }
279 template<class M, class X, class Y, class K, int l>
280 void ubutsolve (const M& A, X& v, const Y& d, const K& w, BL<l> /*bl*/)
281 {
283 }
284
285
286
287 //============================================================
288 // generic block diagonal solves
289 // consider block decomposition A = L + D + U
290 // we can apply relaxation or not
291 // we can recurse over a fixed number of levels
292 //============================================================
293
294 // template meta program for diagonal solves
295 template<int I, WithRelaxType relax>
297 template<class M, class X, class Y, class K>
298 static void bdsolve (const M& A, X& v, const Y& d, const K& w)
299 {
300 // iterator types
302 using coliterator = typename M::ConstColIterator;
303
304 // local solve at each block and immediate update
305 rrowiterator rendi{A.begin()};
306 for (rrowiterator i = rrowiterator{A.end()}; i!=rendi; ++i)
307 {
308 auto row = std::prev(i.base()).index();
309 coliterator ii=(*i).find(row);
310 algmeta_bdsolve<I-1,relax>::bdsolve(*ii,v[row],d[row],w);
311 }
312 }
313 };
314
315 // recursion end ...
316 template<>
318 template<class M, class X, class Y, class K>
319 static void bdsolve (const M& A, X& v, const Y& d, const K& w)
320 {
321 A.solve(v,d);
322 v *= w;
323 }
324 };
325 template<>
327 template<class M, class X, class Y, class K>
328 static void bdsolve (const M& A, X& v, const Y& d, const K& /*w*/)
329 {
330 A.solve(v,d);
331 }
332 };
333
334 // user calls
335
336 // default block recursion level = 1
337
339 template<class M, class X, class Y>
340 void bdsolve (const M& A, X& v, const Y& d)
341 {
342 typename X::field_type w=1;
344 }
346 template<class M, class X, class Y, class K>
347 void bdsolve (const M& A, X& v, const Y& d, const K& w)
348 {
350 }
351
352 // general block recursion level >= 0
353
355 template<class M, class X, class Y, int l>
356 void bdsolve (const M& A, X& v, const Y& d, BL<l> /*bl*/)
357 {
358 typename X::field_type w=1;
360 }
362 template<class M, class X, class Y, class K, int l>
363 void bdsolve (const M& A, X& v, const Y& d, const K& w, BL<l> /*bl*/)
364 {
366 }
367
368
369 //============================================================
370 // generic steps of iteration methods
371 // Jacobi, Gauss-Seidel, SOR, SSOR
372 // work directly on Ax=b, ie solve M(x^{i+1}-x^i) = w (b-Ax^i)
373 // we can recurse over a fixed number of levels
374 //============================================================
375
376 // template meta program for iterative solver steps
377 template<int I, typename M>
379
380 template<class X, class Y, class K>
381 static void dbgs (const M& A, X& x, const Y& b, const K& w)
382 {
383 typedef typename M::ConstRowIterator rowiterator;
384 typedef typename M::ConstColIterator coliterator;
385 typedef typename Y::block_type bblock;
386 bblock rhs;
387
388 X xold(x); // remember old x
389
390 rowiterator endi=A.end();
391 for (rowiterator i=A.begin(); i!=endi; ++i)
392 {
393 rhs = b[i.index()]; // rhs = b_i
394 coliterator endj=(*i).end();
395 coliterator j=(*i).begin();
396 if constexpr (IsNumber<typename M::block_type>())
397 {
398 for (; j.index()<i.index(); ++j)
399 rhs -= (*j) * x[j.index()];
400 coliterator diag=j++; // *diag = a_ii and increment coliterator j from a_ii to a_i+1,i to skip diagonal
401 for (; j != endj; ++j)
402 rhs -= (*j) * x[j.index()];
403 x[i.index()] = rhs / (*diag);
404 }
405 else
406 {
407 for (; j.index()<i.index(); ++j) // iterate over a_ij with j < i
408 (*j).mmv(x[j.index()],rhs); // rhs -= sum_{j<i} a_ij * xnew_j
409 coliterator diag=j++; // *diag = a_ii and increment coliterator j from a_ii to a_i+1,i to skip diagonal
410 for (; j != endj; ++j) // iterate over a_ij with j > i
411 (*j).mmv(x[j.index()],rhs); // rhs -= sum_{j>i} a_ij * xold_j
412 algmeta_itsteps<I-1,typename M::block_type>::dbgs(*diag,x[i.index()],rhs,w); // if I==1: xnew_i = rhs/a_ii
413 }
414 }
415 // next two lines: xnew_i = w / a_ii * (b_i - sum_{j<i} a_ij * xnew_j - sum_{j>=i} a_ij * xold_j) + (1-w)*xold;
416 x *= w;
417 x.axpy(K(1)-w,xold);
418 }
419
420 template<class X, class Y, class K>
421 static void bsorf (const M& A, X& x, const Y& b, const K& w)
422 {
423 typedef typename M::ConstRowIterator rowiterator;
424 typedef typename M::ConstColIterator coliterator;
425 typedef typename Y::block_type bblock;
426 typedef typename X::block_type xblock;
427 bblock rhs;
428 xblock v;
429
430 rowiterator endi=A.end();
431 for (rowiterator i=A.begin(); i!=endi; ++i)
432 {
433 rhs = b[i.index()]; // rhs = b_i
434 coliterator endj=(*i).end(); // iterate over a_ij with j < i
435 coliterator j=(*i).begin();
436 if constexpr (IsNumber<typename M::block_type>())
437 {
438 for (; j.index()<i.index(); ++j)
439 rhs -= (*j) * x[j.index()]; // rhs -= sum_{j<i} a_ij * xnew_j
440 coliterator diag=j; // *diag = a_ii
441 for (; j!=endj; ++j)
442 rhs -= (*j) * x[j.index()]; // rhs -= sum_{j<i} a_ij * xnew_j
443 v = rhs / (*diag);
444 x[i.index()] += w*v; // x_i = w / a_ii * (b_i - sum_{j<i} a_ij * xnew_j - sum_{j>=i} a_ij * xold_j)
445 }
446 else
447 {
448 for (; j.index()<i.index(); ++j)
449 (*j).mmv(x[j.index()],rhs); // rhs -= sum_{j<i} a_ij * xnew_j
450 coliterator diag=j; // *diag = a_ii
451 for (; j!=endj; ++j)
452 (*j).mmv(x[j.index()],rhs); // rhs -= sum_{j<i} a_ij * xnew_j
453 v=x[i.index()]; // Initialize nested data structure if there are entries
454 algmeta_itsteps<I-1,typename M::block_type>::bsorf(*diag,v,rhs,w); // if blocksize I==1: v = rhs/a_ii
455 x[i.index()].axpy(w,v); // x_i = w / a_ii * (b_i - sum_{j<i} a_ij * xnew_j - sum_{j>=i} a_ij * xold_j)
456 }
457 }
458 }
459
460 template<class X, class Y, class K>
461 static void bsorb (const M& A, X& x, const Y& b, const K& w)
462 {
464 typedef typename M::ConstColIterator coliterator;
465 typedef typename Y::block_type bblock;
466 typedef typename X::block_type xblock;
467 bblock rhs;
468 xblock v;
469
470 rrowiterator rbegini=rrowiterator{A.begin()};
471 auto rindex = [](const rrowiterator& it) { return std::prev(it.base()).index(); };
472 for (rrowiterator i=rrowiterator{A.end()}; i!=rbegini; ++i)
473 {
474 auto row = rindex(i);
475 rhs = b[row];
476 coliterator endj=(*i).end();
477 coliterator j=(*i).begin();
478 if constexpr (IsNumber<typename M::block_type>())
479 {
480 for (; j.index()<row; ++j)
481 rhs -= (*j) * x[j.index()];
482 coliterator diag=j;
483 for (; j!=endj; ++j)
484 rhs -= (*j) * x[j.index()];
485 v = rhs / (*diag);
486 x[row] += w*v;
487 }
488 else
489 {
490 for (; j.index()<row; ++j)
491 j->mmv(x[j.index()],rhs);
492 coliterator diag=j;
493 for (; j!=endj; ++j)
494 j->mmv(x[j.index()],rhs);
495 v = x[row]; // Initialize nested data structure if there are entries
497 x[row].axpy(w,v);
498 }
499 }
500 }
501
502 template<class X, class Y, class K>
503 static void dbjac (const M& A, X& x, const Y& b, const K& w)
504 {
505 typedef typename M::ConstRowIterator rowiterator;
506 typedef typename M::ConstColIterator coliterator;
507 typedef typename Y::block_type bblock;
508 bblock rhs;
509
510 X v(x); // allocate with same size
511
512 rowiterator endi=A.end();
513 for (rowiterator i=A.begin(); i!=endi; ++i)
514 {
515 rhs = b[i.index()];
516 coliterator endj=(*i).end();
517 coliterator j=(*i).begin();
518 if constexpr (IsNumber<typename M::block_type>())
519 {
520 for (; j.index()<i.index(); ++j)
521 rhs -= (*j) * x[j.index()];
522 coliterator diag=j;
523 for (; j!=endj; ++j)
524 rhs -= (*j) * x[j.index()];
525 v[i.index()] = rhs / (*diag);
526 }
527 else
528 {
529 for (; j.index()<i.index(); ++j)
530 j->mmv(x[j.index()],rhs);
531 coliterator diag=j;
532 for (; j!=endj; ++j)
533 j->mmv(x[j.index()],rhs);
535 }
536 }
537 x.axpy(w,v);
538 }
539 };
540 // end of recursion
541 template<typename M>
542 struct algmeta_itsteps<0,M> {
543 template<class X, class Y, class K>
544 static void dbgs (const M& A, X& x, const Y& b, const K& /*w*/)
545 {
546 A.solve(x,b);
547 }
548 template<class X, class Y, class K>
549 static void bsorf (const M& A, X& x, const Y& b, const K& /*w*/)
550 {
551 A.solve(x,b);
552 }
553 template<class X, class Y, class K>
554 static void bsorb (const M& A, X& x, const Y& b, const K& /*w*/)
555 {
556 A.solve(x,b);
557 }
558 template<class X, class Y, class K>
559 static void dbjac (const M& A, X& x, const Y& b, const K& /*w*/)
560 {
561 A.solve(x,b);
562 }
563 };
564
565 template<int I, typename T1, typename... MultiTypeMatrixArgs>
566 struct algmeta_itsteps<I,MultiTypeBlockMatrix<T1, MultiTypeMatrixArgs...>> {
567 template<
568 typename... MultiTypeVectorArgs,
569 class K>
578
579 template<
580 typename... MultiTypeVectorArgs,
581 class K>
590
591 template<
592 typename... MultiTypeVectorArgs,
593 class K>
602
603 template<
604 typename... MultiTypeVectorArgs,
605 class K
606 >
615 };
616
617 // user calls
618
620 template<class M, class X, class Y, class K>
621 void dbgs (const M& A, X& x, const Y& b, const K& w)
622 {
624 }
626 template<class M, class X, class Y, class K, int l>
627 void dbgs (const M& A, X& x, const Y& b, const K& w, BL<l> /*bl*/)
628 {
630 }
632 template<class M, class X, class Y, class K>
633 void bsorf (const M& A, X& x, const Y& b, const K& w)
634 {
636 }
638 template<class M, class X, class Y, class K, int l>
639 void bsorf (const M& A, X& x, const Y& b, const K& w, BL<l> /*bl*/)
640 {
642 }
644 template<class M, class X, class Y, class K>
645 void bsorb (const M& A, X& x, const Y& b, const K& w)
646 {
648 }
650 template<class M, class X, class Y, class K, int l>
651 void bsorb (const M& A, X& x, const Y& b, const K& w, BL<l> /*bl*/)
652 {
654 }
656 template<class M, class X, class Y, class K>
657 void dbjac (const M& A, X& x, const Y& b, const K& w)
658 {
660 }
662 template<class M, class X, class Y, class K, int l>
663 void dbjac (const M& A, X& x, const Y& b, const K& w, BL<l> /*bl*/)
664 {
666 }
667
668
671} // end namespace
672
673#endif
static void dbjac(const TMatrix &A, TVector &x, const TVector &b, const K &w)
Definition multitypeblockmatrix.hh:584
static void dbgs(const TMatrix &A, TVector &x, const TVector &b, const K &w)
Definition multitypeblockmatrix.hh:500
static void bsorb(const TMatrix &A, TVector &x, const TVector &b, const K &w)
Definition multitypeblockmatrix.hh:556
static constexpr size_type N()
Return the number of matrix rows.
Definition multitypeblockmatrix.hh:84
static void bsorf(const TMatrix &A, TVector &x, const TVector &b, const K &w)
Definition multitypeblockmatrix.hh:529
void bltsolve(const M &A, X &v, const Y &d)
block lower triangular solve
Definition gsetc.hh:177
WithDiagType
Definition gsetc.hh:49
void bsorb(const M &A, X &x, const Y &b, const K &w)
SSOR step.
Definition gsetc.hh:645
void ubltsolve(const M &A, X &v, const Y &d)
unit block lower triangular solve
Definition gsetc.hh:190
void dbjac(const M &A, X &x, const Y &b, const K &w)
Jacobi step.
Definition gsetc.hh:657
void dbgs(const M &A, X &x, const Y &b, const K &w)
GS step.
Definition gsetc.hh:621
WithRelaxType
Definition gsetc.hh:54
void bdsolve(const M &A, X &v, const Y &d)
block diagonal solve, no relaxation
Definition gsetc.hh:340
void butsolve(const M &A, X &v, const Y &d)
block upper triangular solve
Definition gsetc.hh:204
void bsorf(const M &A, X &x, const Y &b, const K &w)
SOR step.
Definition gsetc.hh:633
void ubutsolve(const M &A, X &v, const Y &d)
unit block upper triangular solve
Definition gsetc.hh:217
@ nodiag
Definition gsetc.hh:51
@ withdiag
Definition gsetc.hh:50
@ norelax
Definition gsetc.hh:56
@ withrelax
Definition gsetc.hh:55
static constexpr size_type M()
static constexpr size_type N()
A Vector class to support different block types.
Definition multitypeblockvector.hh:59
A Matrix class to support different block types.
Definition multitypeblockmatrix.hh:46
compile-time parameter for block recursion depth
Definition gsetc.hh:45
@ recursion_level
Definition gsetc.hh:46
Definition gsetc.hh:69
static void butsolve(const M &A, X &v, const Y &d, const K &w)
Definition gsetc.hh:90
static void bltsolve(const M &A, X &v, const Y &d, const K &w)
Definition gsetc.hh:71
static void bltsolve(const M &A, X &v, const Y &d, const K &w)
Definition gsetc.hh:116
static void butsolve(const M &A, X &v, const Y &d, const K &w)
Definition gsetc.hh:122
static void bltsolve(const M &A, X &v, const Y &d, const K &)
Definition gsetc.hh:131
static void butsolve(const M &A, X &v, const Y &d, const K &)
Definition gsetc.hh:136
static void bltsolve(const M &, X &v, const Y &d, const K &w)
Definition gsetc.hh:144
static void butsolve(const M &, X &v, const Y &d, const K &w)
Definition gsetc.hh:150
static void bltsolve(const M &, X &v, const Y &d, const K &)
Definition gsetc.hh:159
static void butsolve(const M &, X &v, const Y &d, const K &)
Definition gsetc.hh:164
Definition gsetc.hh:296
static void bdsolve(const M &A, X &v, const Y &d, const K &w)
Definition gsetc.hh:298
static void bdsolve(const M &A, X &v, const Y &d, const K &w)
Definition gsetc.hh:319
static void bdsolve(const M &A, X &v, const Y &d, const K &)
Definition gsetc.hh:328
Definition gsetc.hh:378
static void bsorb(const M &A, X &x, const Y &b, const K &w)
Definition gsetc.hh:461
static void bsorf(const M &A, X &x, const Y &b, const K &w)
Definition gsetc.hh:421
static void dbjac(const M &A, X &x, const Y &b, const K &w)
Definition gsetc.hh:503
static void dbgs(const M &A, X &x, const Y &b, const K &w)
Definition gsetc.hh:381
static void dbgs(const M &A, X &x, const Y &b, const K &)
Definition gsetc.hh:544
static void dbjac(const M &A, X &x, const Y &b, const K &)
Definition gsetc.hh:559
static void bsorf(const M &A, X &x, const Y &b, const K &)
Definition gsetc.hh:549
static void bsorb(const M &A, X &x, const Y &b, const K &)
Definition gsetc.hh:554
static void dbgs(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A, MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector< MultiTypeVectorArgs... > &b, const K &w)
Definition gsetc.hh:570
static void dbjac(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A, MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector< MultiTypeVectorArgs... > &b, const K &w)
Definition gsetc.hh:607
static void bsorf(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A, MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector< MultiTypeVectorArgs... > &b, const K &w)
Definition gsetc.hh:582
static void bsorb(const MultiTypeBlockMatrix< T1, MultiTypeMatrixArgs... > &A, MultiTypeBlockVector< MultiTypeVectorArgs... > &x, const MultiTypeBlockVector< MultiTypeVectorArgs... > &b, const K &w)
Definition gsetc.hh:594
T prev(T... args)