ilu.hh
Go to the documentation of this file.00001 #ifndef DUNE_ILU_HH
00002 #define DUNE_ILU_HH
00003
00004 #include<cmath>
00005 #include<complex>
00006 #include<iostream>
00007 #include<iomanip>
00008 #include<string>
00009 #include<set>
00010 #include<map>
00011
00012 #include "istlexception.hh"
00013 #include "io.hh"
00014
00019 namespace Dune {
00020
00025 class MatrixBlockError : public virtual Dune::FMatrixError {
00026 public:
00027 int r, c;
00028 };
00029
00030
00032 template<class M>
00033 void bilu0_decomposition (M& A)
00034 {
00035
00036 typedef typename M::RowIterator rowiterator;
00037 typedef typename M::ColIterator coliterator;
00038 typedef typename M::block_type block;
00039
00040
00041 rowiterator endi=A.end();
00042 for (rowiterator i=A.begin(); i!=endi; ++i)
00043 {
00044
00045 coliterator endij=(*i).end();
00046 coliterator ij;
00047
00048
00049 for (ij=(*i).begin(); ij.index()<i.index(); ++ij)
00050 {
00051
00052 coliterator jj = A[ij.index()].find(ij.index());
00053
00054
00055 (*ij).rightmultiply(*jj);
00056
00057
00058 coliterator endjk=A[ij.index()].end();
00059 coliterator jk=jj; ++jk;
00060 coliterator ik=ij; ++ik;
00061 while (ik!=endij && jk!=endjk)
00062 if (ik.index()==jk.index())
00063 {
00064 block B(*jk);
00065 B.leftmultiply(*ij);
00066 *ik -= B;
00067 ++ik; ++jk;
00068 }
00069 else
00070 {
00071 if (ik.index()<jk.index())
00072 ++ik;
00073 else
00074 ++jk;
00075 }
00076 }
00077
00078
00079 if (ij.index()!=i.index())
00080 DUNE_THROW(ISTLError,"diagonal entry missing");
00081 try {
00082 (*ij).invert();
00083 }
00084 catch (Dune::FMatrixError & e) {
00085 DUNE_THROW(MatrixBlockError, "ILU failed to invert matrix block A["
00086 << i.index() << "][" << ij.index() << "]" << e.what();
00087 th__ex.r=i.index(); th__ex.c=ij.index(););
00088 }
00089 }
00090 }
00091
00093 template<class M, class X, class Y>
00094 void bilu_backsolve (const M& A, X& v, const Y& d)
00095 {
00096
00097 typedef typename M::ConstRowIterator rowiterator;
00098 typedef typename M::ConstColIterator coliterator;
00099 typedef typename Y::block_type dblock;
00100 typedef typename X::block_type vblock;
00101
00102
00103 rowiterator endi=A.end();
00104 for (rowiterator i=A.begin(); i!=endi; ++i)
00105 {
00106 dblock rhs(d[i.index()]);
00107 for (coliterator j=(*i).begin(); j.index()<i.index(); ++j)
00108 (*j).mmv(v[j.index()],rhs);
00109 v[i.index()] = rhs;
00110 }
00111
00112
00113 rowiterator rendi=A.rend();
00114 for (rowiterator i=A.rbegin(); i!=rendi; --i)
00115 {
00116 vblock rhs(v[i.index()]);
00117 coliterator j;
00118 for (j=(*i).rbegin(); j.index()>i.index(); --j)
00119 (*j).mmv(v[j.index()],rhs);
00120 v[i.index()] = 0;
00121 (*j).umv(rhs,v[i.index()]);
00122 }
00123 }
00124
00125
00126
00127
00128 template<class M>
00129 typename M::field_type& firstmatrixelement (M& A)
00130 {
00131 return firstmatrixelement(*(A.begin()->begin()));
00132 }
00133
00134 template<class K, int n, int m>
00135 K& firstmatrixelement (FieldMatrix<K,n,m>& A)
00136 {
00137 return A[0][0];
00138 }
00139
00140 template<class K>
00141 K& firstmatrixelement (FieldMatrix<K,1,1>& A)
00142 {
00143 return A[0][0];
00144 }
00145
00146
00153 template<class M>
00154 void bilu_decomposition (const M& A, int n, M& ILU)
00155 {
00156
00157 typedef typename M::RowIterator rowiterator;
00158 typedef typename M::ColIterator coliterator;
00159 typedef typename M::ConstRowIterator crowiterator;
00160 typedef typename M::ConstColIterator ccoliterator;
00161 typedef typename M::CreateIterator createiterator;
00162 typedef typename M::block_type block;
00163 typedef typename M::field_type K;
00164 typedef typename std::map<int,int> map;
00165 typedef typename std::map<int,int>::iterator mapiterator;
00166
00167
00168 crowiterator endi=A.end();
00169 createiterator ci=ILU.createbegin();
00170 for (crowiterator i=A.begin(); i!=endi; ++i)
00171 {
00172
00173 map rowpattern;
00174
00175
00176 for (ccoliterator j=(*i).begin(); j!=(*i).end(); ++j)
00177 rowpattern[j.index()] = 0;
00178
00179
00180 for (mapiterator ik=rowpattern.begin(); (*ik).first<i.index(); ++ik)
00181 {
00182 if ((*ik).second<n)
00183 {
00184
00185
00186
00187 coliterator endk = ILU[(*ik).first].end();
00188 coliterator kj = ILU[(*ik).first].find((*ik).first);
00189 for (++kj; kj!=endk; ++kj)
00190 {
00191 int generation = (int) firstmatrixelement(*kj);
00192 if (generation<n)
00193 {
00194 mapiterator ij = rowpattern.find(kj.index());
00195 if (ij==rowpattern.end())
00196 {
00197
00198
00199
00200 rowpattern[kj.index()] = generation+1;
00201 }
00202 }
00203 }
00204 }
00205 }
00206
00207
00208 for (mapiterator ik=rowpattern.begin(); ik!=rowpattern.end(); ++ik)
00209 ci.insert((*ik).first);
00210 ++ci;
00211
00212
00213 coliterator endILUij = ILU[i.index()].end();;
00214 for (coliterator ILUij=ILU[i.index()].begin(); ILUij!=endILUij; ++ILUij)
00215 firstmatrixelement(*ILUij) = (K) rowpattern[ILUij.index()];
00216 }
00217
00218
00219
00220
00221 for (crowiterator i=A.begin(); i!=endi; ++i)
00222 {
00223 coliterator ILUij;
00224 coliterator endILUij = ILU[i.index()].end();;
00225 for (ILUij=ILU[i.index()].begin(); ILUij!=endILUij; ++ILUij)
00226 (*ILUij) = 0;
00227 ccoliterator Aij = (*i).begin();
00228 ccoliterator endAij = (*i).end();
00229 ILUij = ILU[i.index()].begin();
00230 while (Aij!=endAij && ILUij!=endILUij)
00231 {
00232 if (Aij.index()==ILUij.index())
00233 {
00234 *ILUij = *Aij;
00235 ++Aij; ++ILUij;
00236 }
00237 else
00238 {
00239 if (Aij.index()<ILUij.index())
00240 ++Aij;
00241 else
00242 ++ILUij;
00243 }
00244 }
00245 }
00246
00247
00248 bilu0_decomposition(ILU);
00249 }
00250
00251
00254 }
00255
00256 #endif