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