basisevaluator.hh

Go to the documentation of this file.
00001 #ifndef DUNE_BASISEVALUATOR_HH
00002 #define DUNE_BASISEVALUATOR_HH
00003 
00004 #include <vector>
00005 
00006 #include <dune/common/fvector.hh>
00007 #include <dune/common/fmatrix.hh>
00008 
00009 #include <dune/grid/genericgeometry/topologytypes.hh>
00010 
00011 #include <dune/localfunctions/utility/field.hh>
00012 
00013 #include <dune/localfunctions/utility/multiindex.hh>
00014 
00015 #include <dune/localfunctions/utility/tensor.hh>
00016 
00017 namespace Dune
00018 {
00019   /*******************************************
00020    * Should be removed as soon as the Tensor
00021    * classes have been revisited. See remarks
00022    * in tensor.hh (also hold true here).
00023    *******************************************/
00024  
00025 
00026   template <class B>
00027   struct MonomialEvaluator
00028   {
00029     typedef B Basis;
00030     typedef typename Basis::Field Field;
00031     typedef typename Basis::DomainVector DomainVector;
00032     static const int dimension = Basis::dimension;
00033     static const int dimRange = Basis::dimRange;
00034 
00035     typedef std::vector<Field> Container;
00036 
00037     template< class Deriv >
00038     struct BaseIterator;
00039 
00040     template <unsigned int deriv>
00041     struct Iterator 
00042     {
00043       typedef BaseIterator<Derivatives<Field,dimension,dimRange,deriv,derivative> > All;
00044       typedef BaseIterator<Derivatives<Field,dimension,1,0,value> > Integrate;
00045     };
00046 
00047     unsigned int size() const 
00048     {
00049       return size_;
00050     }
00051 
00052     protected:
00053     MonomialEvaluator(const Basis &basis,unsigned int order,unsigned int size) 
00054     : basis_(basis),
00055       order_(order),
00056       size_(size),
00057       container_(0)
00058     {
00059     }
00060     template <int deriv>
00061     void resize() 
00062     {
00063       const int totalSize = Derivatives<Field,dimension,dimRange,deriv,derivative>::size*size_;
00064       container_.resize(totalSize);
00065     }
00066     MonomialEvaluator(const MonomialEvaluator&);
00067     const Basis &basis_;
00068     unsigned int order_,size_;
00069     Container container_;
00070   };
00071 
00072 
00073   template< class B >
00074   template< class Deriv >
00075   struct MonomialEvaluator< B >::BaseIterator
00076   {
00077     typedef Deriv Derivatives;
00078     typedef typename Deriv::Field Field;
00079     static const unsigned int blockSize = Deriv::size;
00080     typedef Dune::FieldVector<Field,blockSize> Block;
00081     static const DerivativeLayout layout = Deriv::layout;
00082     static const unsigned int dimDomain = Deriv::dimDomain;
00083     static const unsigned int dimRange = Deriv::dimRange;
00084 
00085     typedef std::vector<Field> Container;
00086     typedef typename Container::iterator CIter;
00087 
00088     explicit BaseIterator ( Container &container ) 
00089     : pos_( container.begin() ),
00090       end_( container.end() )
00091     {}
00092 
00093     const Deriv &operator*() const 
00094     {
00095       assert(!done());
00096       return reinterpret_cast<const Deriv&>(*pos_);
00097     }
00098 
00099     const Deriv *operator->() const 
00100     {
00101       return &(operator*());
00102     }
00103 
00104     bool done () const
00105     {
00106       return pos_ == end_;
00107     }
00108 
00109     BaseIterator &operator++ () 
00110     {
00111       pos_ += blockSize;
00112       return *this;
00113     }
00114 
00115     BaseIterator &operator+= ( unsigned int skip )
00116     {
00117       pos_ += skip*blockSize;
00118       return *this;
00119     }
00120 
00121   private:
00122     CIter pos_;
00123     const CIter end_;
00124   };
00125 
00126   template< class B >
00127   struct StandardEvaluator
00128   : public MonomialEvaluator< B >
00129   {
00130     typedef B Basis;
00131     typedef typename Basis::Field Field;
00132     typedef typename Basis::DomainVector DomainVector;
00133     typedef std::vector<Field> Container;
00134     static const int dimension = Basis::dimension;
00135     static const int dimRange = Basis::dimRange;
00136     typedef MonomialEvaluator<B> Base;
00137 
00138     template <unsigned int deriv>
00139     struct Iterator : public Base::template Iterator<deriv>
00140     {
00141     };
00142 
00143     StandardEvaluator(const Basis &basis) 
00144     : Base(basis,basis.order(),basis.size())
00145     {
00146     }
00147     template <unsigned int deriv,class DVector>
00148     typename Iterator<deriv>::All evaluate(const DVector &x) 
00149     {
00150       Base::template resize<deriv>();
00151       basis_.template evaluate<deriv>(x,&(container_[0]));
00152       return typename Iterator<deriv>::All(container_);
00153     }
00154     typename Iterator<0>::Integrate integrate() 
00155     {
00156       Base::template resize<0>();
00157       basis_.integrate(&(container_[0]));
00158       return typename Iterator<0>::Integrate(container_);
00159     }
00160 
00161   protected:
00162     StandardEvaluator ( const Basis &basis, unsigned int size )
00163     : Base( basis, basis.order(), size )
00164     {}
00165 
00166   private:
00167     StandardEvaluator(const StandardEvaluator&);
00168     using Base::basis_;
00169     using Base::container_;
00170   };
00171 
00172 #if 0 // OLD OLD
00173   template< class B, class Fill >
00174   struct VecEvaluator
00175   : public StandardEvaluator< B >
00176   {
00177     typedef B Basis;
00178     typedef typename Basis::Field Field;
00179     static const int dimension = Basis::dimension;
00180     static const int dimRange = Basis::dimRange*Fill::dimRange;
00181     typedef typename Basis::DomainVector DomainVector;
00182     typedef std::vector<Field> Container;
00183     typedef StandardEvaluator<B> Base;
00184 
00185     template <unsigned int deriv>
00186     struct Iterator 
00187     {
00188       typedef typename Base::template BaseIterator<Derivatives<Field,dimension,dimRange,deriv,Fill::layout> > All;
00189     };
00190 
00191     VecEvaluator ( const Basis &basis, const Fill &fill )
00192     : Base( basis, basis.size() ),
00193       fill_( fill ),
00194       size_( basis.size()*dimRange )
00195     {
00196     }
00197     template <unsigned int deriv>
00198     typename Iterator<deriv>::All evaluate(const DomainVector &x) 
00199     {
00200       resize< deriv >();
00201       fill_.template apply<deriv>( x,Base::template evaluate<deriv>(x), vecContainer_ );
00202       std::vector<Derivatives<Field,dimension,dimRange,deriv,Fill::layout> >& derivContainer =
00203          reinterpret_cast<std::vector<Derivatives<Field,dimension,dimRange,deriv,Fill::layout> >&>(vecContainer_);
00204       return typename Iterator<deriv>::All(derivContainer);
00205     }
00206     template <unsigned int deriv,class DVector>
00207     typename Iterator<deriv>::All evaluate(const DVector &x) 
00208     {
00209       resize< deriv >();
00210       fill_.template apply<deriv>( x,Base::template evaluate<deriv>(x), vecContainer_ );
00211       std::vector<Derivatives<Field,dimension,dimRange,deriv,Fill::layout> >& derivContainer =
00212          reinterpret_cast<std::vector<Derivatives<Field,dimension,dimRange,deriv,Fill::layout> >&>(vecContainer_);
00213       return typename Iterator<deriv>::All(derivContainer);
00214     }
00215     unsigned int size() const
00216     {
00217       return size_;
00218     }
00219 
00220   protected:
00221     VecEvaluator ( const Basis &basis, const Fill &fill, unsigned int size )
00222     : Base( basis, basis.size() ),
00223       fill_( fill ),
00224       size_( size )
00225     {
00226       resize< 2 >();
00227     }
00228 
00229     template <int deriv>
00230     void resize() 
00231     {
00232       const int totalSize = Derivatives<Field,dimension,dimRange,deriv,derivative>::size*size_;
00233       vecContainer_.resize(totalSize);
00234     }
00235 
00236     VecEvaluator(const VecEvaluator&);
00237 
00238     Container vecContainer_;
00239     const Fill &fill_;
00240     unsigned int size_;
00241   };
00242 
00243   template <int dimR,DerivativeLayout layout>
00244   struct DiagonalFill;
00245 
00246   template <int dimR>
00247   struct DiagonalFill<dimR,derivative>
00248   {
00249     static const DerivativeLayout layout = derivative;
00250     static const int dimRange = dimR;
00251     template <int deriv, class Domain, class Iter,class Field>
00252     void apply(const Domain &x,
00253                Iter iter,std::vector<Field> &vecContainer) const
00254     {
00255       typedef std::vector<Field> Container;
00256       typename Container::iterator vecIter = vecContainer.begin();
00257       for ( ; !iter.done(); ++iter)
00258       {
00259         const typename Iter::Block &block = iter->block();
00260         for (int r1=0;r1<dimR;++r1) 
00261         {
00262           unsigned int b = 0;
00263           apply<Field>(r1,x,block,b,vecIter);
00264         }
00265       }
00266     }
00267     template <class Field, class Domain, class Block,class VecIter>
00268     void apply(int r1, const Domain &x,
00269                const Block &block,unsigned int &b, 
00270                VecIter &vecIter) const
00271     {
00272       unsigned int bStart = b;
00273       unsigned int bEnd = b+Block::size;
00274       apply<Field>(r1,x,block,bStart,bEnd,vecIter);
00275       b=bEnd;
00276     }
00277     template <class Field, class Domain, class Block,class VecIter>
00278     void apply(int r1, const Domain &x,const Block &block,
00279                unsigned int bStart, unsigned int bEnd,
00280                VecIter &vecIter) const
00281     {
00282       for (int r2=0;r2<dimR;++r2) 
00283       {
00284         for (unsigned int bb=bStart;bb<bEnd;++bb)
00285         {
00286           *vecIter = (r1==r2?block[bb]:Field(0));
00287           ++vecIter;
00288         }
00289       }
00290     }
00291   };
00292   template <int dimR>
00293   struct DiagonalFill<dimR,value>
00294   {
00295     static const DerivativeLayout layout = value;
00296     static const int dimRange = dimR;
00297     template <int deriv, class Domain, class Iter,class Field>
00298     void apply(const Domain &x,
00299                Iter iter,std::vector<Field> &vecContainer) const
00300     {
00301       typedef std::vector<Field> Container;
00302       typename Container::iterator vecIter = vecContainer.begin();
00303       for ( ; !iter.done(); ++iter)
00304       {
00305         const typename Iter::Block &block = iter->block();
00306         for (int r1=0;r1<dimR;++r1) 
00307         {
00308           unsigned int b = 0;
00309           apply<Field>(Int2Type<deriv>(),r1,x,block,b,vecIter);
00310         }
00311       }
00312     }
00313     template <class Field, class Domain, class Block,class VecIter,int deriv>
00314     void apply(const Int2Type<deriv>&, int r1, const Domain &x,
00315                const Block &block,unsigned int &b, 
00316                VecIter &vecIter) const
00317     {
00318       apply<Field>(Int2Type<deriv-1>(),r1,x,block,b,vecIter);
00319       unsigned int bStart = b;
00320       unsigned int bEnd = b+LFETensor<Field,Domain::dimension,deriv>::size;
00321       apply<Field>(r1,x,block,bStart,bEnd,vecIter);
00322       b=bEnd;
00323     }
00324     template <class Field, class Domain, class Block,class VecIter>
00325     void apply(const Int2Type<0>&, int r1, const Domain &x,
00326                const Block &block,unsigned int &b, 
00327                VecIter &vecIter) const
00328     {
00329       apply<Field>(r1,x,block,b,b+1,vecIter);
00330       ++b;
00331     }
00332     template <class Field, class Domain, class Block,class VecIter>
00333     void apply(int r1, const Domain &x,const Block &block,
00334                unsigned int bStart, unsigned int bEnd,
00335                VecIter &vecIter) const
00336     {
00337       for (int r2=0;r2<dimR;++r2) 
00338       {
00339         for (unsigned int bb=bStart;bb<bEnd;++bb)
00340         {
00341           *vecIter = (r1==r2?block[bb]:Field(0));
00342           ++vecIter;
00343         }
00344       }
00345     }
00346   };
00347 
00348   template <class B,int dimR,DerivativeLayout layout>
00349   struct VectorialEvaluator 
00350   : public VecEvaluator<B,DiagonalFill<dimR,layout> >
00351   {
00352     typedef DiagonalFill<dimR,layout> Fill;
00353     typedef VecEvaluator< B,Fill > Base;
00354     VectorialEvaluator(const B &basis)
00355     : Base(basis,fill_,basis.size()*dimR)
00356     {
00357     }
00358     private:
00359     Fill fill_;
00360   };
00361 #endif // OLD OLD
00362 
00363 }
00364 
00365 #endif
Generated on Sat Apr 24 11:15:33 2010 for dune-localfunctions by  doxygen 1.6.3