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