- Home
- About DUNE
- Download
- Documentation
- Community
- Development
00001 #ifndef DUNE_COEFFMATRIX_HH 00002 #define DUNE_COEFFMATRIX_HH 00003 #include <cassert> 00004 #include <iostream> 00005 #include <vector> 00006 #include <dune/common/fvector.hh> 00007 #include <dune/localfunctions/utility/field.hh> 00008 #include <dune/localfunctions/utility/tensor.hh> 00009 00010 namespace Dune 00011 { 00012 /************************************************* 00013 * Default class for storing a coefficient matrix 00014 * for the PolynomialBasis. Basically a simple 00015 * CRS structure is used. The additional complexity 00016 * is due to the storage and efficient evaluation 00017 * of higher order derivatives. See the remarks 00018 * in tensor.hh which also hold true for this file. 00019 *************************************************/ 00020 template <class Field, class Field2> 00021 struct Mult 00022 { 00023 typedef Field2 BasisEntry; 00024 static void add(const Field &vec1, const BasisEntry &vec2, 00025 BasisEntry &res) 00026 { 00027 res += vec1*vec2; 00028 } 00029 }; 00030 00031 template <class Field,class Field2, int dimRange> 00032 struct Mult< Field,FieldVector<Field2,dimRange> > 00033 { 00034 typedef FieldVector<Field2,dimRange> BasisEntry; 00035 static void add(const Field &vec1, const BasisEntry &vec2, 00036 BasisEntry &res) 00037 { 00038 res.axpy(vec1,vec2); 00039 } 00040 }; 00041 00042 template< class F , unsigned int bSize > 00043 class SparseCoeffMatrix 00044 { 00045 public: 00046 typedef F Field; 00047 static const unsigned int blockSize = bSize; 00048 typedef SparseCoeffMatrix<Field,blockSize> This; 00049 00050 SparseCoeffMatrix() 00051 : coeff_(0), 00052 rows_(0), 00053 skip_(0), 00054 numRows_(0), 00055 numCols_(0) 00056 {} 00057 00058 ~SparseCoeffMatrix() 00059 { 00060 delete [] coeff_; 00061 delete [] rows_; 00062 delete [] skip_; 00063 } 00064 00065 const unsigned int size () const 00066 { 00067 return numRows_/blockSize; 00068 } 00069 const unsigned int baseSize () const 00070 { 00071 return numCols_; 00072 } 00073 00074 template< class BasisIterator, class FF> 00075 void mult ( const BasisIterator &x, 00076 unsigned int numLsg, 00077 FF *y ) const 00078 { 00079 typedef typename BasisIterator::Derivatives XDerivatives; 00080 assert( numLsg*blockSize <= (size_t)numRows_ ); 00081 unsigned int row = 0; 00082 Field *pos = rows_[ 0 ]; 00083 unsigned int *skipIt = skip_; 00084 XDerivatives val; 00085 for( size_t i = 0; i < numLsg; ++i) 00086 { 00087 for( unsigned int r = 0; r < blockSize; ++r, ++row ) 00088 { 00089 val = 0; 00090 BasisIterator itx = x; 00091 for( ; pos != rows_[ row+1 ]; ++pos, ++skipIt ) 00092 { 00093 itx += *skipIt; 00094 val.axpy(*pos,*itx); 00095 } 00096 DerivativeAssign<XDerivatives,FF>::apply(r,val,*(y+i*XDerivatives::size*blockSize)); 00097 } 00098 } 00099 } 00100 template< class BasisIterator, class Vector> 00101 void mult ( const BasisIterator &x, 00102 Vector &y ) const 00103 { 00104 typedef typename Vector::value_type YDerivatives; 00105 typedef typename BasisIterator::Derivatives XDerivatives; 00106 size_t numLsg = y.size(); 00107 assert( numLsg*blockSize <= (size_t)numRows_ ); 00108 unsigned int row = 0; 00109 Field *pos = rows_[ 0 ]; 00110 unsigned int *skipIt = skip_; 00111 XDerivatives val; 00112 for( size_t i = 0; i < numLsg; ++i) 00113 { 00114 for( unsigned int r = 0; r < blockSize; ++r, ++row ) 00115 { 00116 val = 0; 00117 BasisIterator itx = x; 00118 for( ; pos != rows_[ row+1 ]; ++pos, ++skipIt ) 00119 { 00120 itx += *skipIt; 00121 val.axpy(*pos,*itx); 00122 } 00123 DerivativeAssign<XDerivatives,YDerivatives>::apply(r,val,y[i]); 00124 } 00125 } 00126 } 00127 template <unsigned int deriv, class BasisIterator, class Vector> 00128 void mult ( const BasisIterator &x, 00129 Vector &y ) const 00130 { 00131 typedef typename Vector::value_type YDerivatives; 00132 typedef typename BasisIterator::Derivatives XDerivatives; 00133 typedef FieldVector<typename XDerivatives::Field,YDerivatives::size> XLFETensor; 00134 size_t numLsg = y.size(); 00135 assert( numLsg*blockSize <= (size_t)numRows_ ); 00136 unsigned int row = 0; 00137 Field *pos = rows_[ 0 ]; 00138 unsigned int *skipIt = skip_; 00139 for( size_t i = 0; i < numLsg; ++i) 00140 { 00141 XLFETensor val(typename XDerivatives::Field(0)); 00142 for( unsigned int r = 0; r < blockSize; ++r, ++row ) 00143 { 00144 BasisIterator itx = x; 00145 for( ; pos != rows_[ row+1 ]; ++pos, ++skipIt ) 00146 { 00147 itx += *skipIt; 00148 LFETensorAxpy<XDerivatives,XLFETensor,deriv>::apply(r,*pos,*itx,val); 00149 } 00150 } 00151 field_cast(val,y[i]); 00152 } 00153 } 00154 00155 template< class RowMatrix > 00156 void fill ( const RowMatrix &mat, bool verbose=false ) 00157 { 00158 numRows_ = mat.rows(); 00159 numCols_ = mat.cols(); 00160 unsigned int size = numRows_*numCols_; 00161 00162 delete [] coeff_; 00163 delete [] rows_; 00164 delete [] skip_; 00165 00166 Field* coeff = new Field[ size ]; 00167 // we always initialize the next skip entry to zero, 00168 // including the one following the end, so allocate 00169 // size+1 entries so we will stay within the bounds. 00170 unsigned int *skip = new unsigned int[ size+1 ]; 00171 rows_ = new Field*[ numRows_+1 ]; 00172 std::vector<Field> row( numCols_ ); 00173 00174 rows_[ 0 ] = coeff; 00175 Field *cit = coeff; 00176 unsigned int *sit = skip; 00177 for( unsigned int r = 0; r < numRows_; ++r ) 00178 { 00179 *sit = 0; 00180 mat.row( r, row ); 00181 for( unsigned int c = 0; c < numCols_; ++c ) 00182 { 00183 const Field &val = row[c]; 00184 if (val < Zero<Field>() || Zero<Field>() < val) 00185 { 00186 *cit = val; 00187 ++sit; 00188 ++cit; 00189 *sit = 1; 00190 } else 00191 { 00192 ++(*sit); 00193 } 00194 } 00195 rows_[ r+1 ] = cit; 00196 } 00197 assert( size_t(rows_[numRows_]-rows_[0]) <= size_t(size) ); 00198 size = rows_[numRows_]-rows_[0]; 00199 coeff_ = new Field[ size ]; 00200 skip_ = new unsigned int[ size ]; 00201 for (unsigned int i=0;i<size;++i) 00202 { 00203 coeff_[i] = coeff[i]; 00204 skip_[i] = skip[i]; 00205 } 00206 for (unsigned int i=0;i<=numRows_;++i) 00207 rows_[ i ] = coeff_ + (rows_[ i ] - coeff); 00208 00209 delete [] coeff; 00210 delete [] skip; 00211 00212 if (verbose) 00213 std::cout << "Entries: " << (rows_[numRows_]-rows_[0]) 00214 << " full: " << numCols_*numRows_ 00215 << std::endl; 00216 } 00217 // b += a*C[k] 00218 template <class Vector> 00219 void addRow( unsigned int k, const Field &a, Vector &b) const 00220 { 00221 assert(k<numRows_); 00222 unsigned int j=0; 00223 unsigned int *skipIt = skip_ + (rows_[ k ]-rows_[ 0 ]); 00224 for( Field *pos = rows_[ k ]; 00225 pos != rows_[ k+1 ]; 00226 ++pos, ++skipIt ) 00227 { 00228 j += *skipIt; 00229 assert( j < b.size() ); 00230 b[j] += field_cast<typename Vector::value_type>( (*pos)*a ); // field_cast 00231 } 00232 } 00233 private: 00234 SparseCoeffMatrix ( const This &other ) 00235 : numRows_( other.numRows_ ), 00236 numCols_( other.numCols_ ) 00237 { 00238 const unsigned int size = other.rows_[numRows_]-other.rows_[0]; 00239 coeff_ = new Field[ size ]; 00240 rows_ = new Field*[ numRows_+1 ]; 00241 skip_ = new unsigned int[ size ]; 00242 for (unsigned int i=0;i<size;++i) 00243 { 00244 coeff_[i] = other.coeff_[i]; 00245 skip_[i] = other.skip_[i]; 00246 } 00247 for (unsigned int i=0;i<=numRows_;++i) 00248 rows_[ i ] = coeff_ + (other.rows_[ i ] - other.coeff_); 00249 } 00250 00251 This &operator= (const This&); 00252 Field *coeff_; 00253 Field **rows_; 00254 unsigned int *skip_; 00255 unsigned int numRows_,numCols_; 00256 }; 00257 00258 } 00259 00260 #endif // DUNE_COEFFMATRIX_HH 00261
Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].