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
00015
00016
00017
00018
00019
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
00075
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
00101
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