00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef __PRECOND_H
00034 #define __PRECOND_H
00035
00036 #include <iostream>
00037 using std::ostream;
00038 using std::endl;
00039
00040 #include <iomanip>
00041 using std::setw;
00042
00043 #include "OFELI_Config.h"
00044 #include "Vect.h"
00045 #include "util.h"
00046 #include "Matrix.h"
00047
00048 namespace OFELI {
00049
00054 template<class T_> class SpMatrix;
00055
00056 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00057 template<class T_,class M_>
00058 int inv_diag(size_t n, const M_ &A, valarray<T_> &diag)
00059 {
00060 for (int i=1; i<=int(n); i++) {
00061 if (A(i,i) == T_(0.))
00062 return i;
00063 if ((diag[i-1]=T_(1.)/A(i,i)) == T_(0.))
00064 return -i;
00065 }
00066 return 0;
00067 }
00068
00069 template<class T_>
00070 int inv_diag(size_t n, const Matrix<T_> *A, valarray<T_> &diag)
00071 {
00072 for (size_t i=1; i<=n; i++) {
00073 T_ d = (*A)(i,i);
00074 if (d == T_(0.))
00075 return i;
00076 diag[i-1] = T_(1)/d;
00077 if (diag[i-1] == T_(0.))
00078 return -i;
00079 }
00080 return 0;
00081 }
00082 #endif
00083
00095 template<class T_> class Prec
00096 {
00097
00098 public:
00099
00101 Prec() {
00102 _type = -1;
00103 #ifdef _OFELI_DEBUG
00104 std::clog << "An instance of class Prec is constructed.\n";
00105 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00106 #endif
00107 }
00108
00117 Prec(int type) {
00118 _type = type;
00119 #ifdef _OFELI_DEBUG
00120 std::clog << "An instance of class Prec is constructed.\n";
00121 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00122 #endif
00123 }
00124
00134 Prec(const SpMatrix<T_> &A, int type=IDENT_PREC) {
00135 _type = type;
00136 setMatrix(A);
00137 #ifdef _OFELI_DEBUG
00138 std::clog << "An instance of class Prec is constructed.\n";
00139 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00140 #endif
00141 }
00142
00152 Prec(const Matrix<T_> *A, int type=IDENT_PREC) {
00153 _type = type;
00154 setMatrix(A);
00155 #ifdef _OFELI_DEBUG
00156 std::clog << "An instance of class Prec is constructed.\n";
00157 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00158 #endif
00159 }
00160
00162 ~Prec()
00163 {
00164 #ifdef _OFELI_DEBUG
00165 std::clog << "An instance of class Prec is destructed.\n";
00166 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00167 #endif
00168 }
00169
00178 void setType(int type) { _type = type; }
00179
00182 void setMatrix(const Matrix<T_> *A)
00183 {
00184 if (_type==-1) {
00185 cerr << "Error in OFELI::Prec" << endl;
00186 cerr << "In setMatrix(A) : Choose preconditioner before setting matrix" << endl;
00187 exit(1);
00188 }
00189 _a = (SpMatrix<T_> *)(A);
00190 _size = _a->getSize();
00191 if (_type==IDENT_PREC) { }
00192 else if (_type==DIAG_PREC) {
00193 _pivot.resize(_size);
00194 int i;
00195 if ((i = inv_diag()) != 0) {
00196 cerr << "\n*** Fatal Error in OFELI ***\nIn Prec::setMatrix(A) : ";
00197 cerr << "Zero detected in element " << i << endl;
00198 cerr << "Program stops\n";
00199 exit(1);
00200 }
00201 }
00202 else if (_type==ILU_PREC) {
00203 size_t i, j, k=1;
00204 _pivot.resize(_size);
00205 _id.resize(_size);
00206 for (i=0; i<_size; i++) {
00207 for (j=_a->getRowPtr(i+1); j<_a->getRowPtr(i+2); j++,k++) {
00208 if (_a->getColInd(j)==i+1) {
00209 _id[i] = k;
00210 if ((*_a)(k)==0) {
00211 cerr << "\n*** Fatal Error in OFELI ***\nIn Prec::setMatrix(a) : ";
00212 cerr << "Zero detected in element " << i+1 << endl;
00213 cerr << "Program stops\n";
00214 exit(1);
00215 }
00216 _pivot[i] = (*_a)(k);
00217 }
00218 }
00219 }
00220 bool found;
00221 T_ c = 0;
00222 for (i=0; i<_size; i++) {
00223 _pivot[i] = 1./_pivot[i];
00224 for (j=_id[i]+1; j<=_a->getRowPtr(i+2)-1; j++) {
00225 found = false;
00226 size_t l = _a->getColInd(j);
00227 for (k=_a->getRowPtr(l); k<=_id[l-1]-1; k++) {
00228 if (_a->getColInd(k)==i+1) {
00229 found = true;
00230 c = (*_a)(k);
00231 }
00232 }
00233 if (found)
00234 _pivot[l-1] -= c * _pivot[i] * (*_a)(j);
00235 }
00236 }
00237 }
00238 else
00239 ;
00240 }
00241
00244 void setMatrix(const SpMatrix<T_> &A)
00245 {
00246 if (_type==-1) {
00247 cerr << "Error in OFELI::Prec" << endl;
00248 cerr << "In setMatrix(A) : Choose preconditioner before setting matrix" << endl;
00249 exit(1);
00250 }
00251 _a = &A;
00252 _size = _a->getSize();
00253 if (_type==IDENT_PREC) {
00254 }
00255 else if (_type==DIAG_PREC) {
00256 _pivot.resize(_size);
00257 int i;
00258 if ((i=inv_diag()) != 0) {
00259 cerr << "\n*** Fatal Error in OFELI ***\nIn Prec::setMatrix(a) : ";
00260 cerr << "Zero detected in element " << i << endl;
00261 cerr << "Program stops\n";
00262 exit(1);
00263 }
00264 }
00265 else if (_type==ILU_PREC) {
00266 size_t i, j, k=1;
00267 _pivot.resize(_size);
00268 _id.resize(_size);
00269 for (i=0; i<_size; i++) {
00270 for (j=_a->getRowPtr(i+1); j<_a->getRowPtr(i+2); j++, k++) {
00271 if (_a->getColInd(j)==i+1) {
00272 _id[i] = k;
00273 if ((*_a)(k)==T_(0.)) {
00274 cerr << "\n*** Fatal Error in OFELI ***\nIn Prec::setMatrix(a) : ";
00275 cerr << "Zero detected in element " << i+1 << endl;
00276 cerr << "Program stops\n";
00277 exit(1);
00278 }
00279 _pivot[i] = (*_a)(k);
00280 }
00281 }
00282 }
00283 bool found;
00284 T_ c = T_(0.);
00285 for (i=0; i<_size; i++) {
00286 _pivot[i] = T_(1.)/_pivot[i];
00287 for (j=_id[i]+1; j<=_a->getRowPtr(i+2)-1; j++) {
00288 found = false;
00289 size_t l = _a->getColInd(j);
00290 for (k=_a->getRowPtr(l); k<=_id[l-1]-1; k++) {
00291 if (_a->getColInd(k)==i+1) {
00292 found = true;
00293 c = (*_a)(k);
00294 }
00295 }
00296 if (found)
00297 _pivot[l-1] -= c * _pivot[i] * (*_a)(j);
00298 }
00299 }
00300 }
00301 else
00302 ;
00303 }
00304
00307 void Solve(Vect<T_> &x) const
00308 {
00309 if (_type==DIAG_PREC) {
00310 for (size_t i=0; i<_size; i++)
00311 x[i] *= _pivot[i];
00312 }
00313 else if (_type==ILU_PREC) {
00314 int i, j;
00315 Vect<T_> z(_size);
00316 for (i=0; i<int(_size); i++) {
00317 T_ s = 0;
00318 for (j=_a->getRowPtr(i+1); j<=int(_id[i])-1; j++)
00319 s += (*_a)[j-1] * z(_a->getColInd(j));
00320 z[i] = _pivot[i] * (x[i]-s);
00321 }
00322 for (i=_size-1; i>=0; i--) {
00323 T_ s = 0;
00324 for (j=_id[i]+1; j<=int(_a->getRowPtr(i+2))-1; j++) {
00325 s += (*_a)[j-1] * x(_a->getColInd(j));
00326 x[i] = z[i] - _pivot[i] * s;
00327 }
00328 }
00329 }
00330 else
00331 ;
00332 }
00333
00338 void Solve(const Vect<T_> &b, Vect<T_> &x) const
00339 {
00340 if (_type==IDENT_PREC) {
00341 x = b;
00342 }
00343 else if (_type==DIAG_PREC) {
00344 for (size_t i=0; i<_size; i++)
00345 x[i] = b[i] * _pivot[i];
00346 }
00347 else if (_type==ILU_PREC) {
00348 int i, j;
00349 Vect<T_> z(_size);
00350 for (i=0; i<int(_size); i++) {
00351 T_ s = 0;
00352 for (j=int(_a->getRowPtr(i+1)); j<=int(_id[i])-1; j++)
00353 s += (*_a)[j-1] * z(_a->getColInd(j));
00354 z[i] = _pivot[i] * (b[i]-s);
00355 }
00356 for (i=int(_size-1); i>=0; i--) {
00357 T_ s = 0;
00358 for (j=int(_id[i]+1); j<=int(_a->getRowPtr(i+2))-1; j++)
00359 s += (*_a)[j-1] * x(_a->getColInd(j));
00360 x[i] = z[i] - _pivot[i] * s;
00361 }
00362 }
00363 else
00364 ;
00365 }
00366
00369 void TransSolve(Vect<T_> &x) const
00370 {
00371 if (_type==DIAG_PREC) {
00372 Solve(x);
00373 }
00374 else if (_type==ILU_PREC) {
00375 int i, j;
00376 Vect<T_> z(_size), temp(x);
00377 T_ tmp;
00378 for (i=0; i<int(_size); i++) {
00379 z[i] = temp[i];
00380 tmp = _pivot[i] * z[i];
00381 for (j=_id[i]+1; j<=int(_a->getRowPtr(i+2))-1; j++)
00382 temp(_a->getColInd(j)) -= tmp * (*_a)(j);
00383 }
00384 for (i=_size-1; i>=0; i--) {
00385 x[i] = _pivot[i] * z[i];
00386 for (j=_a->getRowPtr(i+1); j<=int(_id[i])-1; j++)
00387 z(_a->getColInd(j)) -= (*_a)(j) * x[i];
00388 }
00389 }
00390 else
00391 ;
00392 }
00393
00394
00399 void TransSolve(const Vect<T_> &b, Vect<T_> &x) const { x = b; TransSolve(x); }
00400
00402 T_ & getPivot(size_t i) const { return _pivot[i-1]; }
00403
00404 private:
00405 valarray<T_> _pivot;
00406 valarray<size_t> _id;
00407 const SpMatrix<T_> *_a;
00408 size_t _size;
00409 int _type;
00410
00411 int inv_diag()
00412 {
00413 for (size_t i=1; i<=_a->getNbRows(); i++) {
00414 if ((*_a)(i,i) == T_(0.))
00415 return i;
00416 if ((_pivot[i-1]=T_(1.)/(*_a)(i,i)) == T_(0.))
00417 return -int(i);
00418 }
00419 return 0;
00420 }
00421 };
00422
00423
00424
00425
00426
00437 template<class T_> class Precond
00438 {
00439
00440 public :
00441
00443 Precond() { }
00444
00446 Precond (const Matrix<T_> *A) { }
00447
00449 virtual ~Precond() { }
00450
00451 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00452 virtual void Solve(Vect<T_> &x) const = 0;
00453 virtual void Solve(const Vect<T_> &b, Vect<T_> &x) const = 0;
00454 virtual void TransSolve(Vect<T_> &x) const = 0;
00455 virtual void TransSolve(const Vect<T_> &b, Vect<T_> &x) const = 0;
00456 #endif
00457
00458 protected:
00459 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00460 valarray<T_> _pivot;
00461 valarray<size_t> _id;
00462 const Matrix<T_> *_a;
00463 size_t _size;
00464 #endif
00465
00466 };
00467
00468
00469
00470
00471
00483 template<class T_,class M_> class IdentPrec
00484 {
00485
00486 public:
00487
00489 IdentPrec(const M_ &A);
00490
00492 ~IdentPrec();
00493
00496 void Solve(Vect<T_> &x) const;
00497
00502 void Solve(const Vect<T_> &b, Vect<T_> &x) const;
00503
00506 void TransSolve(Vect<T_> &x) const { }
00507
00512 void TransSolve(const Vect<T_> &b, Vect<T_> &x) const;
00513
00514 };
00515
00516
00517
00518
00519
00520
00521
00522 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00523
00535 template<class T_> class IdentPrecond : virtual public Precond<T_>
00536 {
00537
00538 public:
00539
00541 IdentPrecond(const Matrix<T_> *A);
00542
00544 ~IdentPrecond();
00545
00548 void Solve(Vect<T_> &x) const { }
00549
00554 void Solve(const Vect<T_> &b, Vect<T_> &x) const;
00555
00558 void TransSolve(Vect<T_> &x) const { }
00559
00564 void TransSolve(const Vect<T_> &b, Vect<T_> &x) const;
00565
00566 };
00567 #endif
00568
00569
00570
00571
00572
00573
00586 template<class T_, class M_> class DiagPrec
00587 {
00588
00589 public:
00590
00592 DiagPrec(const M_ &a)
00593 {
00594 _size = a.getSize();
00595 _pivot.resize(_size);
00596 _a = &a;
00597 int i;
00598 if ((i = inv_diag(_size, *_a, _pivot)) != 0) {
00599 cerr << "\n*** Fatal Error in OFELI ***\nIn DiagPrec::DiagPrec(M_ &) : ";
00600 cerr << "Zero detected in element " << i << endl;
00601 cerr << "Program stops\n";
00602 exit(1);
00603 }
00604 #ifdef _OFELI_DEBUG
00605 std::clog << "An instance of class DiagPrec is constructed.\n";
00606 std::clog << "File : " << __FILE__ << ", Line : " << __LINE__ << endl;
00607 #endif
00608 }
00609
00611 ~DiagPrec()
00612 {
00613 #ifdef _OFELI_DEBUG
00614 std::clog << "An instance of class DiagPrec is constructed.\n";
00615 std::clog << "File : " << __FILE__ << ", Line : " << __LINE__ << endl;
00616 #endif
00617 }
00618
00621 void Solve(Vect<T_> &x) const
00622 {
00623 for (size_t i=0; i<_size; i++)
00624 x[i] *= _pivot[i];
00625 }
00626
00631 void Solve(const Vect<T_> &b, Vect<T_> &x) const
00632 {
00633 for (size_t i=0; i<_size; i++)
00634 x[i] = b[i] * _pivot[i];
00635 }
00636
00639 void TransSolve(Vect<T_> &x) const { Solve(x); }
00640
00644 void TransSolve(const Vect<T_> &b, Vect<T_> &x) const { Solve(b,x); }
00645
00647 const T_ & getDiag(size_t i) const { return _pivot[i-1]; }
00648
00650 T_ & getPivot(size_t i) const { return _pivot[i-1]; }
00651
00652 private:
00653 valarray<T_> _pivot;
00654 const M_ *_a;
00655 size_t _size;
00656 };
00657
00658
00659
00660
00661
00662
00663 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00664 template<class T_> class DiagPrecond : virtual public Precond<T_>
00665 {
00666
00667 public:
00668
00670 DiagPrecond(const Matrix<T_> *a)
00671 {
00672 _size = a->getSize();
00673 _pivot.resize(_size);
00674 _a = a;
00675 int i;
00676 if ((i = inv_diag(_size, _a, _pivot)) != 0) {
00677 cerr << "\n*** Fatal Error in OFELI ***\nIn DiagPrecond::DiagPrecond(...) : ";
00678 cerr << "Zero detected in element " << i << endl;
00679 cerr << "Program stops\n";
00680 exit(1);
00681 }
00682 #ifdef _OFELI_DEBUG
00683 std::clog << "An instance of class DiagPrecond is constructed.\n";
00684 std::clog << "File : " << __FILE__ << ", Line : " << __LINE__ << endl;
00685 #endif
00686 }
00687
00689 ~DiagPrecond()
00690 {
00691 #ifdef _OFELI_DEBUG
00692 std::clog << "An instance of class DiagPrecond is constructed.\n";
00693 std::clog << "File : " << __FILE__ << ", Line : " << __LINE__ << endl;
00694 #endif
00695 }
00696
00699 void Solve(Vect<T_> &x) const
00700 {
00701 for (size_t i=0; i<_size; i++)
00702 x[i] *= _pivot[i];
00703 }
00704
00709 void Solve(const Vect<T_> &b, Vect<T_> &x) const
00710 {
00711 for (size_t i=0; i<_size; i++)
00712 x[i] = b[i] * _pivot[i];
00713 }
00714
00717 void TransSolve(Vect<T_> &x) const { Solve(x); }
00718
00723 void TransSolve(const Vect<T_> &b, Vect<T_> &x) const { Solve(b,x); }
00724
00726 const T_ & getDiag(size_t i) const { return _pivot[i-1]; }
00727
00729 T_ & getPivot(size_t i) const { return _pivot[i-1]; }
00730
00731 using Precond<T_>::_size;
00732 using Precond<T_>::_pivot;
00733 using Precond<T_>::_a;
00734 };
00735 #endif
00736
00737
00738
00739
00740
00741
00753 template<class T_, class M_> class ILUPrec
00754 {
00755
00756 public:
00757
00760 ILUPrec() {
00761 #ifdef _OFELI_DEBUG
00762 std::clog << "An instance of class ILUPrec is constructed.\n";
00763 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00764 #endif
00765 }
00766
00768 ILUPrec(const M_ &a) {
00769 setMatrix(a);
00770 #ifdef _OFELI_DEBUG
00771 std::clog << "An instance of class ILUPrec is constructed.\n";
00772 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
00773 #endif
00774 }
00775
00777 ~ILUPrec()
00778 {
00779 #ifdef _OFELI_DEBUG
00780 std::clog << "An instance of class ILUPrec is destructed.\n";
00781 std::clog << "File : " << __FILE__ << ", Line : " << __LINE__ << endl;
00782 #endif
00783 }
00784
00787 void setMatrix(const M_ &a)
00788 {
00789 size_t i, j, k=1;
00790 _size = a.getSize();
00791 _pivot.resize(_size);
00792 _id.resize(_size);
00793 _a = &a;
00794 for (i=0; i<_size; i++) {
00795 for (j=_a->getRowPtr(i+1); j<_a->getRowPtr(i+2); j++,k++) {
00796 if (_a->getColInd(j)==i+1) {
00797 _id[i] = k;
00798 if ((*_a)(k)==0) {
00799 cerr << "\n*** Fatal Error in OFELI ***\nIn ILUPrec::setMatrix(M_ &) : ";
00800 cerr << "Zero detected in element " << i+1 << endl;
00801 cerr << "Program stops\n";
00802 exit(1);
00803 }
00804 _pivot[i] = (*_a)(k);
00805 }
00806 }
00807 }
00808
00809 bool found;
00810 T_ c = 0;
00811 for (i=0; i<_size; i++) {
00812 _pivot[i] = 1./_pivot[i];
00813 for (j=_id[i]+1; j<=_a->getRowPtr(i+2)-1; j++) {
00814 found = false;
00815 size_t l = _a->getColInd(j);
00816 for (k=_a->getRowPtr(l); k<=_id[l-1]-1; k++) {
00817 if (_a->getColInd(k)==i+1) {
00818 found = true;
00819 c = (*_a)(k);
00820 }
00821 }
00822 if (found)
00823 _pivot[l-1] -= c * _pivot[i] * (*_a)(j);
00824 }
00825 }
00826 }
00827
00830 void Solve(Vect<T_> &x) const
00831 {
00832 int i, j;
00833 Vect<T_> z(_size);
00834 for (i=0; i<_size; i++) {
00835 T_ s = 0;
00836 for (j=_a->getRowPtr(i+1); j<=_id[i]-1; j++)
00837 s += (*_a)[j-1] * z(_a->getColInd(j));
00838 z[i] = _pivot[i] * (x[i]-s);
00839 }
00840 for (i=_size-1; i>=0; i--) {
00841 T_ s = 0;
00842 for (j=_id[i]+1; j<=_a->getRowPtr(i+2)-1; j++) {
00843 s += (*_a)[j-1] * x(_a->getColInd(j));
00844 x[i] = z[i] - _pivot[i] * s;
00845 }
00846 }
00847 }
00848
00853 void Solve(const Vect<T_> &b, Vect<T_> &x) const
00854 {
00855 int i, j;
00856 Vect<T_> z(_size);
00857 for (i=0; i<int(_size); i++) {
00858 T_ s = 0;
00859 for (j=int(_a->getRowPtr(i+1)); j<=int(_id[i])-1; j++)
00860 s += (*_a)[j-1] * z(_a->getColInd(j));
00861 z[i] = _pivot[i] * (b[i]-s);
00862 }
00863 for (i=int(_size-1); i>=0; i--) {
00864 T_ s = 0;
00865 for (j=int(_id[i]+1); j<=int(_a->getRowPtr(i+2))-1; j++)
00866 s += (*_a)[j-1] * x(_a->getColInd(j));
00867 x[i] = z[i] - _pivot[i] * s;
00868 }
00869 }
00870
00873 void TransSolve(Vect<T_> &x) const
00874 {
00875 int i, j;
00876 Vect<T_> z(_size), temp(x);
00877 T_ tmp;
00878
00879 for (i=0; i<_size; i++) {
00880 z[i] = temp[i];
00881 tmp = _pivot[i] * z[i];
00882 for (j=_id[i]+1; j<=_a->getRowPtr(i+2)-1; j++)
00883 temp(_a->getColInd(j)) -= tmp * (*_a)(j);
00884 }
00885
00886 for (i=_size-1; i>=0; i--) {
00887 x[i] = _pivot[i] * z[i];
00888 for (j=_a->getRowPtr(i+1); j<=_id[i]-1; j++)
00889 z(_a->getColInd(j)) -= (*_a)(j) * x[i];
00890 }
00891 }
00892
00896 void TransSolve(const Vect<T_> &b, Vect<T_> &x) const { x = b; TransSolve(x); }
00897
00899 T_ & getPivot(size_t i) const { return _pivot[i-1]; }
00900
00901 private:
00902 valarray<T_> _pivot;
00903 valarray<size_t> _id;
00904 const M_ *_a;
00905 size_t _size;
00906 };
00907
00908
00909
00910
00911
00912 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00913 template<class T_> class ILUPrecond : virtual public Precond<T_>
00914 {
00915
00916 public:
00917
00919 ILUPrecond(const Matrix<T_> *A)
00920 {
00921 size_t i, j, k=1;
00922 _size = A->getSize();
00923 _pivot.resize(_size);
00924 _id.resize(_size);
00925 _a = A;
00926
00927 for (i=0; i<_size; i++) {
00928 for (j=_a->getRowPtr(i+1); j<_a->getRowPtr(i+2); j++) {
00929 size_t jj = _a->getColInd(j);
00930 if (jj==i+1) {
00931 _id[i] = k;
00932 if ((*_a)(i+1,i+1)==0) {
00933 cerr << "\n*** Fatal Error in OFELI ***\nIn ILUPrecond::ILUPrecond(...) : ";
00934 cerr << "Zero detected in element " << i+1 << endl;
00935 cerr << "Program stops\n";
00936 exit(1);
00937 }
00938 _pivot[i] = (*_a)(i+1,i+1);
00939 }
00940 k++;
00941 }
00942 }
00943 T_ c = 0;
00944 for (i=0; i<_size; i++) {
00945 _pivot[i] = T_(1)/_pivot[i];
00946 for (j=_id[i]+1; j<=_a->getRowPtr(i+2)-1; j++) {
00947 bool found = false;
00948 size_t l = _a->getColInd(j);
00949 for (k=_a->getRowPtr(l); k<=_id[l-1]-1; k++) {
00950 if (_a->getColInd(k)==i+1) {
00951 found = true;
00952 c = (*_a)(i+1,i+1);
00953 }
00954 }
00955 if (found)
00956 _pivot[l-1] -= c * _pivot[i] * (*_a)(i+1,l);
00957 }
00958 }
00959 #ifdef _OFELI_DEBUG
00960 std::clog << "An instance of class ILUPrecond is constructed.\n";
00961 std::clog << "File : " << __FILE__ << ", Line : " << __LINE__ << endl;
00962 #endif
00963 }
00964
00966 ~ILUPrecond()
00967 {
00968 #ifdef _OFELI_DEBUG
00969 std::clog << "An instance of class ILUPrecond is destructed.\n";
00970 std::clog << "File : " << __FILE__ << ", Line : " << __LINE__ << endl;
00971 #endif
00972 }
00973
00976 void Solve(Vect<T_> &x) const
00977 {
00978 size_t i, j;
00979 Vect<T_> z(_size);
00980 for (i=0; i<_size; i++) {
00981 T_ s = 0;
00982 for (j=_a->getRowPtr(i+1); j<=_id[i]-1; j++) {
00983 size_t k = _a->getColInd(j);
00984 s += (*_a)(i+1,k) * z[k-1];
00985 }
00986 z[i] = _pivot[i] * (x[i]-s);
00987 }
00988
00989 for (int ii=int(_size-1); ii>=0; ii--) {
00990 T_ s = 0;
00991 for (j=_id[ii]+1; j<=_a->getRowPtr(ii+2)-1; j++) {
00992 size_t k = _a->getColInd(j);
00993 s += (*_a)(ii+1,k) * x[k-1];
00994 }
00995 x[ii] = z[ii] - _pivot[ii] * s;
00996 }
00997 }
00998
01003 void Solve(const Vect<T_> &b, Vect<T_> &x) const { x = b; Solve(x); }
01004
01007 void TransSolve(Vect<T_> &x) const
01008 {
01009
01010 if (x.size()==0) { }
01011 }
01012
01017 void TransSolve(const Vect<T_> &b, Vect<T_> &x) const { x = b; TransSolve(x); }
01018
01020 T_ & getPivot(size_t i) const { return _pivot[i-1]; }
01021
01022
01023 using Precond<T_>::_size;
01024 using Precond<T_>::_pivot;
01025 using Precond<T_>::_id;
01026 using Precond<T_>::_a;
01027 };
01028 #endif
01029
01030
01032
01034
01035 template<class T_,class M_>
01036 IdentPrec<T_,M_>::IdentPrec(const M_ &A)
01037 {
01038 A.getNbRows();
01039 #ifdef _OFELI_DEBUG
01040 std::clog << "An instance of class IdentPrec is constructed.\n";
01041 std::clog << "File : " << __FILE__ << ", Line : " << __LINE__ << endl;
01042 #endif
01043 }
01044
01045
01046 template<class T_,class M_>
01047 IdentPrec<T_,M_>::~IdentPrec()
01048 {
01049 #ifdef _OFELI_DEBUG
01050 std::clog << "An instance of class IdentPrec is destructed.\n";
01051 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
01052 #endif
01053 }
01054
01055
01056 template<class T_,class M_>
01057 void IdentPrec<T_,M_>::Solve(Vect<T_> &x) const
01058 {
01059 x.size();
01060 }
01061
01062
01063 template<class T_,class M_>
01064 void IdentPrec<T_,M_>::Solve(const Vect<T_> &b, Vect<T_> &x) const
01065 {
01066 x = b;
01067 }
01068
01069 template<class T_,class M_>
01070 void IdentPrec<T_,M_>::TransSolve(const Vect<T_> &b, Vect<T_> &x) const
01071 {
01072 x = b;
01073 }
01074
01075
01076 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01077 template<class T_>
01078 IdentPrecond<T_>::IdentPrecond(const Matrix<T_> *A)
01079 {
01080 #ifdef _OFELI_DEBUG
01081 std::clog << "An instance of class IdentPrecond is constructed.\n";
01082 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
01083 #endif
01084 }
01085 #endif
01086
01087
01088 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01089 template<class T_>
01090 IdentPrecond<T_>::~IdentPrecond()
01091 {
01092 #ifdef _OFELI_DEBUG
01093 std::clog << "An instance of class IdentPrecond is destructed.\n";
01094 std::clog << "File: " << __FILE__ << ", Line: " << __LINE__ << endl;
01095 #endif
01096 }
01097 #endif
01098
01099
01100 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01101 template<class T_>
01102 void IdentPrecond<T_>::Solve(const Vect<T_> &b, Vect<T_> &x) const
01103 {
01104 x = b;
01105 }
01106 #endif
01107
01108
01109 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01110 template<class T_>
01111 void IdentPrecond<T_>::TransSolve(const Vect<T_> &b, Vect<T_> &x) const
01112 {
01113 x = b;
01114 }
01115 #endif
01116
01117 }
01118
01119 #endif