dune-localfunctions
2.1.1
|
00001 #ifndef DUNE_BASISMATRIX_HH 00002 #define DUNE_BASISMATRIX_HH 00003 00004 #include <fstream> 00005 #include <dune/common/exceptions.hh> 00006 00007 #include <dune/localfunctions/utility/lfematrix.hh> 00008 #include <dune/localfunctions/utility/monomialbasis.hh> 00009 #include <dune/localfunctions/utility/polynomialbasis.hh> 00010 00011 namespace Dune 00012 { 00013 /**************************************** 00014 * A dense matrix representation of a ''polynomial'' 00015 * basis. Its represent a basis as a linear 00016 * combination of a second basis, i.e., a 00017 * monomial basis. It is simular to the PolynomialBasis 00018 * but it not derived from the LocalBasis class. 00019 * It is used to define a ''pre basis''. 00020 ****************************************/ 00021 template< class PreBasis, class Interpolation, 00022 class Field > 00023 struct BasisMatrix; 00024 00025 template< class PreBasis, class Interpolation, 00026 class Field > 00027 struct BasisMatrixBase : public LFEMatrix<Field> 00028 { 00029 typedef LFEMatrix<Field> Matrix; 00030 00031 BasisMatrixBase( const PreBasis& preBasis, 00032 const Interpolation& localInterpolation ) 00033 : cols_(preBasis.size()) 00034 { 00035 localInterpolation.interpolate( preBasis, *this ); 00036 00037 if ( !Matrix::invert() ) 00038 { 00039 DUNE_THROW(MathError, "While computing basis a singular matrix was constructed!"); 00040 } 00041 } 00042 unsigned int cols () const 00043 { 00044 return cols_; 00045 } 00046 unsigned int rows () const 00047 { 00048 return Matrix::rows(); 00049 } 00050 private: 00051 unsigned int cols_; 00052 }; 00053 00054 template< class Topology, class F, 00055 class Interpolation, 00056 class Field > 00057 struct BasisMatrix< const MonomialBasis< Topology, F >, Interpolation, Field > 00058 : public BasisMatrixBase< const MonomialBasis< Topology, F >, Interpolation, Field > 00059 { 00060 typedef const MonomialBasis< Topology, F > PreBasis; 00061 typedef BasisMatrixBase<PreBasis,Interpolation,Field> Base; 00062 typedef typename Base::Matrix Matrix; 00063 00064 BasisMatrix( const PreBasis& preBasis, 00065 const Interpolation& localInterpolation ) 00066 : Base(preBasis, localInterpolation) 00067 { 00068 } 00069 template <class Vector> 00070 void row( const unsigned int row, Vector &vec ) const 00071 { 00072 const unsigned int N = Matrix::rows(); 00073 assert( Matrix::cols() == N && vec.size() == N ); 00074 // note: that the transposed matrix is computed, 00075 // and is square 00076 for (unsigned int i=0;i<N;++i) 00077 field_cast(Matrix::operator()(i,row),vec[i]); 00078 } 00079 }; 00080 template< int dim, class F, 00081 class Interpolation, 00082 class Field > 00083 struct BasisMatrix< const Dune::VirtualMonomialBasis< dim, F >, Interpolation, Field > 00084 : public BasisMatrixBase< const VirtualMonomialBasis< dim, F >, Interpolation, Field > 00085 { 00086 typedef const VirtualMonomialBasis< dim, F > PreBasis; 00087 typedef BasisMatrixBase<PreBasis,Interpolation,Field> Base; 00088 typedef typename Base::Matrix Matrix; 00089 00090 BasisMatrix( const PreBasis& preBasis, 00091 const Interpolation& localInterpolation ) 00092 : Base(preBasis, localInterpolation) 00093 { 00094 } 00095 template <class Vector> 00096 void row( const unsigned int row, Vector &vec ) const 00097 { 00098 const unsigned int N = Matrix::rows(); 00099 assert( Matrix::cols() == N && vec.size() == N ); 00100 // note: that the transposed matrix is computed, 00101 // and is square 00102 for (unsigned int i=0;i<N;++i) 00103 field_cast(Matrix::operator()(i,row),vec[i]); 00104 } 00105 }; 00106 template< class Eval, class CM, class D, class R, 00107 class Interpolation, 00108 class Field > 00109 struct BasisMatrix< const PolynomialBasis<Eval,CM,D,R>, Interpolation, Field > 00110 : public BasisMatrixBase< const PolynomialBasis<Eval,CM,D,R>, Interpolation, Field > 00111 { 00112 typedef const PolynomialBasis<Eval,CM,D,R> PreBasis; 00113 typedef BasisMatrixBase<PreBasis,Interpolation,Field> Base; 00114 typedef typename Base::Matrix Matrix; 00115 00116 BasisMatrix( const PreBasis& preBasis, 00117 const Interpolation& localInterpolation ) 00118 : Base(preBasis, localInterpolation), 00119 preBasis_(preBasis) 00120 { 00121 } 00122 unsigned int cols() const 00123 { 00124 return preBasis_.matrix().baseSize() ; 00125 } 00126 template <class Vector> 00127 void row( const unsigned int row, Vector &vec ) const 00128 { 00129 assert( Matrix::rows() == Matrix::cols() ); 00130 assert( vec.size() == preBasis_.matrix().baseSize() ); 00131 assert( Matrix::cols() == preBasis_.size() ); 00132 for (unsigned int j=0;j<Matrix::cols();++j) 00133 vec[j] = 0; 00134 for (unsigned int i=0;i<Matrix::rows();++i) 00135 preBasis_.matrix(). 00136 addRow(i,Base::Matrix::operator()(i,row),vec); 00137 } 00138 private: 00139 const PreBasis& preBasis_; 00140 }; 00141 template< class Eval, class CM, 00142 class Interpolation, 00143 class Field > 00144 struct BasisMatrix< const PolynomialBasisWithMatrix<Eval,CM>, Interpolation, Field > 00145 : public BasisMatrixBase< const PolynomialBasisWithMatrix<Eval,CM>, Interpolation, Field > 00146 { 00147 typedef const PolynomialBasisWithMatrix<Eval,CM> PreBasis; 00148 typedef BasisMatrixBase<PreBasis,Interpolation,Field> Base; 00149 typedef typename Base::Matrix Matrix; 00150 00151 BasisMatrix( const PreBasis& preBasis, 00152 const Interpolation& localInterpolation ) 00153 : Base(preBasis, localInterpolation), 00154 preBasis_(preBasis) 00155 { 00156 } 00157 unsigned int cols() const 00158 { 00159 return preBasis_.matrix().baseSize() ; 00160 } 00161 unsigned int rows () const 00162 { 00163 assert( Matrix::rows() == preBasis_.matrix().size() ); 00164 return preBasis_.matrix().size()*CM::blockSize ; 00165 } 00166 template <class Vector> 00167 void row( const unsigned int row, Vector &vec ) const 00168 { 00169 unsigned int r = row / CM::blockSize; 00170 assert( r < Matrix::rows() ); 00171 assert( Matrix::rows() == Matrix::cols() ); 00172 assert( vec.size() == preBasis_.matrix().baseSize() ); 00173 assert( Matrix::cols() == preBasis_.size() ); 00174 for (unsigned int j=0;j<vec.size();++j) 00175 vec[j] = 0; 00176 for (unsigned int i=0;i<Matrix::rows();++i) 00177 preBasis_.matrix(). 00178 addRow(i*CM::blockSize+row%CM::blockSize,Base::Matrix::operator()(i,r),vec); 00179 } 00180 private: 00181 const PreBasis& preBasis_; 00182 }; 00183 } 00184 00185 #endif // DUNE_BASISMATRIX_HH 00186