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 #ifndef _ILU0_PRECONDITIONER_H_
00032 #define _ILU0_PRECONDITIONER_H_
00033
00034 #include "Preconditioner.h"
00035 #include "SparseRowMatrix.h"
00036 #include "RealVector.h"
00037 #include <stdio.h>
00038 #include <string>
00039
00040 namespace FDDlib {
00041
00046 class ILU0Preconditioner : public Preconditioner
00047 {
00048 private:
00050 SparseRowMatrix<double> SRMD_;
00052 RealVector<double> invDiag_;
00053
00054 public:
00056 ILU0Preconditioner() {len_ = 0;}
00058 ~ILU0Preconditioner() {}
00059
00063 void init(SparseRowMatrix<double>& srmd) throw(std::string)
00064 {
00065 int i,j,k,l,m;
00066 double v;
00067
00068
00069
00070
00071
00072
00073 SRMD_ = srmd;
00074
00075 len_ = SRMD_.getNumRows();
00076 invDiag_.init(len_);
00077
00078 for (i = 1; i < len_; i++)
00079 {
00080 for (j = 0; j < SRMD_.getNumCols(i); j++)
00081 {
00082 k = SRMD_.getCol(i,j);
00083 if (k < i)
00084 {
00085 v = SRMD_.val(i,k)/SRMD_.val(k,k);
00086 SRMD_.set(i,k,v);
00087 for (l = 0; l < SRMD_.getNumCols(i); l++)
00088 {
00089 m = SRMD_.getCol(i,l);
00090 if (m > k)
00091 {
00092 v = SRMD_.val(i,m) - SRMD_.val(i,k)*SRMD_.val(k,m);
00093 SRMD_.set(i,m,v);
00094 }
00095 }
00096 }
00097 }
00098 }
00099
00100 for (i = 0; i < len_; i++)
00101 {
00102 invDiag_(i) = 1/SRMD_.val(i,i);
00103 }
00104
00105 }
00106
00107
00113 template<class Vector>
00114 Vector lowerSolve(const Vector& x) const
00115 {
00117 int i, j;
00119 int cols, col;
00121 Vector r(len_);
00123 SparseRowEntry<double>* ep;
00125 double v;
00126
00128 for (i = 0; i < len_; i++)
00129 {
00130 if (i == 0)
00131 {
00132 r(i) = invDiag_(i)*x(i);
00133 r(i) = x(i);
00134 }
00135 else
00136 {
00137 cols = SRMD_.getNumCols(i);
00138 ep = SRMD_.getRowEntry(i);
00139 v = 0;
00140 for (j = 0; j < cols; j++)
00141 {
00142 col = ep->column;
00143 if (col < i)
00144 {
00145 v += (ep->val)*r(col);
00146 }
00147 ep++;
00148 }
00149 v = x(i) - v;
00150 r(i) = v;
00151 }
00152 }
00153
00155 return r;
00156 }
00157
00163 template<class Vector>
00164 Vector upperSolve(const Vector& x) const
00165 {
00167 int i, j;
00169 int cols, col;
00171 Vector r(len_);
00173 SparseRowEntry<double>* ep;
00175 double v;
00176
00178 for (i = len_ - 1; i >= 0; i--)
00179 {
00180 if (i == len_ - 1)
00181 {
00182 r(i) = invDiag_(i)*x(i);
00183 }
00184 else
00185 {
00186 cols = SRMD_.getNumCols(i);
00187 v = 0;
00188 ep = SRMD_.getRowEntry(i);
00189 for (j = 0; j < cols; j++)
00190 {
00191 col = ep->column;;
00192 if (col > i)
00193 {
00194 v += (ep->val)*r(col);
00195 }
00196 ep++;
00197 }
00198 v = x(i) - v;
00199 v *= invDiag_(i);
00200 r(i) = v;
00201 }
00202 }
00203
00205 return r;
00206 }
00207
00208
00214 RealVector<double> solve(const RealVector<double>& x) const
00215 {
00216 RealVector<double> u(len_);
00217 RealVector<double> l(len_);
00218
00219 l = lowerSolve(x);
00220 u = upperSolve(l);
00221
00222
00223 return u;
00224
00225 }
00226
00227
00228 };
00229 }
00230 #endif
00231