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
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