00001 #ifndef DUNE_PRECONDITIONERS_HH
00002 #define DUNE_PRECONDITIONERS_HH
00003
00004 #include<cmath>
00005 #include<complex>
00006 #include<iostream>
00007 #include<iomanip>
00008 #include<string>
00009
00010 #include"solvercategory.hh"
00011 #include "istlexception.hh"
00012 #include "matrixutils.hh"
00013 #include "io.hh"
00014 #include "gsetc.hh"
00015 #include "ilu.hh"
00016
00017
00018 namespace Dune {
00056
00070
00071 template<class X, class Y>
00072 class Preconditioner {
00073 public:
00075 typedef X domain_type;
00077 typedef Y range_type;
00079 typedef typename X::field_type field_type;
00080
00096 virtual void pre (X& x, Y& b) = 0;
00097
00108 virtual void apply (X& v, const Y& d) = 0;
00109
00118 virtual void post (X& x) = 0;
00119
00120
00121 virtual ~Preconditioner () {}
00122 };
00123
00124
00125
00126
00127
00128
00129
00140 template<class M, class X, class Y, int l=1>
00141 class SeqSSOR : public Preconditioner<X,Y> {
00142 public:
00144 typedef M matrix_type;
00146 typedef X domain_type;
00148 typedef Y range_type;
00150 typedef typename X::field_type field_type;
00151
00152
00153 enum {
00155 category=SolverCategory::sequential};
00156
00164 SeqSSOR (const M& A, int n, field_type w)
00165 : _A_(A), _n(n), _w(w)
00166 {
00167 CheckIfDiagonalPresent<l>::check(_A_);
00168 }
00169
00175 virtual void pre (X& x, Y& b) {}
00176
00182 virtual void apply (X& v, const Y& d)
00183 {
00184 for (int i=0; i<_n; i++){
00185 bsorf(_A_,v,d,_w,BL<l>());
00186 bsorb(_A_,v,d,_w,BL<l>());
00187 }
00188 }
00189
00195 virtual void post (X& x) {}
00196
00197 private:
00199 const M& _A_;
00201 int _n;
00203 field_type _w;
00204 };
00205
00206
00207
00218 template<class M, class X, class Y, int l=1>
00219 class SeqSOR : public Preconditioner<X,Y> {
00220 public:
00222 typedef M matrix_type;
00224 typedef X domain_type;
00226 typedef Y range_type;
00228 typedef typename X::field_type field_type;
00229
00230
00231 enum {
00233 category=SolverCategory::sequential
00234 };
00235
00243 SeqSOR (const M& A, int n, field_type w)
00244 : _A_(A), _n(n), _w(w)
00245 {
00246 CheckIfDiagonalPresent<l>::check(_A_);
00247 }
00248
00254 virtual void pre (X& x, Y& b) {}
00255
00261 virtual void apply (X& v, const Y& d)
00262 {
00263 this->template apply<true>(v,d);
00264 }
00265
00274 template<bool forward>
00275 void apply(X& v, const Y& d)
00276 {
00277 if(forward)
00278 for (int i=0; i<_n; i++){
00279 bsorf(_A_,v,d,_w,BL<l>());
00280 }
00281 else
00282 for (int i=0; i<_n; i++){
00283 bsorb(_A_,v,d,_w,BL<l>());
00284 }
00285 }
00286
00292 virtual void post (X& x) {}
00293
00294 private:
00296 const M& _A_;
00298 int _n;
00300 field_type _w;
00301 };
00302
00303
00313 template<class M, class X, class Y, int l=1>
00314 class SeqGS : public Preconditioner<X,Y> {
00315 public:
00317 typedef M matrix_type;
00319 typedef X domain_type;
00321 typedef Y range_type;
00323 typedef typename X::field_type field_type;
00324
00325
00326 enum {
00328 category=SolverCategory::sequential
00329 };
00330
00338 SeqGS (const M& A, int n, field_type w)
00339 : _A_(A), _n(n), _w(w)
00340 {
00341 CheckIfDiagonalPresent<l>::check(_A_);
00342 }
00343
00349 virtual void pre (X& x, Y& b) {}
00350
00356 virtual void apply (X& v, const Y& d)
00357 {
00358 for (int i=0; i<_n; i++){
00359 dbgs(_A_,v,d,_w,BL<l>());
00360 }
00361 }
00362
00368 virtual void post (X& x) {}
00369
00370 private:
00372 const M& _A_;
00374 int _n;
00376 field_type _w;
00377 };
00378
00379
00389 template<class M, class X, class Y, int l=1>
00390 class SeqJac : public Preconditioner<X,Y> {
00391 public:
00393 typedef M matrix_type;
00395 typedef X domain_type;
00397 typedef Y range_type;
00399 typedef typename X::field_type field_type;
00400
00401
00402 enum {
00404 category=SolverCategory::sequential
00405 };
00406
00414 SeqJac (const M& A, int n, field_type w)
00415 : _A_(A), _n(n), _w(w)
00416 {
00417 CheckIfDiagonalPresent<l>::check(_A_);
00418 }
00419
00425 virtual void pre (X& x, Y& b) {}
00426
00432 virtual void apply (X& v, const Y& d)
00433 {
00434 for (int i=0; i<_n; i++){
00435 dbjac(_A_,v,d,_w,BL<l>());
00436 }
00437 }
00438
00444 virtual void post (X& x) {}
00445
00446 private:
00448 const M& _A_;
00450 int _n;
00452 field_type _w;
00453 };
00454
00455
00456
00466 template<class M, class X, class Y>
00467 class SeqILU0 : public Preconditioner<X,Y> {
00468 public:
00470 typedef typename Dune::remove_const<M>::type matrix_type;
00472 typedef X domain_type;
00474 typedef Y range_type;
00476 typedef typename X::field_type field_type;
00477
00478
00479 enum {
00481 category=SolverCategory::sequential
00482 };
00483
00490 SeqILU0 (const M& A, field_type w)
00491 : ILU(A)
00492 {
00493 _w =w;
00494 bilu0_decomposition(ILU);
00495 }
00496
00502 virtual void pre (X& x, Y& b) {}
00503
00509 virtual void apply (X& v, const Y& d)
00510 {
00511 bilu_backsolve(ILU,v,d);
00512 v *= _w;
00513 }
00514
00520 virtual void post (X& x) {}
00521
00522 private:
00524 field_type _w;
00526 matrix_type ILU;
00527 };
00528
00529
00541 template<class M, class X, class Y>
00542 class SeqILUn : public Preconditioner<X,Y> {
00543 public:
00545 typedef typename Dune::remove_const<M>::type matrix_type;
00547 typedef X domain_type;
00549 typedef Y range_type;
00551 typedef typename X::field_type field_type;
00552
00553
00554 enum {
00556 category=SolverCategory::sequential
00557 };
00558
00566 SeqILUn (const M& A, int n, field_type w)
00567 : ILU(A.N(),A.M(),M::row_wise)
00568 {
00569 _n = n;
00570 _w = w;
00571 bilu_decomposition(A,n,ILU);
00572 }
00573
00579 virtual void pre (X& x, Y& b) {}
00580
00586 virtual void apply (X& v, const Y& d)
00587 {
00588 bilu_backsolve(ILU,v,d);
00589 v *= _w;
00590 }
00591
00597 virtual void post (X& x) {}
00598
00599 private:
00601 matrix_type ILU;
00603 int _n;
00605 field_type _w;
00606 };
00607
00608
00609
00618 template<class X, class Y>
00619 class Richardson : public Preconditioner<X,Y> {
00620 public:
00622 typedef X domain_type;
00624 typedef Y range_type;
00626 typedef typename X::field_type field_type;
00627
00628
00629 enum {
00631 category=SolverCategory::sequential
00632 };
00633
00639 Richardson (field_type w=1.0)
00640 {
00641 _w = w;
00642 }
00643
00649 virtual void pre (X& x, Y& b) {}
00650
00656 virtual void apply (X& v, const Y& d)
00657 {
00658 v = d;
00659 v *= _w;
00660 }
00661
00667 virtual void post (X& x) {}
00668
00669 private:
00671 field_type _w;
00672 };
00673
00674
00675
00678 }
00679
00680 #endif