00001
00022 #ifndef TBCI_SOLVER_ILU0PRECOND_H
00023 #define TBCI_SOLVER_ILU0PRECOND_H
00024
00025 #include "precond.h"
00026
00027 NAMESPACE_TBCI
00028
00029 template <typename T> class Symm_BdMatrix;
00030
00034 template <typename T>
00035 class ILU0_Symm_BdMatrixPreconditioner : public Preconditioner_Sig<T, Symm_BdMatrix<T> >
00036 {
00037 public:
00038 ILU0_Symm_BdMatrixPreconditioner () : matrix(0) {}
00039 ILU0_Symm_BdMatrixPreconditioner (const Symm_BdMatrix<T> &A)
00040 { update (A); }
00041 ~ILU0_Symm_BdMatrixPreconditioner () {}
00042
00043
00044
00045 void update (const Symm_BdMatrix<T> &A);
00046
00047
00048
00049 TVector<T> solve (TVector<T> x) const;
00050
00051
00052 inline TVector<T> solve (const Vector<T> &v) const
00053 {
00054 TVector<T> tv(v);
00055 return (solve(tv));
00056 }
00057
00058
00059
00060 inline TVector<T> transSolve (const Vector<T> &v) const
00061 { return solve(v); }
00062
00063 inline TVector<T> transSolve (TVector<T> tv) const
00064 { return solve(tv); }
00065
00066 private:
00067 BVector<T> pivots;
00068 const Symm_BdMatrix<T> *matrix;
00069
00070
00071 BVector<unsigned int> conf;
00072 unsigned int dimension;
00073 BVector<T*> rowPtr;
00074 };
00075
00076 template<typename T>
00077 void ILU0_Symm_BdMatrixPreconditioner<T>::update (const Symm_BdMatrix<T> &A)
00078 {
00079 matrix = &A;
00080 if (pivots.size() != matrix->rows())
00081 pivots.resize(matrix->rows());
00082 if (UNLIKELY(pivots.size() == 0))
00083 STD__ cerr << "\n NULL pointer encountered! \n" << STD__ flush;
00084 for (unsigned int i=0; i<matrix->rows(); ++i)
00085 pivots(i) = T(1.0)/(*matrix)(i,i);
00086
00087 conf.resize(matrix->conf);
00088 dimension = matrix->dimension;
00089 rowPtr.resize(matrix->rowPtr);
00090 }
00091
00092
00093 template<typename T>
00094 TVector<T> ILU0_Symm_BdMatrixPreconditioner<T>::solve (TVector<T> y) const
00095 {
00096 unsigned int* confPtr;
00097 T* elementPtr;
00098 ALIGN2(register T sum, MIN_ALIGN2);
00099
00100 const unsigned int csize = conf.size();
00101
00102
00103 if (LIKELY(csize == 0)) {
00104 for (unsigned int i=0; i<dimension; ++i)
00105 y.setval(i) = pivots(i)*y.get(i);
00106 return y;
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116 for (int g = 0; g < (int)dimension; ++g) {
00117 sum = (T)0.0;
00118 int cnfi;
00119 for (unsigned int i=0; (i<csize) && ((cnfi = conf(i)) <= g);) {
00120 elementPtr = rowPtr(g - cnfi) + ++i;
00121 sum += (*elementPtr) * y.get(g - cnfi);
00122 }
00123
00124 y.setval(g) = pivots(g) * (y.get(g) - sum);
00125 }
00126
00127
00128
00129
00130
00131 for (int h = dimension-2; h >= 0; --h)
00132 {
00133 confPtr = conf.vecptr();
00134 elementPtr = rowPtr(h) +1;
00135
00136 sum = (T)0.0;
00137 while (elementPtr != rowPtr(h+1)) {
00138 sum += (*elementPtr) * y.get(h + (*confPtr));
00139 confPtr++;
00140 elementPtr++;
00141 }
00142
00143 y.setval(h) -= pivots(h) * sum;
00144 }
00145
00146
00147 return y;
00148 }
00149
00150
00151
00152
00153
00154
00155
00156 template <typename T> class BdMatrix;
00157
00161 template <typename T>
00162 class ILU0_BdMatrixPreconditioner : public Preconditioner_Sig<T, BdMatrix<T> >
00163 {
00164 public:
00165 ILU0_BdMatrixPreconditioner () {}
00166 ILU0_BdMatrixPreconditioner (const BdMatrix<T> &A)
00167 { update(A); }
00168 ~ILU0_BdMatrixPreconditioner () {}
00169
00170
00171 void update (const BdMatrix<T> &A);
00172
00173
00174 TVector<T> solve (TVector<T> x) const;
00175
00176 inline TVector<T> solve (const Vector<T> &v) const
00177 {
00178 TVector<T> tv(v);
00179 return (solve(tv));
00180 }
00181
00182
00183 inline TVector<T> transSolve (const Vector<T> &v) const
00184 { return solve(v); }
00185
00186 inline TVector<T> transSolve ( TVector<T> tv) const
00187 { return solve(tv); }
00188
00189 private:
00190 BVector<T> pivots;
00191
00192 BVector<T*> ldiag, udiag;
00193 BVector<unsigned int> bdconf;
00194
00195 unsigned int dimension;
00196 };
00197
00198 template <typename T>
00199 void ILU0_BdMatrixPreconditioner<T>::update (const BdMatrix<T> &A)
00200 {
00201
00202 dimension = A.dim;
00203 udiag.resize(A.adiag); ldiag.resize(A.bdiag);
00204
00205
00206 if (pivots.size() != dimension)
00207 pivots.resize(dimension);
00208 BCHK(pivots.size() == 0, VecErr, "ILU0_BdMPrecond::update: Null ptr", 0,);
00209 for (unsigned i = 0; i < dimension; ++i)
00210 pivots(i) = T(1.0) / A(i,i);
00211
00212
00213 bdconf.resize(A.diagconf);
00214 }
00215
00217 template <typename T>
00218 TVector<T> ILU0_BdMatrixPreconditioner<T>::solve(TVector<T> y) const
00219 {
00220 ALIGN2(register T sum, MIN_ALIGN2);
00221
00222
00223 BCHK(dimension != y.size(), VecErr, "ILU0_BdMPrecond::solve: Dims don't match", dimension, y);
00224
00225
00226 if (bdconf.size() == 0) {
00227 for (unsigned int i=0; i<dimension; ++i)
00228 y.setval(i) *= pivots(i);
00229 return y;
00230 }
00231
00232
00233
00234
00235
00236
00237
00238 y.setval(0) = pivots(0) * (y.get(0));
00239 int h;
00240 const unsigned int bsize = bdconf.size();
00241 for (h = 1; h < (int)dimension; ++h) {
00242 sum = (T)0; int bdi;
00243 for (unsigned int i=0; i < bsize && (bdi = bdconf(i)) <= h; ++i)
00244 sum += (*(ldiag(bdi) + h-bdi)) * y.get (h-bdi);
00245 y.setval(h) = pivots(h) * (y.get(h) - sum);
00246 }
00247
00248
00249
00250
00251
00252
00253 for (h = dimension-2; h >= 0; --h) {
00254 sum = (T)0; int bdi;
00255 for (unsigned int i=0; i < bsize && (bdi = bdconf(i))+h < (int)dimension; ++i)
00256 sum += (*(udiag(bdi) + h)) * y.get(bdi + h);
00257 y.setval(h) -= pivots(h) * sum;
00258 }
00259
00260
00261 return y;
00262 }
00263
00264 NAMESPACE_END
00265
00266 #endif