00001
00002
00003 #ifndef DUNE_ISTLIO_HH
00004 #define DUNE_ISTLIO_HH
00005
00006 #include<cmath>
00007 #include<complex>
00008 #include <limits>
00009 #include<ios>
00010 #include<iomanip>
00011 #include<fstream>
00012 #include<string>
00013
00014 #include "istlexception.hh"
00015 #include <dune/common/fvector.hh>
00016 #include <dune/common/fmatrix.hh>
00017 #include "bcrsmatrix.hh"
00018
00019
00020 namespace Dune {
00021
00032
00033
00034
00035 template<class V>
00036 void recursive_printvector (std::ostream& s, const V& v, std::string rowtext, int& counter,
00037 int columns, int width, int precision)
00038 {
00039 for (typename V::ConstIterator i=v.begin(); i!=v.end(); ++i)
00040 recursive_printvector(s,*i,rowtext,counter,columns,width,precision);
00041 }
00042
00043
00044 template<class K, int n>
00045 void recursive_printvector (std::ostream& s, const FieldVector<K,n>& v, std::string rowtext, int& counter,
00046 int columns, int width, int precision)
00047 {
00048
00049 for (int i=0; i<n; i++)
00050 {
00051 if (counter%columns==0)
00052 {
00053 s << rowtext;
00054 s << " ";
00055 s.width(4);
00056 s << counter;
00057 }
00058 s << " ";
00059 s.width(width);
00060 s << v[i];
00061 counter++;
00062 if (counter%columns==0)
00063 s << std::endl;
00064 }
00065 }
00066
00067
00068 template<class V>
00069 void printvector (std::ostream& s, const V& v, std::string title, std::string rowtext,
00070 int columns=1, int width=10, int precision=2)
00071 {
00072
00073 int counter=0;
00074
00075
00076 std::ios_base::fmtflags oldflags = s.flags();
00077
00078
00079 s.setf(std::ios_base::scientific, std::ios_base::floatfield);
00080 int oldprec = s.precision();
00081 s.precision(precision);
00082
00083
00084 s << title << " [blocks=" << v.N() << ",dimension=" << v.dim() << "]" << std::endl;
00085
00086
00087 recursive_printvector(s,v,rowtext,counter,columns,width,precision);
00088
00089
00090 if (counter%columns!=0)
00091 s << std::endl;
00092
00093
00094 s.flags(oldflags);
00095 s.precision(oldprec);
00096 }
00097
00098
00099
00100
00101
00103 inline void fill_row (std::ostream& s, int m, int width, int precision)
00104 {
00105 for (int j=0; j<m; j++)
00106 {
00107 s << " ";
00108 s.width(width);
00109 s << ".";
00110 }
00111 }
00112
00113 template<typename B, typename A>
00114 class BCRSMatrix;
00115
00116 template<typename K, int n, int m>
00117 class FieldMatrix;
00118
00119 template<typename M>
00120 struct MatrixDimension
00121 {
00122 };
00123
00124
00125 template<typename B, typename TA>
00126 struct MatrixDimension<BCRSMatrix<B,TA> >
00127 {
00128 typedef BCRSMatrix<B,TA> Matrix;
00129 typedef typename Matrix::block_type block_type;
00130 typedef typename Matrix::size_type size_type;
00131
00132 static size_type rowdim (const Matrix& A, size_type i)
00133 {
00134 const B* row = A.r[i].getptr();
00135 if(row)
00136 return MatrixDimension<block_type>::rowdim(*row);
00137 else
00138 return 0;
00139 }
00140
00141 static size_type coldim (const Matrix& A, size_type c)
00142 {
00143
00144 if (A.nnz>0)
00145 {
00146 for (size_type k=0; k<A.nnz; k++) {
00147 if (A.j[k]==c) {
00148 return MatrixDimension<block_type>::coldim(A.a[k]);
00149 }
00150 }
00151 }
00152 else
00153 {
00154 for (size_type i=0; i<A.N(); i++)
00155 {
00156 size_type* j = A.r[i].getindexptr();
00157 B* a = A.r[i].getptr();
00158 for (size_type k=0; k<A.r[i].getsize(); k++)
00159 if (j[k]==c) {
00160 return MatrixDimension<block_type>::coldim(a[k]);
00161 }
00162 }
00163 }
00164
00165
00166 return 0;
00167 }
00168
00169 static size_type rowdim (const Matrix& A){
00170 size_type nn=0;
00171 for (size_type i=0; i<A.N(); i++)
00172 nn += rowdim(A,i);
00173 return nn;
00174 }
00175
00176 static size_type coldim (const Matrix& A){
00177 typedef typename Matrix::ConstRowIterator ConstRowIterator;
00178 typedef typename Matrix::ConstColIterator ConstColIterator;
00179
00180
00181
00182
00183 std::vector<size_type> coldims(A.M(),std::numeric_limits<size_type>::max());
00184
00185 for (ConstRowIterator row=A.begin(); row!=A.end(); ++row)
00186 for (ConstColIterator col=row->begin(); col!=row->end(); ++col)
00187
00188 if (coldims[col.index()]==std::numeric_limits<size_type>::max())
00189 coldims[col.index()] = MatrixDimension<block_type>::coldim(*col);
00190
00191 size_type sum = 0;
00192 for (typename std::vector<size_type>::iterator it=coldims.begin(); it!=coldims.end(); ++it)
00193
00194 if ((*it)>=0)
00195 sum += *it;
00196
00197 return sum;
00198 }
00199 };
00200
00201
00202 template<typename B, int n, int m, typename TA>
00203 struct MatrixDimension<BCRSMatrix<FieldMatrix<B,n,m> ,TA> >
00204 {
00205 typedef BCRSMatrix<FieldMatrix<B,n,m> ,TA> Matrix;
00206 typedef typename Matrix::size_type size_type;
00207
00208 static size_type rowdim (const Matrix& A, size_type i)
00209 {
00210 return n;
00211 }
00212
00213 static size_type coldim (const Matrix& A, size_type c)
00214 {
00215 return m;
00216 }
00217
00218 static size_type rowdim (const Matrix& A){
00219 return A.N()*n;
00220 }
00221
00222 static size_type coldim (const Matrix& A){
00223 return A.M()*m;
00224 }
00225 };
00226
00227 template<typename K, int n, int m>
00228 struct MatrixDimension<FieldMatrix<K,n,m> >
00229 {
00230 typedef FieldMatrix<K,n,m> Matrix;
00231 typedef typename Matrix::size_type size_type;
00232
00233 static size_type rowdim(const Matrix& A, size_type r)
00234 {
00235 return 1;
00236 }
00237
00238 static size_type coldim(const Matrix& A, size_type r)
00239 {
00240 return 1;
00241 }
00242
00243 static size_type rowdim(const Matrix& A)
00244 {
00245 return n;
00246 }
00247
00248 static size_type coldim(const Matrix& A)
00249 {
00250 return m;
00251 }
00252 };
00253
00255 template<class M>
00256 void print_row (std::ostream& s, const M& A, typename M::size_type I,
00257 typename M::size_type J, typename M::size_type therow,
00258 int width, int precision)
00259 {
00260 typename M::size_type i0=I;
00261 for (typename M::size_type i=0; i<A.N(); i++)
00262 {
00263 if (therow>=i0 && therow<i0+MatrixDimension<M>::rowdim(A,i))
00264 {
00265
00266 typename M::size_type j0=J;
00267 for (typename M::size_type j=0; j<A.M(); j++)
00268 {
00269
00270 typename M::ConstColIterator it = A[i].find(j);
00271
00272
00273 if (it!=A[i].end())
00274 print_row(s,*it,i0,j0,therow,width,precision);
00275 else
00276 fill_row(s,MatrixDimension<M>::coldim(A,j),width,precision);
00277
00278
00279 j0 += MatrixDimension<M>::coldim(A,j);
00280 }
00281 }
00282
00283 i0 += MatrixDimension<M>::rowdim(A,i);
00284 }
00285 }
00286
00288 template<class K, int n, int m>
00289 void print_row (std::ostream& s, const FieldMatrix<K,n,m>& A,
00290 typename FieldMatrix<K,n,m>::size_type I, typename FieldMatrix<K,n,m>::size_type J,
00291 typename FieldMatrix<K,n,m>::size_type therow, int width, int precision)
00292 {
00293 typedef typename FieldMatrix<K,n,m>::size_type size_type;
00294
00295 for (size_type i=0; i<n; i++)
00296 if (I+i==therow)
00297 for (int j=0; j<m; j++)
00298 {
00299 s << " ";
00300 s.width(width);
00301 s << A[i][j];
00302 }
00303 }
00304
00306 template<class K>
00307 void print_row (std::ostream& s, const FieldMatrix<K,1,1>& A, typename FieldMatrix<K,1,1>::size_type I,
00308 typename FieldMatrix<K,1,1>::size_type J, typename FieldMatrix<K,1,1>::size_type therow,
00309 int width, int precision)
00310 {
00311 if (I==therow)
00312 {
00313 s << " ";
00314 s.width(width);
00315 s << static_cast<K>(A);
00316 }
00317 }
00318
00322 template<class M>
00323 void printmatrix (std::ostream& s, const M& A, std::string title, std::string rowtext,
00324 int width=10, int precision=2)
00325 {
00326
00327
00328 std::ios_base::fmtflags oldflags = s.flags();
00329
00330
00331 s.setf(std::ios_base::scientific, std::ios_base::floatfield);
00332 int oldprec = s.precision();
00333 s.precision(precision);
00334
00335
00336 s << title
00337 << " [n=" << A.N()
00338 << ",m=" << A.M()
00339 << ",rowdim=" << MatrixDimension<M>::rowdim(A)
00340 << ",coldim=" << MatrixDimension<M>::coldim(A)
00341 << "]" << std::endl;
00342
00343
00344 for (typename M::size_type i=0; i<MatrixDimension<M>::rowdim(A); i++)
00345 {
00346 s << rowtext;
00347 s << " ";
00348 s.width(4);
00349 s << i;
00350 print_row(s,A,0,0,i,width,precision);
00351 s << std::endl;
00352 }
00353
00354
00355 s.flags(oldflags);
00356 s.precision(oldprec);
00357 }
00358
00376 template<class B, int n, int m, class A>
00377 void printSparseMatrix(std::ostream& s,
00378 const BCRSMatrix<FieldMatrix<B,n,m>,A>& mat,
00379 std::string title, std::string rowtext,
00380 int width=3, int precision=2)
00381 {
00382 typedef BCRSMatrix<FieldMatrix<B,n,m>,A> Matrix;
00383
00384 std::ios_base::fmtflags oldflags = s.flags();
00385
00386 s.setf(std::ios_base::scientific, std::ios_base::floatfield);
00387 int oldprec = s.precision();
00388 s.precision(precision);
00389
00390 s << title
00391 << " [n=" << mat.N()
00392 << ",m=" << mat.M()
00393 << ",rowdim=" << MatrixDimension<Matrix>::rowdim(mat)
00394 << ",coldim=" << MatrixDimension<Matrix>::coldim(mat)
00395 << "]" << std::endl;
00396
00397 typedef typename Matrix::ConstRowIterator Row;
00398
00399 for(Row row=mat.begin(); row != mat.end();++row){
00400 int skipcols=0;
00401 bool reachedEnd=false;
00402
00403 while(!reachedEnd){
00404 for(int innerrow=0; innerrow<n; ++innerrow){
00405 int count=0;
00406 typedef typename Matrix::ConstColIterator Col;
00407 Col col=row->begin();
00408 for(; col != row->end(); ++col,++count){
00409 if(count<skipcols)
00410 continue;
00411 if(count>=skipcols+width)
00412 break;
00413 if(innerrow==0){
00414 if(count==skipcols){
00415 s << rowtext;
00416 s << " ";
00417 s.width(4);
00418 s << row.index()<<": ";
00419 }
00420 s.width(4);
00421 s<<col.index()<<": |";
00422 }else{
00423 if(count==skipcols){
00424 for(int i=0; i < rowtext.length(); i++)
00425 s<<" ";
00426 s<<" ";
00427 }
00428 s<<" |";
00429 }
00430 for(int innercol=0; innercol < m; ++innercol){
00431 s.width(9);
00432 s<<(*col)[innerrow][innercol]<<" ";
00433 }
00434
00435 s<<"|";
00436 }
00437 if(innerrow==n-1 && col==row->end())
00438 reachedEnd=true;
00439 else
00440 s<<std::endl;
00441 }
00442 skipcols+=width;
00443 s<<std::endl;
00444 }
00445 s<<std::endl;
00446 }
00447
00448
00449 s.flags(oldflags);
00450 s.precision(oldprec);
00451 }
00452
00453 namespace
00454 {
00455 template<typename T>
00456 struct MatlabPODWriter
00457 {
00458 static std::ostream& write(const T& t, std::ostream& s)
00459 {
00460 s<<t;
00461 return s;
00462 }
00463 };
00464 template<typename T>
00465 struct MatlabPODWriter<std::complex<T> >
00466 {
00467 static std::ostream& write(const std::complex<T>& t, std::ostream& s)
00468 {
00469 s<<t.real()<<" "<<t.imag();
00470 return s;
00471 }
00472 };
00473 }
00478 template <class FieldType, int rows, int cols>
00479 void writeMatrixToMatlabHelper(const FieldMatrix<FieldType,rows,cols>& matrix,
00480 int rowOffset, int colOffset,
00481 std::ostream& s)
00482 {
00483 for (int i=0; i<rows; i++)
00484 for (int j=0; j<cols; j++){
00485
00486 s << rowOffset + i + 1 << " " << colOffset + j + 1 << " ";
00487 MatlabPODWriter<FieldType>::write(matrix[i][j], s)<< std::endl;
00488 }
00489 }
00490
00491 template <class MatrixType>
00492 void writeMatrixToMatlabHelper(const MatrixType& matrix,
00493 int externalRowOffset, int externalColOffset,
00494 std::ostream& s)
00495 {
00496
00497 std::vector<typename MatrixType::size_type> colOffset(matrix.M());
00498 if (colOffset.size() > 0)
00499 colOffset[0] = 0;
00500
00501 for (typename MatrixType::size_type i=0; i<matrix.M()-1; i++)
00502 colOffset[i+1] = colOffset[i] + MatrixDimension<MatrixType>::coldim(matrix,i);
00503
00504 typename MatrixType::size_type rowOffset = 0;
00505
00506
00507 for (typename MatrixType::size_type rowIdx=0; rowIdx<matrix.N(); rowIdx++) {
00508
00509 const typename MatrixType::row_type& row = matrix[rowIdx];
00510
00511 typename MatrixType::row_type::ConstIterator cIt = row.begin();
00512 typename MatrixType::row_type::ConstIterator cEndIt = row.end();
00513
00514
00515 for (; cIt!=cEndIt; ++cIt)
00516 writeMatrixToMatlabHelper(*cIt,
00517 externalRowOffset+rowOffset,
00518 externalColOffset + colOffset[cIt.index()],
00519 s);
00520
00521 rowOffset += MatrixDimension<MatrixType>::rowdim(matrix, rowIdx);
00522 }
00523
00524 }
00525
00540 template <class MatrixType>
00541 void writeMatrixToMatlab(const MatrixType& matrix,
00542 const std::string& filename)
00543 {
00544 std::ofstream outStream(filename.c_str());
00545
00546 writeMatrixToMatlabHelper(matrix, 0, 0, outStream);
00547 }
00548
00551 }
00552
00553 #endif