dune-localfunctions  2.1.1
lagrange/interpolation.hh
Go to the documentation of this file.
00001 #ifndef DUNE_LAGRANGEBASIS_INTERPOLATION_HH
00002 #define DUNE_LAGRANGEBASIS_INTERPOLATION_HH
00003 
00004 #include <vector>
00005 #include <dune/grid/common/topologyfactory.hh>
00006 #include <dune/localfunctions/lagrange/lagrangecoefficients.hh>
00007 
00008 namespace Dune
00009 {
00010 
00011   template< template <class,unsigned int> class LP,
00012             unsigned int dim, class F >
00013   struct LagrangeInterpolationFactory;
00014 
00015   // LocalLagrangeInterpolation
00016   // --------------------------
00017 
00018   template< template <class,unsigned int> class LP,
00019             unsigned int dim, class F >
00020   class LocalLagrangeInterpolation
00021   {
00022     typedef LocalLagrangeInterpolation< LP,dim,F > This;
00023 
00024   public:
00025     typedef LP<F,dim> LagrangePointSet;
00026     typedef typename LagrangePointSet::Field Field;
00027 
00028     static const unsigned int dimension = LagrangePointSet::dimension;
00029 
00030   private:
00031     friend class LagrangeInterpolationFactory<LP,dim,F>;
00032     const LagrangePointSet &lagrangePoints_;
00033 
00034     explicit LocalLagrangeInterpolation ( const LagrangePointSet &lagrangePoints )
00035     : lagrangePoints_( lagrangePoints )
00036     {}
00037     const LagrangePointSet *points () const
00038     {
00039       return &lagrangePoints_;
00040     }
00041 
00042   public:
00043     template< class Function, class Fy >
00044     void interpolate ( const Function &function, std::vector< Fy > &coefficients ) const
00045     {
00046       typedef typename LagrangePointSet::iterator Iterator;
00047 
00048       coefficients.resize( lagrangePoints_.size() );
00049 
00050       unsigned int index = 0;
00051       const Iterator end = lagrangePoints_.end();
00052       for( Iterator it = lagrangePoints_.begin(); it != end; ++it )
00053       {
00054         typename Function::RangeType val;
00055         function.evaluate( field_cast<typename Function::DomainType::field_type>(it->point()), val );
00056         field_cast( val, coefficients[ index++ ] );
00057       }
00058     }
00059 
00060     template< class Matrix, class Basis >
00061     void interpolate ( const Basis &basis, Matrix &coefficients ) const
00062     {
00063       typedef typename LagrangePointSet::iterator Iterator;
00064 
00065       coefficients.resize( lagrangePoints_.size(), basis.size( ) );
00066 
00067       unsigned int index = 0;
00068       const Iterator end = lagrangePoints_.end();
00069       for( Iterator it = lagrangePoints_.begin(); it != end; ++it )
00070         basis.template evaluate<0>( it->point(), coefficients.rowPtr( index++ ) );
00071     }
00072 
00073     const LagrangePointSet &lagrangePoints () const
00074     {
00075       return lagrangePoints_;
00076     }
00077   };
00078 
00079 
00080 
00081   // LocalLagrangeInterpolationFactory
00082   // ---------------------------------
00083   template< template <class,unsigned int> class LP,
00084             unsigned int dim, class F >
00085   struct LagrangeInterpolationFactoryTraits
00086   {
00087     typedef LagrangeCoefficientsFactory<LP,dim,F> LagrangePointSetFactory;
00088     typedef typename LagrangePointSetFactory::Object LagrangePointSet;
00089 
00090     typedef typename LagrangePointSetFactory::Key Key;
00091     typedef const LocalLagrangeInterpolation< LP,dim,F > Object;
00092     typedef LagrangeInterpolationFactory<LP,dim,F> Factory;
00093 
00094     static const unsigned int dimension = dim;
00095   };
00096 
00097   template< template <class,unsigned int> class LP,
00098             unsigned int dim, class F >
00099   struct LagrangeInterpolationFactory :
00100     public TopologyFactory< LagrangeInterpolationFactoryTraits< LP,dim,F > >
00101   {
00102     typedef LagrangeInterpolationFactoryTraits< LP,dim,F > Traits;
00103     typedef typename Traits::Key Key;
00104     typedef typename Traits::Object Object;
00105 
00106     template< class Topology >
00107     static Object *createObject ( const Key &key )
00108     {
00109       const typename Traits::LagrangePointSet *lagrangeCoeff
00110         = Traits::LagrangePointSetFactory::template create< Topology >( key );
00111       if ( lagrangeCoeff == 0 )
00112         return 0;
00113       else 
00114         return new Object( *lagrangeCoeff );
00115     }
00116     static void release( Object *object) 
00117     {
00118       Traits::LagrangePointSetFactory::release( object->points() );
00119       delete object;
00120     }
00121   };
00122 
00123 }
00124 
00125 #endif // #ifndef DUNE_LAGRANGEBASIS_INTERPOLATION_HH