- Home
- About DUNE
- Download
- Documentation
- Community
- Development
00001 #ifndef DUNE_BLOCK_TRIDIAGONAL_MATRIX_HH 00002 #define DUNE_BLOCK_TRIDIAGONAL_MATRIX_HH 00003 00004 #include <dune/istl/bcrsmatrix.hh> 00005 00011 namespace Dune { 00021 template <class B, class A=std::allocator<B> > 00022 class BTDMatrix : public BCRSMatrix<B,A> 00023 { 00024 public: 00025 00026 //===== type definitions and constants 00027 00029 typedef typename B::field_type field_type; 00030 00032 typedef B block_type; 00033 00035 typedef A allocator_type; 00036 00038 //typedef BCRSMatrix<B,A>::row_type row_type; 00039 00041 typedef typename A::size_type size_type; 00042 00044 enum {blocklevel = B::blocklevel+1}; 00045 00047 BTDMatrix() : BCRSMatrix<B,A>() {} 00048 00049 explicit BTDMatrix(int size) 00050 : BCRSMatrix<B,A>(size, size, BCRSMatrix<B,A>::random) 00051 { 00052 // special handling for 1x1 matrices 00053 if (size==1) { 00054 00055 this->BCRSMatrix<B,A>::setrowsize(0, 1); 00056 this->BCRSMatrix<B,A>::endrowsizes(); 00057 00058 this->BCRSMatrix<B,A>::addindex(0, 0); 00059 this->BCRSMatrix<B,A>::endindices(); 00060 00061 return; 00062 } 00063 00064 // Set number of entries for each row 00065 this->BCRSMatrix<B,A>::setrowsize(0, 2); 00066 00067 for (int i=1; i<size-1; i++) 00068 this->BCRSMatrix<B,A>::setrowsize(i, 3); 00069 00070 this->BCRSMatrix<B,A>::setrowsize(size-1, 2); 00071 00072 this->BCRSMatrix<B,A>::endrowsizes(); 00073 00074 // The actual entries for each row 00075 this->BCRSMatrix<B,A>::addindex(0, 0); 00076 this->BCRSMatrix<B,A>::addindex(0, 1); 00077 00078 for (int i=1; i<size-1; i++) { 00079 this->BCRSMatrix<B,A>::addindex(i, i-1); 00080 this->BCRSMatrix<B,A>::addindex(i, i ); 00081 this->BCRSMatrix<B,A>::addindex(i, i+1); 00082 } 00083 00084 this->BCRSMatrix<B,A>::addindex(size-1, size-2); 00085 this->BCRSMatrix<B,A>::addindex(size-1, size-1); 00086 00087 this->BCRSMatrix<B,A>::endindices(); 00088 00089 } 00090 00092 BTDMatrix& operator= (const BTDMatrix& other) { 00093 this->BCRSMatrix<B,A>::operator=(other); 00094 return *this; 00095 } 00096 00098 BTDMatrix& operator= (const field_type& k) { 00099 this->BCRSMatrix<B,A>::operator=(k); 00100 return *this; 00101 } 00102 00108 template <class V> 00109 void solve (V& x, const V& rhs) const { 00110 00111 // special handling for 1x1 matrices. The generic algorithm doesn't work for them 00112 if (this->N()==1) { 00113 (*this)[0][0].solve(x[0],rhs[0]); 00114 return; 00115 } 00116 00117 // Make copies of the rhs and the right matrix band 00118 V d = rhs; 00119 std::vector<block_type> c(this->N()-1); 00120 for (size_t i=0; i<this->N()-1; i++) 00121 c[i] = (*this)[i][i+1]; 00122 00123 /* Modify the coefficients. */ 00124 block_type a_00_inv; 00125 FMatrixHelp::invertMatrix((*this)[0][0], a_00_inv); 00126 00127 //c[0] /= (*this)[0][0]; /* Division by zero risk. */ 00128 block_type c_0_tmp = c[0]; 00129 FMatrixHelp::multMatrix(a_00_inv, c_0_tmp, c[0]); 00130 00131 // d = a^{-1} d /* Division by zero would imply a singular matrix. */ 00132 typename V::block_type d_0_tmp = d[0]; 00133 (*this)[0][0].solve(d[0], d_0_tmp); 00134 00135 for (unsigned int i = 1; i < this->N(); i++) { 00136 00137 // id = ( a_ii - c_{i-1} a_{i, i-1} ) ^{-1} 00138 block_type tmp; 00139 FMatrixHelp::multMatrix(c[i-1], (*this)[i][i-1], tmp); 00140 block_type id = (*this)[i][i]; 00141 id -= tmp; 00142 id.invert(); /* Division by zero risk. */ 00143 00144 if (i<c.size()) { 00145 // c[i] *= id 00146 tmp = c[i]; 00147 FMatrixHelp::multMatrix(tmp, id, c[i]); /* Last value calculated is redundant. */ 00148 } 00149 00150 // d[i] = (d[i] - d[i-1] * (*this)[i][i-1]) * id; 00151 (*this)[i][i-1].mmv(d[i-1], d[i]); 00152 typename V::block_type tmpVec = d[i]; 00153 id.mv(tmpVec, d[i]); 00154 //d[i] *= id; 00155 00156 } 00157 00158 /* Now back substitute. */ 00159 x[this->N() - 1] = d[this->N() - 1]; 00160 for (int i = this->N() - 2; i >= 0; i--) { 00161 //x[i] = d[i] - c[i] * x[i + 1]; 00162 x[i] = d[i]; 00163 c[i].mmv(x[i+1], x[i]); 00164 } 00165 00166 } 00167 00168 private: 00169 00170 // //////////////////////////////////////////////////////////////////////////// 00171 // The following methods from the base class should now actually be called 00172 // //////////////////////////////////////////////////////////////////////////// 00173 00174 // createbegin and createend should be in there, too, but I can't get it to compile 00175 // BCRSMatrix<B,A>::CreateIterator createbegin () {} 00176 // BCRSMatrix<B,A>::CreateIterator createend () {} 00177 void setrowsize (size_type i, size_type s) {} 00178 void incrementrowsize (size_type i) {} 00179 void endrowsizes () {} 00180 void addindex (size_type row, size_type col) {} 00181 void endindices () {} 00182 }; 00185 } // end namespace Dune 00186 00187 #endif
Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].