dune-localfunctions  2.1.1
basismatrix.hh
Go to the documentation of this file.
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