00001 #ifndef DUNE_MONOMIALBASIS_HH
00002 #define DUNE_MONOMIALBASIS_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/grid/common/topologyfactory.hh>
00014 #include <dune/localfunctions/utility/multiindex.hh>
00015 #include <dune/localfunctions/utility/tensor.hh>
00016
00017 namespace Dune
00018 {
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 template< class Topology >
00069 class MonomialBasisSize;
00070
00071 template< class Topology, class F >
00072 class MonomialBasis;
00073
00074
00075
00076
00077
00078
00079 template<>
00080 class MonomialBasisSize< GenericGeometry::Point >
00081 {
00082 typedef MonomialBasisSize< GenericGeometry::Point > This;
00083
00084 public:
00085 static This &instance ()
00086 {
00087 static This _instance;
00088 return _instance;
00089 }
00090
00091 typedef GenericGeometry::Point Topology;
00092
00093 friend class MonomialBasisSize< GenericGeometry::Prism< Topology > >;
00094 friend class MonomialBasisSize< GenericGeometry::Pyramid< Topology > >;
00095
00096 mutable unsigned int maxOrder_;
00097
00098 mutable unsigned int *sizes_;
00099
00100 mutable unsigned int *numBaseFunctions_;
00101
00102 MonomialBasisSize ()
00103 : maxOrder_( 0 ),
00104 sizes_( 0 ),
00105 numBaseFunctions_( 0 )
00106 {
00107 computeSizes( 2 );
00108 }
00109
00110 ~MonomialBasisSize ()
00111 {
00112 delete[] sizes_;
00113 delete[] numBaseFunctions_;
00114 }
00115
00116 unsigned int operator() ( const unsigned int order ) const
00117 {
00118 return numBaseFunctions_[ order ];
00119 }
00120
00121 unsigned int maxOrder () const
00122 {
00123 return maxOrder_;
00124 }
00125
00126 void computeSizes ( unsigned int order ) const
00127 {
00128 if (order <= maxOrder_)
00129 return;
00130
00131 maxOrder_ = order;
00132
00133 delete [] sizes_;
00134 delete [] numBaseFunctions_;
00135 sizes_ = new unsigned int [ order+1 ];
00136 numBaseFunctions_ = new unsigned int [ order+1 ];
00137
00138 sizes_[ 0 ] = 1;
00139 numBaseFunctions_[ 0 ] = 1;
00140 for( unsigned int k = 1; k <= order; ++k )
00141 {
00142 sizes_[ k ] = 0;
00143 numBaseFunctions_[ k ] = 1;
00144 }
00145 }
00146 };
00147
00148 template< class BaseTopology >
00149 class MonomialBasisSize< GenericGeometry::Prism< BaseTopology > >
00150 {
00151 typedef MonomialBasisSize< GenericGeometry::Prism< BaseTopology > > This;
00152
00153 public:
00154 static This &instance ()
00155 {
00156 static This _instance;
00157 return _instance;
00158 }
00159
00160 typedef GenericGeometry::Prism< BaseTopology > Topology;
00161
00162 friend class MonomialBasisSize< GenericGeometry::Prism< Topology > >;
00163 friend class MonomialBasisSize< GenericGeometry::Pyramid< Topology > >;
00164
00165 mutable unsigned int maxOrder_;
00166
00167 mutable unsigned int *sizes_;
00168
00169 mutable unsigned int *numBaseFunctions_;
00170
00171 MonomialBasisSize ()
00172 : maxOrder_( 0 ),
00173 sizes_( 0 ),
00174 numBaseFunctions_( 0 )
00175 {
00176 computeSizes( 2 );
00177 }
00178
00179 ~MonomialBasisSize ()
00180 {
00181 delete[] sizes_;
00182 delete[] numBaseFunctions_;
00183 }
00184
00185 unsigned int operator() ( const unsigned int order ) const
00186 {
00187 return numBaseFunctions_[ order ];
00188 }
00189
00190 unsigned int maxOrder() const
00191 {
00192 return maxOrder_;
00193 }
00194
00195 void computeSizes ( unsigned int order ) const
00196 {
00197 if (order <= maxOrder_)
00198 return;
00199
00200 maxOrder_ = order;
00201
00202 delete[] sizes_;
00203 delete[] numBaseFunctions_;
00204 sizes_ = new unsigned int[ order+1 ];
00205 numBaseFunctions_ = new unsigned int[ order+1 ];
00206
00207 MonomialBasisSize<BaseTopology> &baseBasis =
00208 MonomialBasisSize<BaseTopology>::instance();
00209 baseBasis.computeSizes( order );
00210 const unsigned int *const baseSizes = baseBasis.sizes_;
00211 const unsigned int *const baseNBF = baseBasis.numBaseFunctions_;
00212
00213 sizes_[ 0 ] = 1;
00214 numBaseFunctions_[ 0 ] = 1;
00215 for( unsigned int k = 1; k <= order; ++k )
00216 {
00217 sizes_[ k ] = baseNBF[ k ] + k*baseSizes[ k ];
00218 numBaseFunctions_[ k ] = numBaseFunctions_[ k-1 ] + sizes_[ k ];
00219 }
00220 }
00221 };
00222
00223 template< class BaseTopology >
00224 class MonomialBasisSize< GenericGeometry::Pyramid< BaseTopology > >
00225 {
00226 typedef MonomialBasisSize< GenericGeometry::Pyramid< BaseTopology > > This;
00227
00228 public:
00229 static This &instance ()
00230 {
00231 static This _instance;
00232 return _instance;
00233 }
00234
00235 typedef GenericGeometry::Pyramid< BaseTopology > Topology;
00236
00237 friend class MonomialBasisSize< GenericGeometry::Prism< Topology > >;
00238 friend class MonomialBasisSize< GenericGeometry::Pyramid< Topology > >;
00239
00240 mutable unsigned int maxOrder_;
00241
00242 mutable unsigned int *sizes_;
00243
00244 mutable unsigned int *numBaseFunctions_;
00245
00246 MonomialBasisSize ()
00247 : maxOrder_( 0 ),
00248 sizes_( 0 ),
00249 numBaseFunctions_( 0 )
00250 {
00251 computeSizes( 2 );
00252 }
00253
00254 ~MonomialBasisSize ()
00255 {
00256 delete[] sizes_;
00257 delete[] numBaseFunctions_;
00258 }
00259
00260 unsigned int operator() ( const unsigned int order ) const
00261 {
00262 return numBaseFunctions_[ order ];
00263 }
00264
00265 unsigned int maxOrder() const
00266 {
00267 return maxOrder_;
00268 }
00269
00270 void computeSizes ( unsigned int order ) const
00271 {
00272 if (order <= maxOrder_)
00273 return;
00274
00275 maxOrder_ = order;
00276
00277 delete[] sizes_;
00278 delete[] numBaseFunctions_;
00279 sizes_ = new unsigned int[ order+1 ];
00280 numBaseFunctions_ = new unsigned int[ order+1 ];
00281
00282 MonomialBasisSize<BaseTopology> &baseBasis =
00283 MonomialBasisSize<BaseTopology>::instance();
00284
00285 baseBasis.computeSizes( order );
00286
00287 const unsigned int *const baseNBF = baseBasis.numBaseFunctions_;
00288 sizes_[ 0 ] = 1;
00289 numBaseFunctions_[ 0 ] = 1;
00290 for( unsigned int k = 1; k <= order; ++k )
00291 {
00292 sizes_[ k ] = baseNBF[ k ];
00293 numBaseFunctions_[ k ] = numBaseFunctions_[ k-1 ] + sizes_[ k ];
00294 }
00295 }
00296 };
00297
00298
00299
00300
00301
00302
00303
00304 template< int mydim, int dim, class F >
00305 struct MonomialBasisHelper
00306 {
00307 typedef MonomialBasisSize< typename GenericGeometry::SimplexTopology< mydim >::type > MySize;
00308 typedef MonomialBasisSize< typename GenericGeometry::SimplexTopology< dim >::type > Size;
00309
00310 static void copy ( const unsigned int deriv, F *&wit, F *&rit,
00311 const unsigned int numBaseFunctions, const F &z )
00312 {
00313
00314 MySize &mySize = MySize::instance();
00315 Size &size = Size::instance();
00316
00317 const F *const rend = rit + size( deriv )*numBaseFunctions;
00318 for( ; rit != rend; )
00319 {
00320 F *prit = rit;
00321
00322 *wit = z * *rit;
00323 ++rit, ++wit;
00324
00325 for( unsigned d = 1; d <= deriv; ++d )
00326 {
00327 #ifndef NDEBUG
00328 const F *const derivEnd = rit + mySize.sizes_[ d ];
00329 #endif
00330 const F *const drend = rit + mySize.sizes_[ d ] - mySize.sizes_[ d-1 ];
00331 for( ; rit != drend ; ++rit, ++wit )
00332 *wit = z * *rit;
00333 for (unsigned int j=1;j<d;++j)
00334 {
00335 const F *const drend = rit + mySize.sizes_[ d-j ] - mySize.sizes_[ d-j-1 ];
00336 for( ; rit != drend ; ++prit, ++rit, ++wit )
00337 *wit = F(j) * *prit + z * *rit;
00338 }
00339 *wit = F(d) * *prit + z * *rit;
00340 ++prit, ++rit, ++wit;
00341 assert(derivEnd == rit);
00342 rit += size.sizes_[d] - mySize.sizes_[d];
00343 prit += size.sizes_[d-1] - mySize.sizes_[d-1];
00344 const F *const emptyWitEnd = wit + size.sizes_[d] - mySize.sizes_[d];
00345 for ( ; wit != emptyWitEnd; ++wit )
00346 *wit = Zero<F>();
00347 }
00348 }
00349 }
00350 };
00351
00352
00353
00354
00355
00356
00357 template< class Topology, class F >
00358 class MonomialBasisImpl;
00359
00360 template< class F >
00361 class MonomialBasisImpl< GenericGeometry::Point, F >
00362 {
00363 typedef MonomialBasisImpl< GenericGeometry::Point, F > This;
00364
00365 public:
00366 typedef GenericGeometry::Point Topology;
00367 typedef F Field;
00368
00369 static const unsigned int dimDomain = Topology::dimension;
00370
00371 typedef FieldVector< Field, dimDomain > DomainVector;
00372
00373 private:
00374 friend class MonomialBasis< Topology, Field >;
00375 friend class MonomialBasisImpl< GenericGeometry::Prism< Topology >, Field >;
00376 friend class MonomialBasisImpl< GenericGeometry::Pyramid< Topology >, Field >;
00377
00378 template< int dimD >
00379 void evaluate ( const unsigned int deriv, const unsigned int order,
00380 const FieldVector< Field, dimD > &x,
00381 const unsigned int block, const unsigned int *const offsets,
00382 Field *const values ) const
00383 {
00384 *values = Unity< F >();
00385 F *const end = values + block;
00386 for( Field *it = values+1 ; it != end; ++it )
00387 *it = Zero< F >();
00388 }
00389
00390 void integrate ( const unsigned int order,
00391 const unsigned int *const offsets,
00392 Field *const values ) const
00393 {
00394 values[ 0 ] = Unity< Field >();
00395 }
00396 };
00397
00398 template< class BaseTopology, class F >
00399 class MonomialBasisImpl< GenericGeometry::Prism< BaseTopology >, F >
00400 {
00401 typedef MonomialBasisImpl< GenericGeometry::Prism< BaseTopology >, F > This;
00402
00403 public:
00404 typedef GenericGeometry::Prism< BaseTopology > Topology;
00405 typedef F Field;
00406
00407 static const unsigned int dimDomain = Topology::dimension;
00408
00409 typedef FieldVector< Field, dimDomain > DomainVector;
00410
00411 private:
00412 friend class MonomialBasis< Topology, Field >;
00413 friend class MonomialBasisImpl< GenericGeometry::Prism< Topology >, Field >;
00414 friend class MonomialBasisImpl< GenericGeometry::Pyramid< Topology >, Field >;
00415
00416 typedef MonomialBasisSize< BaseTopology > BaseSize;
00417 typedef MonomialBasisSize< Topology > Size;
00418
00419 MonomialBasisImpl< BaseTopology, Field > baseBasis_;
00420
00421 MonomialBasisImpl ()
00422 {}
00423
00424 template< int dimD >
00425 void evaluate ( const unsigned int deriv, const unsigned int order,
00426 const FieldVector< Field, dimD > &x,
00427 const unsigned int block, const unsigned int *const offsets,
00428 Field *const values ) const
00429 {
00430 typedef MonomialBasisHelper< dimDomain, dimD, Field > Helper;
00431 const BaseSize &size = BaseSize::instance();
00432
00433 const Field &z = x[ dimDomain-1 ];
00434
00435
00436 baseBasis_.evaluate( deriv, order, x, block, offsets, values );
00437
00438 Field *row0 = values;
00439 for( unsigned int k = 1; k <= order; ++k )
00440 {
00441 Field *row1 = values + block*offsets[ k-1 ];
00442 Field *wit = row1 + block*size.sizes_[ k ];
00443 Helper::copy( deriv, wit, row1, k*size.sizes_[ k ], z );
00444 Helper::copy( deriv, wit, row0, size( k-1 ), z );
00445 row0 = row1;
00446 }
00447 }
00448
00449 void integrate ( const unsigned int order,
00450 const unsigned int *const offsets,
00451 Field *const values ) const
00452 {
00453 const BaseSize &size = BaseSize::instance();
00454 const Size &mySize = Size::instance();
00455
00456 baseBasis_.integrate( order, offsets, values );
00457 const unsigned int *const baseSizes = size.sizes_;
00458
00459 Field *row0 = values;
00460 for( unsigned int k = 1; k <= order; ++k )
00461 {
00462 Field *const row1begin = values + offsets[ k-1 ];
00463 Field *const row1End = row1begin + mySize.sizes_[ k ];
00464 assert( (unsigned int)(row1End - values) <= offsets[ k ] );
00465
00466 Field *row1 = row1begin;
00467 Field *it = row1begin + baseSizes[ k ];
00468 for( unsigned int j = 1; j <= k; ++j )
00469 {
00470 Field *const end = it + baseSizes[ k ];
00471 assert( (unsigned int)(end - values) <= offsets[ k ] );
00472 for( ; it != end; ++row1, ++it )
00473 *it = (Field( j ) / Field( j+1 )) * (*row1);
00474 }
00475 for( ; it != row1End; ++row0, ++it )
00476 *it = (Field( k ) / Field( k+1 )) * (*row0);
00477 row0 = row1;
00478 }
00479 }
00480 };
00481
00482 template< class BaseTopology, class F >
00483 class MonomialBasisImpl< GenericGeometry::Pyramid< BaseTopology >, F >
00484 {
00485 typedef MonomialBasisImpl< GenericGeometry::Pyramid< BaseTopology >, F > This;
00486
00487 public:
00488 typedef GenericGeometry::Pyramid< BaseTopology > Topology;
00489 typedef F Field;
00490
00491 static const unsigned int dimDomain = Topology::dimension;
00492
00493 typedef FieldVector< Field, dimDomain > DomainVector;
00494
00495 private:
00496 friend class MonomialBasis< Topology, Field >;
00497 friend class MonomialBasisImpl< GenericGeometry::Prism< Topology >, Field >;
00498 friend class MonomialBasisImpl< GenericGeometry::Pyramid< Topology >, Field >;
00499
00500 typedef MonomialBasisSize< BaseTopology > BaseSize;
00501 typedef MonomialBasisSize< Topology > Size;
00502
00503 MonomialBasisImpl< BaseTopology, Field > baseBasis_;
00504
00505 MonomialBasisImpl ()
00506 {
00507 }
00508
00509 template< int dimD >
00510 void evaluateSimplexBase ( const unsigned int deriv, const unsigned int order,
00511 const FieldVector< Field, dimD > &x,
00512 const unsigned int block, const unsigned int *const offsets,
00513 Field *const values,
00514 const BaseSize &size ) const
00515 {
00516 baseBasis_.evaluate( deriv, order, x, block, offsets, values );
00517 }
00518
00519 template< int dimD >
00520 void evaluatePyramidBase ( const unsigned int deriv, const unsigned int order,
00521 const FieldVector< Field, dimD > &x,
00522 const unsigned int block, const unsigned int *const offsets,
00523 Field *const values,
00524 const BaseSize &size ) const
00525 {
00526 Field omz = Unity< Field >() - x[ dimDomain-1 ];
00527
00528 if( Zero< Field >() < omz )
00529 {
00530 const Field invomz = Unity< Field >() / omz;
00531 FieldVector< Field, dimD > y;
00532 for( unsigned int i = 0; i < dimDomain-1; ++i )
00533 y[ i ] = x[ i ] * invomz;
00534
00535
00536 baseBasis_.evaluate( deriv, order, y, block, offsets, values );
00537
00538 Field omzk = omz;
00539 for( unsigned int k = 1; k <= order; ++k )
00540 {
00541 Field *it = values + block*offsets[ k-1 ];
00542 Field *const end = it + block*size.sizes_[ k ];
00543 for( ; it != end; ++it )
00544 *it *= omzk;
00545 omzk *= omz;
00546 }
00547 }
00548 else
00549 {
00550 assert( deriv==0 );
00551 *values = Unity< Field >();
00552 for( unsigned int k = 1; k <= order; ++k )
00553 {
00554 Field *it = values + block*offsets[ k-1 ];
00555 Field *const end = it + block*size.sizes_[ k ];
00556 for( ; it != end; ++it )
00557 *it = Zero< Field >();
00558 }
00559 }
00560 }
00561
00562 template< int dimD >
00563 void evaluate ( const unsigned int deriv, const unsigned int order,
00564 const FieldVector< Field, dimD > &x,
00565 const unsigned int block, const unsigned int *const offsets,
00566 Field *const values ) const
00567 {
00568 typedef MonomialBasisHelper< dimDomain, dimD, Field > Helper;
00569 const BaseSize &size = BaseSize::instance();
00570
00571 if( GenericGeometry::IsSimplex< Topology >::value )
00572 evaluateSimplexBase( deriv, order, x, block, offsets, values, size );
00573 else
00574 evaluatePyramidBase( deriv, order, x, block, offsets, values, size );
00575
00576 Field *row0 = values;
00577 for( unsigned int k = 1; k <= order; ++k )
00578 {
00579 Field *row1 = values + block*offsets[ k-1 ];
00580 Field *wit = row1 + block*size.sizes_[ k ];
00581 Helper::copy( deriv, wit, row0, size( k-1 ), x[ dimDomain-1 ] );
00582 row0 = row1;
00583 }
00584 }
00585
00586 void integrate ( const unsigned int order,
00587 const unsigned int *const offsets,
00588 Field *const values ) const
00589 {
00590 const BaseSize &size = BaseSize::instance();
00591
00592
00593 baseBasis_.integrate( order, offsets, values );
00594
00595 const unsigned int *const baseSizes = size.sizes_;
00596
00597 Field *const col0End = values + baseSizes[ 0 ];
00598 for( Field *it = values; it != col0End; ++it )
00599 *it *= Field( 1 ) / Field( int(dimDomain) );
00600 Field *row0 = values;
00601
00602 for( unsigned int k = 1; k <= order; ++k )
00603 {
00604 const Field factor = (Field( 1 ) / Field( k + dimDomain ));
00605
00606 Field *const row1 = values+offsets[ k-1 ];
00607 Field *const col0End = row1 + baseSizes[ k ];
00608 Field *it = row1;
00609 for( ; it != col0End; ++it )
00610 *it *= factor;
00611 for( unsigned int i = 1; i <= k; ++i )
00612 {
00613 Field *const end = it + baseSizes[ k-i ];
00614 assert( (unsigned int)(end - values) <= offsets[ k ] );
00615 for( ; it != end; ++row0, ++it )
00616 *it = (*row0) * (Field( i ) * factor);
00617 }
00618 row0 = row1;
00619 }
00620 }
00621 };
00622
00623
00624
00625
00626
00627
00628 template< class Topology, class F >
00629 class MonomialBasis
00630 : public MonomialBasisImpl< Topology, F >
00631 {
00632 typedef MonomialBasis< Topology, F > This;
00633 typedef MonomialBasisImpl< Topology, F > Base;
00634
00635 public:
00636 static const unsigned int dimension = Base::dimDomain;
00637 static const unsigned int dimRange = 1;
00638
00639 typedef typename Base::Field Field;
00640
00641 typedef typename Base::DomainVector DomainVector;
00642
00643 typedef Dune::FieldVector<Field,dimRange> RangeVector;
00644
00645 typedef MonomialBasisSize<Topology> Size;
00646
00647 MonomialBasis (unsigned int order)
00648 : Base(),
00649 order_(order),
00650 size_(Size::instance())
00651 {
00652 assert(order<=1024);
00653 }
00654
00655 const unsigned int *sizes ( unsigned int order ) const
00656 {
00657 size_.computeSizes( order );
00658 return size_.numBaseFunctions_;
00659 }
00660
00661 const unsigned int *sizes () const
00662 {
00663 return sizes( order_ );
00664 }
00665
00666 const unsigned int size () const
00667 {
00668 size_.computeSizes( order_ );
00669 return size_( order_ );
00670 }
00671
00672 const unsigned int derivSize ( const unsigned int deriv ) const
00673 {
00674 typedef typename GenericGeometry::SimplexTopology< dimension >::type SimplexTopology;
00675 MonomialBasisSize< SimplexTopology >::instance().computeSizes( deriv );
00676 return MonomialBasisSize< SimplexTopology >::instance()( deriv );
00677 }
00678
00679 const unsigned int order () const
00680 {
00681 return order_ ;
00682 }
00683
00684 const unsigned int topologyId ( ) const
00685 {
00686 return Topology::id;
00687 }
00688
00689 void evaluate ( const unsigned int deriv, const DomainVector &x,
00690 Field *const values ) const
00691 {
00692 Base::evaluate( deriv, order_, x, derivSize( deriv ), sizes( order_ ), values );
00693 }
00694
00695 template <unsigned int deriv>
00696 void evaluate ( const DomainVector &x,
00697 Field *const values ) const
00698 {
00699 evaluate( deriv, x, values );
00700 }
00701
00702 template<unsigned int deriv, class Vector >
00703 void evaluate ( const DomainVector &x,
00704 Vector &values ) const
00705 {
00706 evaluate<deriv>(x,&(values[0]));
00707 }
00708 template<unsigned int deriv, DerivativeLayout layout >
00709 void evaluate ( const DomainVector &x,
00710 Derivatives<Field,dimension,1,deriv,layout> *values ) const
00711 {
00712 evaluate<deriv>(x,&(values->block()));
00713 }
00714 template< unsigned int deriv >
00715 void evaluate ( const DomainVector &x,
00716 FieldVector<Field,Derivatives<Field,dimension,1,deriv,value>::size> *values ) const
00717 {
00718 evaluate(0,x,&(values[0][0]));
00719 }
00720
00721 template<class Vector >
00722 void evaluate ( const DomainVector &x,
00723 Vector &values ) const
00724 {
00725 evaluate<0>(x,&(values[0]));
00726 }
00727
00728 template< class DVector, class RVector >
00729 void evaluate ( const DVector &x, RVector &values ) const
00730 {
00731 assert( DVector::size == dimension);
00732 DomainVector bx;
00733 for( int d = 0; d < dimension; ++d )
00734 field_cast( x[ d ], bx[ d ] );
00735 evaluate<0>( bx, values );
00736 }
00737
00738 void integrate ( Field *const values ) const
00739 {
00740 Base::integrate( order_, sizes( order_ ), values );
00741 }
00742 template <class Vector>
00743 void integrate ( Vector &values ) const
00744 {
00745 integrate( &(values[ 0 ]) );
00746 }
00747 private:
00748 MonomialBasis(const This&);
00749 This& operator=(const This&);
00750 unsigned int order_;
00751 Size &size_;
00752 };
00753
00754
00755
00756
00757
00758
00759 template< int dim,class F >
00760 class StandardMonomialBasis
00761 : public MonomialBasis< typename GenericGeometry::SimplexTopology< dim >::type, F >
00762 {
00763 typedef StandardMonomialBasis< dim, F > This;
00764 typedef MonomialBasis< typename GenericGeometry::SimplexTopology< dim >::type, F > Base;
00765
00766 public:
00767 typedef typename GenericGeometry::SimplexTopology< dim >::type Topology;
00768 static const int dimension = dim;
00769
00770 StandardMonomialBasis ( unsigned int order )
00771 : Base( order )
00772 {}
00773 };
00774
00775
00776
00777
00778
00779
00780 template< int dim, class F >
00781 class StandardBiMonomialBasis
00782 : public MonomialBasis< typename GenericGeometry::CubeTopology< dim >::type, F >
00783 {
00784 typedef StandardBiMonomialBasis< dim, F > This;
00785 typedef MonomialBasis< typename GenericGeometry::CubeTopology< dim >::type, F > Base;
00786
00787 public:
00788 typedef typename GenericGeometry::CubeTopology< dim >::type Topology;
00789 static const int dimension = dim;
00790
00791 StandardBiMonomialBasis ( unsigned int order )
00792 : Base( order )
00793 {}
00794 };
00795
00796
00797
00798
00799
00800
00801 template< int dim, class F >
00802 class VirtualMonomialBasis
00803 {
00804 typedef VirtualMonomialBasis< dim, F > This;
00805
00806 public:
00807 typedef F Field;
00808 typedef F StorageField;
00809 static const int dimension = dim;
00810 static const unsigned int dimRange = 1;
00811
00812 typedef FieldVector<Field,dimension> DomainVector;
00813 typedef FieldVector<Field,dimRange> RangeVector;
00814
00815 explicit VirtualMonomialBasis(unsigned int topologyId,
00816 unsigned int order)
00817 : order_(order), topologyId_(topologyId) {}
00818
00819 virtual ~VirtualMonomialBasis() {}
00820
00821 virtual const unsigned int *sizes ( ) const = 0;
00822
00823 const unsigned int size ( ) const
00824 {
00825 return sizes( )[ order_ ];
00826 }
00827
00828 const unsigned int order () const
00829 {
00830 return order_;
00831 }
00832
00833 const unsigned int topologyId ( ) const
00834 {
00835 return topologyId_;
00836 }
00837
00838 virtual void evaluate ( const unsigned int deriv, const DomainVector &x,
00839 Field *const values ) const = 0;
00840 template < unsigned int deriv >
00841 void evaluate ( const DomainVector &x,
00842 Field *const values ) const
00843 {
00844 evaluate( deriv, x, values );
00845 }
00846 template < unsigned int deriv, int size >
00847 void evaluate ( const DomainVector &x,
00848 Dune::FieldVector<Field,size> *const values ) const
00849 {
00850 evaluate( deriv, x, &(values[0][0]) );
00851 }
00852 template<unsigned int deriv, DerivativeLayout layout >
00853 void evaluate ( const DomainVector &x,
00854 Derivatives<Field,dimension,1,deriv,layout> *values ) const
00855 {
00856 evaluate<deriv>(x,&(values->block()));
00857 }
00858 template <unsigned int deriv, class Vector>
00859 void evaluate ( const DomainVector &x,
00860 Vector &values ) const
00861 {
00862 evaluate<deriv>( x, &(values[ 0 ]) );
00863 }
00864 template< class Vector >
00865 void evaluate ( const DomainVector &x,
00866 Vector &values ) const
00867 {
00868 evaluate<0>(x,values);
00869 }
00870 template< class DVector, class RVector >
00871 void evaluate ( const DVector &x, RVector &values ) const
00872 {
00873 assert( DVector::size == dimension);
00874 DomainVector bx;
00875 for( int d = 0; d < dimension; ++d )
00876 field_cast( x[ d ], bx[ d ] );
00877 evaluate<0>( bx, values );
00878 }
00879 template< unsigned int deriv, class DVector, class RVector >
00880 void evaluate ( const DVector &x, RVector &values ) const
00881 {
00882 assert( DVector::size == dimension);
00883 DomainVector bx;
00884 for( int d = 0; d < dimension; ++d )
00885 field_cast( x[ d ], bx[ d ] );
00886 evaluate<deriv>( bx, values );
00887 }
00888
00889 virtual void integrate ( Field *const values ) const = 0;
00890 template <class Vector>
00891 void integrate ( Vector &values ) const
00892 {
00893 integrate( &(values[ 0 ]) );
00894 }
00895 protected:
00896 unsigned int order_;
00897 unsigned int topologyId_;
00898 };
00899
00900 template< class Topology, class F >
00901 class VirtualMonomialBasisImpl
00902 : public VirtualMonomialBasis< Topology::dimension, F >
00903 {
00904 typedef VirtualMonomialBasis< Topology::dimension, F > Base;
00905 typedef VirtualMonomialBasisImpl< Topology, F > This;
00906
00907 public:
00908 typedef typename Base::Field Field;
00909 typedef typename Base::DomainVector DomainVector;
00910
00911 VirtualMonomialBasisImpl(unsigned int order)
00912 : Base(Topology::id,order), basis_(order)
00913 {}
00914
00915 const unsigned int *sizes ( ) const
00916 {
00917 return basis_.sizes(order_);
00918 }
00919
00920 void evaluate ( const unsigned int deriv, const DomainVector &x,
00921 Field *const values ) const
00922 {
00923 basis_.evaluate(deriv,x,values);
00924 }
00925
00926 void integrate ( Field *const values ) const
00927 {
00928 basis_.integrate(values);
00929 }
00930
00931 private:
00932 MonomialBasis<Topology,Field> basis_;
00933 using Base::order_;
00934 };
00935
00936
00937
00938
00939 template< int dim, class F >
00940 struct MonomialBasisFactory;
00941
00942 template< int dim, class F >
00943 struct MonomialBasisFactoryTraits
00944 {
00945 static const unsigned int dimension = dim;
00946 typedef unsigned int Key;
00947 typedef const VirtualMonomialBasis< dimension, F > Object;
00948 typedef MonomialBasisFactory<dim,F> Factory;
00949 };
00950
00951 template< int dim, class F >
00952 struct MonomialBasisFactory :
00953 public TopologyFactory< MonomialBasisFactoryTraits<dim,F> >
00954 {
00955 static const unsigned int dimension = dim;
00956 typedef F StorageField;
00957 typedef MonomialBasisFactoryTraits<dim,F> Traits;
00958
00959 typedef typename Traits::Key Key;
00960 typedef typename Traits::Object Object;
00961
00962 template < int dd, class FF >
00963 struct EvaluationBasisFactory
00964 {
00965 typedef MonomialBasisFactory<dd,FF> Type;
00966 };
00967
00968 template< class Topology >
00969 static Object* createObject ( const Key &order )
00970 {
00971 return new VirtualMonomialBasisImpl< Topology, StorageField >( order );
00972 }
00973 };
00974
00975
00976
00977
00978
00979
00980 template< int dim, class SF >
00981 struct MonomialBasisProvider
00982 : public TopologySingletonFactory< MonomialBasisFactory< dim, SF > >
00983 {
00984 static const unsigned int dimension = dim;
00985 typedef SF StorageField;
00986 template < int dd, class FF >
00987 struct EvaluationBasisFactory
00988 {
00989 typedef MonomialBasisProvider<dd,FF> Type;
00990 };
00991 };
00992
00993 }
00994
00995 #endif