dune-localfunctions  2.1.1
l2interpolation.hh
Go to the documentation of this file.
00001 #ifndef DUNE_L2INTERPOLATION_HH
00002 #define DUNE_L2INTERPOLATION_HH
00003 
00004 #include <dune/grid/common/topologyfactory.hh>
00005 #include <dune/localfunctions/utility/lfematrix.hh>
00006 
00007 #include <dune/grid/common/quadraturerules/gaussquadrature.hh>
00008 
00009 namespace Dune
00010 {
00026   template< class B, class Q, bool onb >
00027   struct LocalL2Interpolation;
00028 
00029   template< class B, class Q >
00030   class LocalL2InterpolationBase
00031   {
00032     typedef LocalL2InterpolationBase< B, Q > This;
00033 
00034   public:
00035     typedef B Basis;
00036     typedef Q Quadrature;
00037 
00038     static const unsigned int dimension = Basis::dimension;
00039 
00040     template< class Function, class DofField >
00041     void interpolate ( const Function &function, std::vector< DofField > &coefficients ) const
00042     {
00043       typedef typename Quadrature::Iterator Iterator;
00044       typedef FieldVector< DofField, Basis::dimRange > RangeVector;
00045 
00046       const unsigned int size = basis().size();
00047       static std::vector< RangeVector > basisValues( size );
00048 
00049       coefficients.resize( size );
00050       basisValues.resize( size );
00051       for( unsigned int i = 0; i < size; ++i )
00052         coefficients[ i ] = Zero< DofField >();
00053 
00054       const Iterator end = quadrature().end();
00055       for( Iterator it = quadrature().begin(); it != end; ++it )
00056       {
00057         basis().evaluate( it->position(), basisValues );
00058         typename Function::RangeType val;
00059         function.evaluate( field_cast<typename Function::DomainType::field_type>(it->position()), val );
00060         RangeVector factor = field_cast< DofField >( val );
00061         factor *= field_cast< DofField >( it->weight() );
00062         for( unsigned int i = 0; i < size; ++i )
00063           coefficients[ i ] += factor * basisValues[ i ];
00064       }
00065     }
00066 
00067     const Basis &basis () const
00068     {
00069       return basis_;
00070     }
00071 
00072     const Quadrature &quadrature () const
00073     {
00074       return quadrature_;
00075     }
00076 
00077   protected:
00078     LocalL2InterpolationBase ( const Basis &basis, const Quadrature &quadrature )
00079     : basis_( basis ),
00080       quadrature_( quadrature )
00081     {}
00082 
00083     const Basis &basis_;
00084     const Quadrature &quadrature_;
00085   };
00086 
00087   template< class B, class Q >
00088   struct LocalL2Interpolation<B,Q,true>
00089   : public LocalL2InterpolationBase<B,Q>
00090   {
00091     typedef LocalL2InterpolationBase<B,Q> Base;
00092     template< class BasisFactory, bool onb >
00093     friend class LocalL2InterpolationFactory;
00094     using Base::Basis;
00095     using Base::Quadrature;
00096   private:
00097     LocalL2Interpolation ( const typename Base::Basis &basis, const typename Base::Quadrature &quadrature )
00098     : Base(basis,quadrature) 
00099     {}
00100   };
00101   template< class B, class Q >
00102   struct LocalL2Interpolation<B,Q,false>
00103   : public LocalL2InterpolationBase<B,Q>
00104   {
00105     typedef LocalL2InterpolationBase<B,Q> Base;
00106     template< class BasisFactory, bool onb >
00107     friend class LocalL2InterpolationFactory;
00108     using Base::Basis;
00109     using Base::Quadrature;
00110     template< class Function, class DofField >
00111     void interpolate ( const Function &function, std::vector< DofField > &coefficients ) const
00112     {
00113       const unsigned size = Base::basis().size();
00114       Base::interpolate(function,val_);
00115       coefficients.resize( size );
00116       for (unsigned int i=0;i<size;++i)
00117       {
00118         coefficients[i] = 0;
00119         for (unsigned int j=0;j<size;++j)
00120         {
00121           coefficients[i] += field_cast<DofField>(massMatrix_(i,j)*val_[j]);
00122         }
00123       }
00124     }
00125   private:
00126     LocalL2Interpolation ( const typename Base::Basis &basis, const typename Base::Quadrature &quadrature )
00127     : Base(basis,quadrature),
00128       val_(basis.size()),
00129       massMatrix_()
00130     {
00131       typedef FieldVector< Field, Base::Basis::dimRange > RangeVector;
00132       typedef typename Base::Quadrature::Iterator Iterator;
00133       const unsigned size = basis.size();
00134       std::vector< RangeVector > basisValues( size );
00135 
00136       massMatrix_.resize( size,size );
00137       for (unsigned int i=0;i<size;++i)
00138         for (unsigned int j=0;j<size;++j)
00139           massMatrix_(i,j) = 0; 
00140       const Iterator end = Base::quadrature().end();
00141       for( Iterator it = Base::quadrature().begin(); it != end; ++it )
00142       {
00143         Base::basis().evaluate( it->position(), basisValues );
00144         for (unsigned int i=0;i<size;++i)
00145           for (unsigned int j=0;j<size;++j)
00146             massMatrix_(i,j) += (basisValues[i]*basisValues[j])*it->weight(); 
00147       }
00148       if ( !massMatrix_.invert() )
00149       {
00150         DUNE_THROW(MathError, "Mass matrix singular in LocalL2Interpolation");
00151       }
00152 
00153     }
00154     typedef typename Base::Basis::StorageField Field;
00155     typedef FieldVector< Field, Base::Basis::dimRange > RangeVector;
00156     typedef LFEMatrix<Field> MassMatrix;
00157     mutable std::vector<Field> val_;
00158     MassMatrix massMatrix_;
00159   };
00160 
00166   template< class BasisFactory, bool onb >
00167   struct LocalL2InterpolationFactory;
00168   template< class BasisFactory, bool onb >
00169   struct LocalL2InterpolationFactoryTraits
00170   {
00171     static const unsigned int dimension = BasisFactory::dimension;
00172     // typedef typename BasisFactory::StorageField Field;
00173     typedef double Field;
00174     typedef GenericGeometry::GaussQuadratureProvider<dimension,Field> QuadratureProvider;
00175     typedef typename QuadratureProvider::Object Quadrature;
00176 
00177     typedef typename BasisFactory::Key Key;
00178     typedef typename BasisFactory::Object Basis;
00179     typedef LocalL2Interpolation< Basis, Quadrature, onb > LocalInterpolation;
00180     typedef const LocalInterpolation Object;
00181     typedef LocalL2InterpolationFactory<BasisFactory,onb> Factory;
00182   };
00183 
00184   template< class BasisFactory, bool onb >
00185   struct LocalL2InterpolationFactory :
00186     public TopologyFactory< LocalL2InterpolationFactoryTraits<BasisFactory,onb> > 
00187   {
00188     typedef LocalL2InterpolationFactoryTraits<BasisFactory,onb> Traits;
00189     static const unsigned int dimension = Traits::dimension;
00190     typedef typename Traits::Key Key;
00191     typedef typename Traits::Basis Basis;
00192     typedef typename Traits::Object Object;;
00193     typedef typename Traits::Field Field;
00194     typedef typename Traits::Quadrature Quadrature;
00195 
00196     template< class Topology >
00197     static Object *createObject ( const Key &key )
00198     {
00199       typedef GenericGeometry::GenericQuadrature< Topology, Field > GenericQuadrature;
00200       const Basis *basis = BasisFactory::template create< Topology >( key );
00201       const Quadrature *quadrature = Traits::QuadratureProvider::template create< Topology >( 2*basis->order()+1 );
00202       return new Object( *basis, *quadrature );
00203     }
00204     static void release ( Object *object )
00205     {
00206       const Basis &basis = object->basis();
00207       const Quadrature &quadrature = object->quadrature();
00208       BasisFactory::release( &basis );
00209       Traits::QuadratureProvider::release( &quadrature );
00210       delete object;
00211     }
00212   };
00213 
00214 }
00215 
00216 #endif // #ifndef DUNE_L2INTERPOLATION_HH