dune-istl
2.1.1
|
00001 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 00002 // vi: set et ts=8 sw=2 sts=2: 00003 #ifndef DUNE_PRECONDITIONERS_HH 00004 #define DUNE_PRECONDITIONERS_HH 00005 00006 #include<cmath> 00007 #include<complex> 00008 #include<iostream> 00009 #include<iomanip> 00010 #include<string> 00011 00012 #include"solvercategory.hh" 00013 #include "istlexception.hh" 00014 #include "matrixutils.hh" 00015 #include "io.hh" 00016 #include "gsetc.hh" 00017 #include "ilu.hh" 00018 00019 00020 namespace Dune { 00058 //===================================================================== 00072 //===================================================================== 00073 template<class X, class Y> 00074 class Preconditioner { 00075 public: 00077 typedef X domain_type; 00079 typedef Y range_type; 00081 typedef typename X::field_type field_type; 00082 00098 virtual void pre (X& x, Y& b) = 0; 00099 00110 virtual void apply (X& v, const Y& d) = 0; 00111 00120 virtual void post (X& x) = 0; 00121 00122 // every abstract base class has a virtual destructor 00123 virtual ~Preconditioner () {} 00124 }; 00125 00126 00127 //===================================================================== 00128 // Implementation of this interface for sequential ISTL-preconditioners 00129 //===================================================================== 00130 00131 00143 template<class M, class X, class Y, int l=1> 00144 class SeqSSOR : public Preconditioner<X,Y> { 00145 public: 00147 typedef M matrix_type; 00149 typedef X domain_type; 00151 typedef Y range_type; 00153 typedef typename X::field_type field_type; 00154 00155 // define the category 00156 enum { 00158 category=SolverCategory::sequential}; 00159 00167 SeqSSOR (const M& A, int n, field_type w) 00168 : _A_(A), _n(n), _w(w) 00169 { 00170 CheckIfDiagonalPresent<M,l>::check(_A_); 00171 } 00172 00178 virtual void pre (X& x, Y& b) {} 00179 00185 virtual void apply (X& v, const Y& d) 00186 { 00187 for (int i=0; i<_n; i++){ 00188 bsorf(_A_,v,d,_w,BL<l>()); 00189 bsorb(_A_,v,d,_w,BL<l>()); 00190 } 00191 } 00192 00198 virtual void post (X& x) {} 00199 00200 private: 00202 const M& _A_; 00204 int _n; 00206 field_type _w; 00207 }; 00208 00209 00210 00222 template<class M, class X, class Y, int l=1> 00223 class SeqSOR : public Preconditioner<X,Y> { 00224 public: 00226 typedef M matrix_type; 00228 typedef X domain_type; 00230 typedef Y range_type; 00232 typedef typename X::field_type field_type; 00233 00234 // define the category 00235 enum { 00237 category=SolverCategory::sequential 00238 }; 00239 00247 SeqSOR (const M& A, int n, field_type w) 00248 : _A_(A), _n(n), _w(w) 00249 { 00250 CheckIfDiagonalPresent<M,l>::check(_A_); 00251 } 00252 00258 virtual void pre (X& x, Y& b) {} 00259 00265 virtual void apply (X& v, const Y& d) 00266 { 00267 this->template apply<true>(v,d); 00268 } 00269 00278 template<bool forward> 00279 void apply(X& v, const Y& d) 00280 { 00281 if(forward) 00282 for (int i=0; i<_n; i++){ 00283 bsorf(_A_,v,d,_w,BL<l>()); 00284 } 00285 else 00286 for (int i=0; i<_n; i++){ 00287 bsorb(_A_,v,d,_w,BL<l>()); 00288 } 00289 } 00290 00296 virtual void post (X& x) {} 00297 00298 private: 00300 const M& _A_; 00302 int _n; 00304 field_type _w; 00305 }; 00306 00307 00318 template<class M, class X, class Y, int l=1> 00319 class SeqGS : public Preconditioner<X,Y> { 00320 public: 00322 typedef M matrix_type; 00324 typedef X domain_type; 00326 typedef Y range_type; 00328 typedef typename X::field_type field_type; 00329 00330 // define the category 00331 enum { 00333 category=SolverCategory::sequential 00334 }; 00335 00343 SeqGS (const M& A, int n, field_type w) 00344 : _A_(A), _n(n), _w(w) 00345 { 00346 CheckIfDiagonalPresent<M,l>::check(_A_); 00347 } 00348 00354 virtual void pre (X& x, Y& b) {} 00355 00361 virtual void apply (X& v, const Y& d) 00362 { 00363 for (int i=0; i<_n; i++){ 00364 dbgs(_A_,v,d,_w,BL<l>()); 00365 } 00366 } 00367 00373 virtual void post (X& x) {} 00374 00375 private: 00377 const M& _A_; 00379 int _n; 00381 field_type _w; 00382 }; 00383 00384 00395 template<class M, class X, class Y, int l=1> 00396 class SeqJac : public Preconditioner<X,Y> { 00397 public: 00399 typedef M matrix_type; 00401 typedef X domain_type; 00403 typedef Y range_type; 00405 typedef typename X::field_type field_type; 00406 00407 // define the category 00408 enum { 00410 category=SolverCategory::sequential 00411 }; 00412 00420 SeqJac (const M& A, int n, field_type w) 00421 : _A_(A), _n(n), _w(w) 00422 { 00423 CheckIfDiagonalPresent<M,l>::check(_A_); 00424 } 00425 00431 virtual void pre (X& x, Y& b) {} 00432 00438 virtual void apply (X& v, const Y& d) 00439 { 00440 for (int i=0; i<_n; i++){ 00441 dbjac(_A_,v,d,_w,BL<l>()); 00442 } 00443 } 00444 00450 virtual void post (X& x) {} 00451 00452 private: 00454 const M& _A_; 00456 int _n; 00458 field_type _w; 00459 }; 00460 00461 00462 00474 template<class M, class X, class Y, int l=1> 00475 class SeqILU0 : public Preconditioner<X,Y> { 00476 public: 00478 typedef typename Dune::remove_const<M>::type matrix_type; 00480 typedef X domain_type; 00482 typedef Y range_type; 00484 typedef typename X::field_type field_type; 00485 00486 // define the category 00487 enum { 00489 category=SolverCategory::sequential 00490 }; 00491 00498 SeqILU0 (const M& A, field_type w) 00499 : ILU(A) // copy A 00500 { 00501 _w =w; 00502 bilu0_decomposition(ILU); 00503 } 00504 00510 virtual void pre (X& x, Y& b) {} 00511 00517 virtual void apply (X& v, const Y& d) 00518 { 00519 bilu_backsolve(ILU,v,d); 00520 v *= _w; 00521 } 00522 00528 virtual void post (X& x) {} 00529 00530 private: 00532 field_type _w; 00534 matrix_type ILU; 00535 }; 00536 00537 00551 template<class M, class X, class Y, int l=1> 00552 class SeqILUn : public Preconditioner<X,Y> { 00553 public: 00555 typedef typename Dune::remove_const<M>::type matrix_type; 00557 typedef X domain_type; 00559 typedef Y range_type; 00561 typedef typename X::field_type field_type; 00562 00563 // define the category 00564 enum { 00566 category=SolverCategory::sequential 00567 }; 00568 00576 SeqILUn (const M& A, int n, field_type w) 00577 : ILU(A.N(),A.M(),M::row_wise) 00578 { 00579 _n = n; 00580 _w = w; 00581 bilu_decomposition(A,n,ILU); 00582 } 00583 00589 virtual void pre (X& x, Y& b) {} 00590 00596 virtual void apply (X& v, const Y& d) 00597 { 00598 bilu_backsolve(ILU,v,d); 00599 v *= _w; 00600 } 00601 00607 virtual void post (X& x) {} 00608 00609 private: 00611 matrix_type ILU; 00613 int _n; 00615 field_type _w; 00616 }; 00617 00618 00619 00628 template<class X, class Y> 00629 class Richardson : public Preconditioner<X,Y> { 00630 public: 00632 typedef X domain_type; 00634 typedef Y range_type; 00636 typedef typename X::field_type field_type; 00637 00638 // define the category 00639 enum { 00641 category=SolverCategory::sequential 00642 }; 00643 00649 Richardson (field_type w=1.0) 00650 { 00651 _w = w; 00652 } 00653 00659 virtual void pre (X& x, Y& b) {} 00660 00666 virtual void apply (X& v, const Y& d) 00667 { 00668 v = d; 00669 v *= _w; 00670 } 00671 00677 virtual void post (X& x) {} 00678 00679 private: 00681 field_type _w; 00682 }; 00683 00684 00685 00688 } // end namespace 00689 00690 #endif