dune-grid  2.1.1
albertagrid/indexsets.hh
Go to the documentation of this file.
00001 #ifndef DUNE_ALBERTAGRIDINDEXSETS_HH
00002 #define DUNE_ALBERTAGRIDINDEXSETS_HH
00003 
00004 #include <dune/common/stdstreams.hh>
00005 
00006 #include <dune/grid/common/grid.hh>
00007 #include <dune/grid/common/indexidset.hh>
00008 #include <dune/grid/common/indexstack.hh>
00009 
00010 #include <dune/grid/albertagrid/misc.hh>
00011 #include <dune/grid/albertagrid/dofadmin.hh>
00012 #include <dune/grid/albertagrid/dofvector.hh>
00013 #include <dune/grid/albertagrid/elementinfo.hh>
00014 #include <dune/grid/albertagrid/gridfamily.hh>
00015 
00016 #if HAVE_ALBERTA
00017 
00018 namespace Dune
00019 {
00020 
00021   namespace Alberta
00022   {
00023     typedef Dune::IndexStack< int, 100000 > IndexStack;
00024 
00025     extern IndexStack *currentIndexStack;
00026   }
00027 
00028 
00029 
00030   // AlbertaGridHierarchicIndexSet
00031   // -----------------------------
00032 
00033   template< int dim, int dimworld >
00034   class AlbertaGridHierarchicIndexSet
00035   : public IndexSet< AlbertaGridFamily< dim, dimworld >, AlbertaGridHierarchicIndexSet< dim,dimworld >, int >
00036   {
00037     typedef AlbertaGridHierarchicIndexSet< dim, dimworld > This;
00038     typedef IndexSet< AlbertaGridFamily< dim, dimworld >, This, int > Base;
00039 
00040     friend class AlbertaGrid< dim, dimworld >;
00041 
00042   public:
00043     typedef AlbertaGrid< dim, dimworld > Grid;
00044     typedef AlbertaGridFamily< dim, dimworld > GridFamily;
00045 
00046     typedef typename Base::IndexType IndexType;
00047 
00048     static const int dimension = GridFamily::dimension;
00049 
00050     typedef Alberta::ElementInfo< dimension > ElementInfo;
00051     typedef Alberta::HierarchyDofNumbering< dimension > DofNumbering;
00052 
00053   private:
00054     typedef typename GridFamily::Traits Traits;
00055 
00056     typedef Alberta::DofVectorPointer< IndexType > IndexVectorPointer;
00057 
00058     class InitEntityNumber;
00059 
00060     template< int codim >
00061     struct CreateEntityNumbers;
00062 
00063     template< int codim >
00064     class RefineNumbering;
00065 
00066     template< int codim >
00067     class CoarsenNumbering;
00068 
00069     explicit AlbertaGridHierarchicIndexSet ( const DofNumbering &dofNumbering );
00070 
00071   public:
00072     typedef Alberta::IndexStack IndexStack;
00073 
00075     template< class Entity >
00076     bool contains ( const Entity & ) const
00077     {
00078       return true; 
00079     }
00080 
00081     using Base::index;
00082     using Base::subIndex;
00083 
00085     template< int cc >
00086     IndexType index ( const typename Traits::template Codim< cc >::Entity &entity ) const
00087     {
00088       typedef AlbertaGridEntity< cc, dim, const Grid > EntityImp;
00089       const EntityImp &entityImp = Grid::getRealImplementation( entity );
00090       return subIndex( entityImp.elementInfo(), entityImp.subEntity(), cc );
00091     }
00092 
00094     template< int cc >
00095     IndexType subIndex ( const typename Traits::template Codim< cc >::Entity &entity, int i, unsigned int codim ) const
00096     {
00097       typedef AlbertaGridEntity< cc, dim, const Grid > EntityImp;
00098       const EntityImp &entityImp = Grid::getRealImplementation( entity );
00099 
00100       int k = i;
00101       if( cc > 0 )
00102       {
00103         const GenericReferenceElement< Alberta::Real, dimension > &refElement
00104           = GenericReferenceElements< Alberta::Real, dimension >::simplex();
00105         k = refElement.subEntity( entityImp.subEntity(), cc, i, codim );
00106       }
00107 
00108       const int j = entityImp.grid().generic2alberta( codim, k );
00109       return subIndex( entityImp.elementInfo(), j, codim );
00110     }
00111 
00113     IndexType size ( const GeometryType &type ) const
00114     {
00115       return (type.isSimplex() ? size( dimension - type.dim() ) : 0);
00116     }
00117 
00119     IndexType size ( int codim ) const
00120     {
00121       assert( (codim >= 0) && (codim <= dimension) );
00122       return indexStack_[ codim ].size();
00123     }
00124 
00126     const std::vector< GeometryType > &geomTypes( int codim ) const
00127     {
00128       assert( (codim >= 0) && (codim <= dimension) );
00129       return geomTypes_[ codim ];
00130     }
00131 
00132     IndexType subIndex ( const ElementInfo &elementInfo, int i, unsigned int codim ) const
00133     {
00134       assert( !elementInfo == false );
00135       return subIndex( elementInfo.element(), i, codim );
00136     }
00137 
00144     IndexType subIndex ( const Alberta::Element *element, int i, unsigned int codim ) const
00145     {
00146       IndexType *array = (IndexType *)entityNumbers_[ codim ];
00147       const IndexType subIndex = array[ dofNumbering_( element, codim, i ) ];
00148       assert( (subIndex >= 0) && (subIndex < size( codim )) );
00149       return subIndex;
00150     }
00151 
00152     void preAdapt ()
00153     {
00154       // set global pointer to index stack
00155       if( !IndexVectorPointer::supportsAdaptationData )
00156       {
00157         assert( Alberta::currentIndexStack == 0 );
00158         Alberta::currentIndexStack = indexStack_;
00159       }
00160     }
00161 
00162     void postAdapt ()
00163     {
00164       // remove global pointer to index stack
00165       if( !IndexVectorPointer::supportsAdaptationData )
00166         Alberta::currentIndexStack = 0;
00167     }
00168 
00169     void create ();
00170     void read ( const std::string &filename );
00171     bool write ( const std::string &filename ) const;
00172 
00173     void release ()
00174     {
00175       for( int i = 0; i <= dimension; ++i )
00176         entityNumbers_[ i ].release();
00177     }
00178 
00179   private:
00180     template< int codim >
00181     static IndexStack &getIndexStack ( const IndexVectorPointer &dofVector )
00182     {
00183       IndexStack *indexStack;
00184       if( IndexVectorPointer::supportsAdaptationData )
00185         indexStack = dofVector.template getAdaptationData< IndexStack >();
00186       else
00187         indexStack = &Alberta::currentIndexStack[ codim ];
00188       assert( indexStack != 0 );
00189       return *indexStack;
00190     }
00191 
00192     // access to the dof vectors
00193     const DofNumbering &dofNumbering_;
00194 
00195     // index stacks providing new numbers during adaptation
00196     IndexStack indexStack_[ dimension+1 ];
00197 
00198     // dof vectors storing the (persistent) numbering
00199     IndexVectorPointer entityNumbers_[ dimension+1 ];
00200 
00201     // all geometry types contained in the grid
00202     std::vector< GeometryType > geomTypes_[ dimension+1 ];
00203   };
00204 
00205 
00206  
00207   // AlbertaGridHierarchicIndexSet::InitEntityNumber
00208   // -----------------------------------------------
00209 
00210   template< int dim, int dimworld >
00211   class AlbertaGridHierarchicIndexSet< dim, dimworld >::InitEntityNumber
00212   {
00213     IndexStack &indexStack_;
00214 
00215   public:
00216     InitEntityNumber ( IndexStack &indexStack )
00217     : indexStack_( indexStack )
00218     {}
00219 
00220     void operator() ( int &dof )
00221     {
00222       dof = indexStack_.getIndex();
00223     }
00224   };
00225 
00226 
00227 
00228   // AlbertaGridHierarchicIndexSet::CreateEntityNumbers
00229   // --------------------------------------------------
00230 
00231   template< int dim, int dimworld >
00232   template< int codim >
00233   struct AlbertaGridHierarchicIndexSet< dim, dimworld >::CreateEntityNumbers
00234   {
00235     static void setup ( AlbertaGridHierarchicIndexSet< dim, dimworld > &indexSet );
00236 
00237     static void apply ( const Alberta::HierarchyDofNumbering< dimension > &dofNumbering,
00238                         AlbertaGridHierarchicIndexSet< dim, dimworld > &indexSet );
00239 
00240     static void apply ( const std::string &filename,
00241                         const Alberta::MeshPointer< dimension > &mesh,
00242                         AlbertaGridHierarchicIndexSet< dim, dimworld > &indexSet );
00243   };
00244 
00245 
00246 
00247   // AlbertaGridHierarchicIndexSet::RefineNumbering
00248   // ----------------------------------------------
00249 
00250   template< int dim, int dimworld >
00251   template< int codim >
00252   struct AlbertaGridHierarchicIndexSet< dim, dimworld >::RefineNumbering
00253   {
00254     static const int dimension = dim;
00255     static const int codimension = codim;
00256 
00257   private:
00258     typedef Alberta::DofAccess< dimension, codimension > DofAccess;
00259 
00260     explicit RefineNumbering ( const IndexVectorPointer &dofVector )
00261     : indexStack_( getIndexStack< codimension >( dofVector ) ),
00262       dofVector_( dofVector ),
00263       dofAccess_( dofVector.dofSpace() )
00264     {}
00265 
00266   public:
00267     void operator() ( const Alberta::Element *child, int subEntity );
00268 
00269     typedef Alberta::Patch< dimension > Patch;
00270     static void interpolateVector ( const IndexVectorPointer &dofVector,
00271                                     const Patch &patch );
00272 
00273   private:
00274     IndexStack &indexStack_;
00275     IndexVectorPointer dofVector_;
00276     DofAccess dofAccess_;
00277   };
00278 
00279 
00280 
00281   // AlbertaGridHierarchicIndexSet::CoarsenNumbering
00282   // -----------------------------------------------
00283 
00284   template< int dim, int dimworld >
00285   template< int codim >
00286   struct AlbertaGridHierarchicIndexSet< dim, dimworld >::CoarsenNumbering
00287   {
00288     static const int dimension = dim;
00289     static const int codimension = codim;
00290 
00291   private:
00292     typedef Alberta::DofAccess< dimension, codimension > DofAccess;
00293 
00294     explicit CoarsenNumbering ( const IndexVectorPointer &dofVector )
00295     : indexStack_( getIndexStack< codimension >( dofVector ) ),
00296       dofVector_( dofVector ),
00297       dofAccess_( dofVector.dofSpace() )
00298     {}
00299 
00300   public:
00301     void operator() ( const Alberta::Element *child, int subEntity );
00302 
00303     typedef Alberta::Patch< dimension > Patch;
00304     static void restrictVector ( const IndexVectorPointer &dofVector,
00305                                  const Patch &patch );
00306   private:
00307     IndexStack &indexStack_;
00308     IndexVectorPointer dofVector_;
00309     DofAccess dofAccess_;
00310   };
00311 
00312 
00313 
00314   // AlbertaGridIndexSet
00315   // -------------------
00316 
00317   template< int dim, int dimworld >
00318   class AlbertaGridIndexSet
00319   : public IndexSet< AlbertaGrid< dim, dimworld >, AlbertaGridIndexSet< dim, dimworld >, int >
00320   {
00321     typedef AlbertaGridIndexSet< dim, dimworld > This;
00322     typedef IndexSet< AlbertaGrid< dim, dimworld >, This, int > Base;
00323 
00324   public:
00325     typedef AlbertaGrid< dim, dimworld > Grid;
00326 
00327     typedef typename Base::IndexType IndexType;
00328 
00329     static const int dimension = Grid::dimension;
00330 
00331     typedef Alberta::ElementInfo< dimension > ElementInfo;
00332     typedef Alberta::HierarchyDofNumbering< dimension > DofNumbering;
00333 
00334   private:
00335     typedef typename Grid::Traits Traits;
00336 
00337     template< int codim >
00338     struct Insert;
00339 
00340   public:
00341     explicit AlbertaGridIndexSet ( const DofNumbering &dofNumbering )
00342     : dofNumbering_( dofNumbering )
00343     {
00344       for( int codim = 0; codim <= dimension; ++codim )
00345       {
00346         indices_[ codim ] = 0;
00347 
00348         const GeometryType type( GeometryType::simplex, dimension - codim );
00349         geomTypes_[ codim ].push_back( type );
00350       }
00351     }
00352 
00353     ~AlbertaGridIndexSet ()
00354     {
00355       for( int codim = 0; codim <= dimension; ++codim )
00356         delete[] indices_[ codim ];
00357     }
00358 
00359     template< class Entity >
00360     bool contains ( const Entity &entity ) const
00361     {
00362       const int codim = Entity::codimension;
00363 
00364       const AlbertaGridEntity< codim, dim, const Grid > &entityImp
00365         = Grid::getRealImplementation( entity );
00366       const Alberta::Element *element = entityImp.elementInfo().el();
00367 
00368       const IndexType *const array = indices_[ codim ];
00369       const IndexType subIndex = array[ dofNumbering_( element, codim, entityImp.subEntity() ) ];
00370 
00371       return (subIndex >= 0);
00372     }
00373 
00374     using Base::index;
00375     using Base::subIndex;
00376 
00378     template< int cc >
00379     IndexType index ( const typename Traits::template Codim< cc >::Entity &entity ) const
00380     {
00381       typedef AlbertaGridEntity< cc, dim, const Grid > EntityImp;
00382       const EntityImp &entityImp = Grid::getRealImplementation( entity );
00383       return subIndex( entityImp.elementInfo(), entityImp.subEntity(), cc );
00384     }
00385 
00387     template< int cc >
00388     IndexType subIndex ( const typename Traits::template Codim< cc >::Entity &entity, int i, unsigned int codim ) const
00389     {
00390       typedef AlbertaGridEntity< cc, dim, const Grid > EntityImp;
00391       const EntityImp &entityImp = Grid::getRealImplementation( entity );
00392 
00393       int k = i;
00394       if( cc > 0 )
00395       {
00396         const GenericReferenceElement< Alberta::Real, dimension > &refElement
00397           = GenericReferenceElements< Alberta::Real, dimension >::simplex();
00398         k = refElement.subEntity( entityImp.subEntity(), cc, i, codim );
00399       }
00400 
00401       const int j = entityImp.grid().generic2alberta( codim, k );
00402       return subIndex( entityImp.elementInfo(), j, codim );
00403     }
00404 
00405     IndexType size ( const GeometryType &type ) const
00406     {
00407       return (type.isSimplex() ? size( dimension - type.dim() ) : 0);
00408     }
00409 
00410     IndexType size ( int codim ) const
00411     {
00412       assert( (codim >= 0) && (codim <= dimension) );
00413       return size_[ codim ];
00414     }
00415 
00416     const std::vector< GeometryType > &geomTypes( int codim ) const
00417     {
00418       assert( (codim >= 0) && (codim <= dimension) );
00419       return geomTypes_[ codim ];
00420     }
00421 
00422     template< class Iterator >
00423     void update ( const Iterator &begin, const Iterator &end )
00424     {
00425       for( int codim = 0; codim <= dimension; ++codim )
00426       {
00427         delete[] indices_[ codim ];
00428 
00429         const unsigned int dofSize = dofNumbering_.size( codim );
00430         indices_[ codim ] = new IndexType[ dofSize ];
00431         for( unsigned int i = 0; i < dofSize; ++i )
00432           indices_[ codim ][ i ] = -1;
00433 
00434         size_[ codim ] = 0;
00435       }
00436 
00437       for( Iterator it = begin; it != end; ++it )
00438       {
00439         const AlbertaGridEntity< 0, dim, const Grid > &entityImp
00440           = Grid::getRealImplementation( *it );
00441         const Alberta::Element *element = entityImp.elementInfo().el();
00442         ForLoop< Insert, 0, dimension >::apply( element, *this );
00443       }
00444     }
00445 
00446   private:
00447     IndexType subIndex ( const ElementInfo &elementInfo, int i, unsigned int codim ) const
00448     {
00449       assert( !elementInfo == false );
00450       return subIndex( elementInfo.element(), i, codim );
00451     }
00452 
00459     IndexType subIndex ( const Alberta::Element *element, int i, unsigned int codim ) const
00460     {
00461       const IndexType *const array = indices_[ codim ];
00462       const IndexType subIndex = array[ dofNumbering_( element, codim, i ) ];
00463       assert( (subIndex >= 0) && (subIndex < size( codim )) );
00464       return subIndex;
00465     }
00466 
00467     // access to the dof vectors
00468     const DofNumbering &dofNumbering_;
00469 
00470     // an array of indices for each codimension
00471     IndexType *indices_[ dimension+1 ];
00472 
00473     // the size of each codimension
00474     IndexType size_[ dimension+1 ];
00475 
00476     // all geometry types contained in the grid
00477     std::vector< GeometryType > geomTypes_[ dimension+1 ];
00478   };
00479 
00480 
00481 
00482   // AlbertaGridIndexSet::Insert
00483   // ---------------------------
00484 
00485   template< int dim, int dimworld >
00486   template< int codim >
00487   struct AlbertaGridIndexSet< dim, dimworld >::Insert
00488   {
00489     static void apply ( const Alberta::Element *const element,
00490                         AlbertaGridIndexSet< dim, dimworld > &indexSet )
00491     {
00492       int *const array = indexSet.indices_[ codim ];
00493       IndexType &size = indexSet.size_[ codim ];
00494 
00495       for( int i = 0; i < Alberta::NumSubEntities< dim, codim >::value; ++i )
00496       {
00497         int &index = array[ indexSet.dofNumbering_( element, codim, i ) ];
00498         if( index < 0 )
00499           index = size++;
00500       }
00501     }
00502   };
00503 
00504 
00505 
00506   // AlbertaGridIdSet
00507   // ----------------
00508 
00510   template< int dim, int dimworld >
00511   class AlbertaGridIdSet
00512   : public IdSet< AlbertaGrid< dim, dimworld >, AlbertaGridIdSet< dim, dimworld >, unsigned int >
00513   {
00514     typedef AlbertaGridIdSet< dim, dimworld > This;
00515     typedef IdSet< AlbertaGrid< dim, dimworld >, This, unsigned int > Base;
00516 
00517     friend class AlbertaGrid< dim, dimworld >;
00518 
00519   public:
00521     typedef typename Base::IdType IdType;
00522 
00523   private:
00524     typedef AlbertaGrid< dim, dimworld > Grid;
00525 
00526     static const int dimension = Grid::dimension;
00527 
00528     typedef typename Grid::HierarchicIndexSet HierarchicIndexSet;
00529 
00530     // create id set, only allowed for AlbertaGrid 
00531     AlbertaGridIdSet ( const HierarchicIndexSet &hIndexSet )
00532     : hIndexSet_( hIndexSet )
00533     {}
00534 
00535   public:
00537     template< class Entity >
00538     IdType id ( const Entity &e ) const
00539     {
00540       const int codim = Entity::codimension;
00541       return id< codim >( e );
00542     }
00543 
00545     template< int codim >
00546     IdType id ( const typename Grid::template Codim< codim >::Entity &e ) const
00547     {
00548       assert( (codim >= 0) && (codim <= dimension) );
00549       const IdType index = hIndexSet_.index( e );
00550       return (index << 2) | IdType( codim );
00551     }
00552 
00554     IdType subId ( const typename Grid::template Codim< 0 >::Entity &e, int i, unsigned int subcodim ) const
00555     {
00556       assert( int( subcodim ) <= dimension );
00557       const IdType index = hIndexSet_.subIndex( e, i, subcodim );
00558       return (index << 2) | IdType( subcodim );
00559     }
00560 
00561     template< int codim >
00562     IdType subId ( const typename Grid::template Codim< codim >::Entity &e, int i, unsigned int subcodim ) const
00563     {
00564       assert( (codim >= 0) && (codim <= dimension) && (int( codim + subcodim ) <= dimension) );
00565       const IdType index = hIndexSet_.subIndex( e, i, subcodim );
00566       return (index << 2) | IdType( codim + subcodim );
00567     }
00568 
00569     template< class Entity >
00570     IdType subId ( const Entity &e, int i, unsigned int subcodim ) const
00571     {
00572       return subId< Entity::codimension >( e, i, subcodim );
00573     }
00574 
00575   private:
00576     // prohibit copying
00577     AlbertaGridIdSet ( const This & );
00578 
00579     const HierarchicIndexSet &hIndexSet_;
00580   };
00581 
00582 } // namespace Dune
00583 
00584 #endif // #if HAVE_ALBERTA
00585 
00586 #endif // #ifndef DUNE_ALBERTAGRIDINDEXSETS_HH