indexsets.hh

00001 #ifndef DUNE_ALBERTAGRIDINDEXSETS_HH
00002 #define DUNE_ALBERTAGRIDINDEXSETS_HH
00003 
00004 #if HAVE_ALBERTA
00005 
00006 #include <dune/common/stdstreams.hh>
00007 
00008 #include <dune/grid/common/grid.hh>
00009 #include <dune/grid/common/indexidset.hh>
00010 #include <dune/grid/common/indexstack.hh>
00011 
00012 #include <dune/grid/albertagrid/albertaheader.hh>
00013 #include <dune/grid/albertagrid/misc.hh>
00014 #include <dune/grid/albertagrid/referencetopo.hh>
00015 #include <dune/grid/albertagrid/dofadmin.hh>
00016 #include <dune/grid/albertagrid/dofvector.hh>
00017 #include <dune/grid/albertagrid/elementinfo.hh>
00018 
00019 namespace Dune
00020 {
00021 
00022   // External Forward Declarations
00023   // -----------------------------
00024 
00025   template< int dim, int dimworld >
00026   class AlbertaGrid;
00027 
00028   template< int codim, int dim, class GridImp >
00029   class AlbertaGridEntity;
00030 
00031 
00032 
00033   namespace Alberta
00034   {
00035     typedef Dune::IndexStack< int, 100000 > IndexStack;
00036 
00037     static IndexStack *currentIndexStack = 0;
00038   }
00039 
00040 
00041 
00043   template <class GridImp>
00044   struct AlbertaGridHierarchicIteratorTypes
00045   {
00047     template<int cd>
00048     struct Codim
00049     {
00050       template<PartitionIteratorType pitype>
00051       struct Partition
00052       {
00053         /*
00054           We use the remove_const to extract the Type from the mutable class,
00055           because the const class is not instantiated yet.
00056         */
00057         typedef typename remove_const<GridImp>::type::Traits::template Codim<cd>::template Partition<pitype>::LeafIterator Iterator;
00058       };
00059     };
00060   };
00061 
00062 
00063 
00064   // AlbertaGridHierarchicIndexSet
00065   // -----------------------------
00066 
00067   template< int dim, int dimworld >
00068   class AlbertaGridHierarchicIndexSet
00069   : public IndexSetDefaultImplementation
00070     < AlbertaGrid< dim, dimworld >,
00071       AlbertaGridHierarchicIndexSet< dim,dimworld >,
00072       AlbertaGridHierarchicIteratorTypes< AlbertaGrid< dim, dimworld > > >
00073   {
00074     typedef AlbertaGridHierarchicIndexSet< dim, dimworld > This;
00075 
00076     friend class AlbertaGrid< dim, dimworld >;
00077 
00078     typedef AlbertaGrid< dim, dimworld > Grid;
00079 
00080     typedef typename Grid::Traits Traits;
00081 
00082     static const int dimension = Grid::dimension;
00083 
00084     typedef Alberta::DofVectorPointer< int > IndexVectorPointer;
00085 
00086     template< int codim >
00087     class DofAccess;
00088 
00089     class InitEntityNumber;
00090 
00091     template< int codim >
00092     struct CreateEntityNumbers;
00093 
00094     template< int codim >
00095     class RefineNumbering;
00096 
00097     template< int codim >
00098     class CoarsenNumbering;
00099 
00100     explicit AlbertaGridHierarchicIndexSet ( const Grid &grid );
00101 
00102   public:
00103     typedef Alberta::IndexStack IndexStack;
00104 
00106     template< class Entity >
00107     bool contains ( const Entity & ) const
00108     {
00109       return true; 
00110     }
00111     
00113     template< class Entity >
00114     int index ( const Entity &entity ) const
00115     {
00116       const int codim = Entity::codimension;
00117       return index< codim >( entity );
00118     }
00119 
00121     template< int codim >
00122     int index ( const typename Grid::Traits::template Codim< codim >::Entity &entity ) const
00123     {
00124       const AlbertaGridEntity< codim, dim, const Grid > &entityImp
00125         = Grid::getRealImplementation( entity );
00126       return subIndex< codim >( entityImp.elementInfo().el(), entityImp.subEntity() );
00127     }
00128 
00130     template< int codim >
00131     int subIndex ( const typename Traits::template Codim< 0 >::Entity &entity, int i ) const
00132     {
00133       const AlbertaGridEntity< 0, dim, const Grid > &entityImp
00134         = Grid::getRealImplementation( entity );
00135       const int j = entityImp.grid().dune2alberta( codim, i );
00136       return subIndex< codim >( entityImp.elementInfo().el(), j );
00137     }
00138 
00140     int size ( GeometryType type ) const
00141     {
00142       return (type.isSimplex() ? size( dimension - type.dim() ) : 0);
00143     }
00144 
00146     int size ( int codim ) const
00147     {
00148       assert( (codim >= 0) && (codim <= dimension) );
00149       return indexStack_[ codim ].size();
00150     }
00151 
00153     const std::vector< GeometryType > &geomTypes( int codim ) const
00154     {
00155       assert( (codim >= 0) && (codim <= dimension) );
00156       return geomTypes_[ codim ];
00157     }
00158 
00159 #ifdef INDEXSET_HAS_ITERATORS
00160 
00162     template<int cd, PartitionIteratorType pitype>
00163     typename AlbertaGridHierarchicIteratorTypes<Grid>::template Codim<cd>::
00164       template Partition<pitype>::Iterator end () const
00165     {
00166       return grid_.template leafend<cd,pitype> ();
00167     }
00168 
00171     template<int cd, PartitionIteratorType pitype>
00172     typename AlbertaGridHierarchicIteratorTypes<Grid>::template Codim<cd>::
00173       template Partition<pitype>::Iterator begin () const
00174     {
00175       return grid_.template leafbegin<cd,pitype> ();
00176     }
00177 #endif
00178 
00179     template< int codim >
00180     int subIndex ( const Alberta::ElementInfo< dimension > &elementInfo, int i ) const
00181     {
00182       assert( !elementInfo == false );
00183       return subIndex< codim >( elementInfo.el(), i );
00184     }
00185 
00191     template< int codim >
00192     int subIndex ( const Alberta::Element *element, int i ) const
00193     {
00194       Int2Type< codim > codimVariable;
00195 
00196       int *array = (int *)entityNumbers_[ codim ];
00197       const int subIndex = array[ dofAccess_[ codimVariable ]( element, i ) ];
00198       assert( (subIndex >= 0) && (subIndex < size( codim )) );
00199       return subIndex;
00200     }
00201 
00202     void preAdapt ()
00203     {
00204       // set global pointer to index stack
00205       if( !IndexVectorPointer::supportsAdaptationData )
00206       {
00207         assert( Alberta::currentIndexStack == 0 );
00208         Alberta::currentIndexStack = indexStack_;
00209       }
00210     }
00211 
00212     void postAdapt ()
00213     {
00214       // remove global pointer to index stack
00215       if( !IndexVectorPointer::supportsAdaptationData )
00216         Alberta::currentIndexStack = 0;
00217     }
00218 
00219     void create ( const Alberta::HierarchyDofNumbering< dimension > &dofNumbering )
00220     {
00221       Alberta::ForLoop< CreateEntityNumbers, 0, dimension >::apply( dofNumbering, *this );
00222     }
00223 
00224     void read ( const std::string &filename,
00225                 const Alberta::MeshPointer< dimension > &mesh )
00226     {
00227       Alberta::ForLoop< CreateEntityNumbers, 0, dimension >::apply( filename, mesh, *this );
00228     }
00229 
00230     bool write ( const std::string &filename ) const
00231     {
00232       bool success = true;
00233       for( int i = 0; i <= dimension; ++i )
00234       {
00235         std::ostringstream s;
00236         s << filename << ".cd" << i;
00237         success &= entityNumbers_[ i ].write( s.str() );
00238       }
00239       return success;
00240     }
00241 
00242     void release ()
00243     {
00244       for( int i = 0; i <= dimension; ++i )
00245         entityNumbers_[ i ].release();
00246     }
00247 
00248   private:
00249     template< int codim >
00250     static IndexStack &getIndexStack ( const IndexVectorPointer &dofVector )
00251     {
00252       IndexStack *indexStack;
00253       if( IndexVectorPointer::supportsAdaptationData )
00254         indexStack = dofVector.template getAdaptationData< IndexStack >();
00255       else
00256         indexStack = &Alberta::currentIndexStack[ codim ];
00257       assert( indexStack != 0 );
00258       return *indexStack;
00259     }
00260 
00261   private:
00262 #ifdef INDEXSET_HAS_ITERATORS
00263     // the grid this index set belongs to
00264     const Grid &grid_;
00265 #endif
00266 
00267     // index stacks providing new numbers during adaptation
00268     IndexStack indexStack_[ dimension+1 ];
00269 
00270     // dof vectors storing the (persistent) numbering
00271     IndexVectorPointer entityNumbers_[ dimension+1 ];
00272 
00273     // access to the dof vectors
00274     Alberta::CodimTable< DofAccess, dimension > dofAccess_;
00275 
00276     // all geometry types contained in the grid
00277     std::vector< GeometryType > geomTypes_[ dimension+1 ];
00278   };
00279 
00280 
00281 
00282   template< int dim, int dimworld >
00283   inline AlbertaGridHierarchicIndexSet< dim, dimworld >
00284     ::AlbertaGridHierarchicIndexSet ( const Grid &grid )
00285 #ifdef INDEXSET_HAS_ITERATORS
00286   : grid_( grid )
00287 #endif
00288   {
00289     for( int codim = 0; codim <= dimension; ++codim )
00290     {
00291       const GeometryType type( GeometryType::simplex, dimension - codim );
00292       geomTypes_[ codim ].push_back( type );
00293     }
00294   }
00295 
00296 
00297 
00298   // AlbertaGridHierarchicIndexSet::DofAccess
00299   // ----------------------------------------
00300 
00301   template< int dim, int dimworld >
00302   template< int codim >
00303   class AlbertaGridHierarchicIndexSet< dim, dimworld >::DofAccess
00304   : public Alberta::DofAccess< dim, codim >
00305   {
00306     typedef Alberta::DofAccess< dim, codim > Base;
00307 
00308   public:
00309     DofAccess ()
00310     {}
00311 
00312     explicit DofAccess ( const Alberta::DofSpace *dofSpace )
00313     : Base( dofSpace )
00314     {}
00315   };
00316 
00317 
00318   
00319   // AlbertaGridHierarchicIndexSet::InitEntityNumber
00320   // -----------------------------------------------
00321 
00322   template< int dim, int dimworld >
00323   class AlbertaGridHierarchicIndexSet< dim, dimworld >::InitEntityNumber
00324   {
00325     IndexStack &indexStack_;
00326 
00327   public:
00328     InitEntityNumber ( IndexStack &indexStack )
00329     : indexStack_( indexStack )
00330     {}
00331 
00332     void operator() ( int &dof )
00333     {
00334       dof = indexStack_.getIndex();
00335     }
00336   };
00337 
00338 
00339 
00340   // AlbertaGridHierarchicIndexSet::CreateEntityNumbers
00341   // --------------------------------------------------
00342 
00343   template< int dim, int dimworld >
00344   template< int codim >
00345   struct AlbertaGridHierarchicIndexSet< dim, dimworld >::CreateEntityNumbers
00346   {
00347     static void setup ( AlbertaGridHierarchicIndexSet< dim, dimworld > &indexSet )
00348     {
00349       IndexVectorPointer &entityNumbers = indexSet.entityNumbers_[ codim ];
00350 
00351       Int2Type< codim > codimVariable;
00352       indexSet.dofAccess_[ codimVariable ] = DofAccess< codim >( entityNumbers.dofSpace() );
00353 
00354       entityNumbers.template setupInterpolation< RefineNumbering< codim > >();
00355       entityNumbers.template setupRestriction< CoarsenNumbering< codim > >();
00356       entityNumbers.setAdaptationData( &(indexSet.indexStack_[ codim ]) );
00357     }
00358 
00359     static void apply ( const Alberta::HierarchyDofNumbering< dimension > &dofNumbering,
00360                         AlbertaGridHierarchicIndexSet< dim, dimworld > &indexSet )
00361     {
00362       const Alberta::DofSpace *dofSpace = dofNumbering.dofSpace( codim );
00363 
00364       std::ostringstream s;
00365       s << "Numbering for codimension " << codim;
00366       indexSet.entityNumbers_[ codim ].create( dofSpace, s.str() );
00367 
00368       InitEntityNumber init( indexSet.indexStack_[ codim ] );
00369       indexSet.entityNumbers_[ codim ].forEach( init );
00370 
00371       setup( indexSet );
00372     }
00373 
00374     static void apply ( const std::string &filename,
00375                         const Alberta::MeshPointer< dimension > &mesh,
00376                         AlbertaGridHierarchicIndexSet< dim, dimworld > &indexSet )
00377     {
00378       std::ostringstream s;
00379       s << filename << ".cd" << codim;
00380       indexSet.entityNumbers_[ codim ].read( s.str(), mesh );
00381 
00382       const int maxIndex = max( indexSet.entityNumbers_[ codim ] );
00383       indexSet.indexStack_[ codim ].setMaxIndex( maxIndex + 1 );
00384 
00385       setup( indexSet );
00386     }
00387   };
00388 
00389 
00390 
00391   // AlbertaGridHierarchicIndexSet::RefineNumbering
00392   // ----------------------------------------------
00393 
00394   template< int dim, int dimworld >
00395   template< int codim >
00396   struct AlbertaGridHierarchicIndexSet< dim, dimworld >::RefineNumbering
00397   {
00398     static const int dimension = dim;
00399     static const int codimension = codim;
00400 
00401   private:
00402     typedef Alberta::Patch< dimension > Patch;
00403     typedef Alberta::DofAccess< dimension, codimension > DofAccess;
00404 
00405     IndexStack &indexStack_;
00406     IndexVectorPointer dofVector_;
00407     DofAccess dofAccess_;
00408 
00409     explicit RefineNumbering ( const IndexVectorPointer &dofVector )
00410     : indexStack_( getIndexStack< codimension >( dofVector ) ),
00411       dofVector_( dofVector ),
00412       dofAccess_( dofVector.dofSpace() )
00413     {}
00414 
00415   public:
00416     void operator() ( const Alberta::Element *child, int subEntity )
00417     {
00418       int *const array = (int *)dofVector_;
00419       const int dof = dofAccess_( child, subEntity );
00420       array[ dof ] = indexStack_.getIndex();
00421     }
00422 
00423     static void interpolateVector ( const IndexVectorPointer &dofVector,
00424                                     const Patch &patch )
00425     {
00426       RefineNumbering refineNumbering( dofVector );
00427       patch.forEachInteriorSubChild( refineNumbering );
00428     }
00429   };
00430 
00431 
00432 
00433   // AlbertaGridHierarchicIndexSet::CoarsenNumbering
00434   // -----------------------------------------------
00435 
00436   template< int dim, int dimworld >
00437   template< int codim >
00438   struct AlbertaGridHierarchicIndexSet< dim, dimworld >::CoarsenNumbering
00439   {
00440     static const int dimension = dim;
00441     static const int codimension = codim;
00442 
00443   private:
00444     typedef Alberta::Patch< dimension > Patch;
00445     typedef Alberta::DofAccess< dimension, codimension > DofAccess;
00446 
00447     IndexStack &indexStack_;
00448     IndexVectorPointer dofVector_;
00449     DofAccess dofAccess_;
00450 
00451     explicit CoarsenNumbering ( const IndexVectorPointer &dofVector )
00452     : indexStack_( getIndexStack< codimension >( dofVector ) ),
00453       dofVector_( dofVector ),
00454       dofAccess_( dofVector.dofSpace() )
00455     {}
00456 
00457   public:
00458     void operator() ( const Alberta::Element *child, int subEntity )
00459     {
00460       int *const array = (int *)dofVector_;
00461       const int dof = dofAccess_( child, subEntity );
00462       indexStack_.freeIndex( array[ dof ] );
00463     }
00464 
00465     static void restrictVector ( const IndexVectorPointer &dofVector,
00466                                  const Patch &patch )
00467     {
00468       CoarsenNumbering coarsenNumbering( dofVector );
00469       patch.forEachInteriorSubChild( coarsenNumbering );
00470     }
00471   };
00472 
00473 
00474 
00475   // AlbertaGridIdSet
00476   // ----------------
00477 
00479   template< int dim, int dimworld >
00480   class AlbertaGridIdSet
00481   : public IdSetDefaultImplementation
00482     < AlbertaGrid< dim, dimworld >, AlbertaGridIdSet< dim, dimworld >, unsigned int >
00483   {
00484     typedef AlbertaGridIdSet< dim, dimworld > This;
00485     typedef AlbertaGrid< dim, dimworld > Grid;
00486     typedef IdSetDefaultImplementation< Grid, This, unsigned int > Base;
00487 
00488     friend class AlbertaGrid< dim, dimworld >;
00489 
00490     static const int codimShift = 30;
00491     static const int maxCodimSize = (1 << codimShift);
00492 
00493     typedef typename Grid::HierarchicIndexSet HierarchicIndexSet;
00494 
00495     const HierarchicIndexSet &hIndexSet_;
00496 
00498     AlbertaGridIdSet ( const HierarchicIndexSet &hIndexSet )
00499     : hIndexSet_( hIndexSet )
00500     {}
00501 
00502   public:
00504     typedef typename Base::IdType IdType;
00505 
00507     template< class Entity >
00508     IdType id ( const Entity &e ) const
00509     {
00510       const int codim = Entity::codimension;
00511       return id< codim >( e );
00512     }
00513 
00515     template< int codim >
00516     IdType id ( const typename Grid::template Codim< codim >::Entity &e ) const
00517     {
00518       assert( hIndexSet_.size( codim ) < maxCodimSize );
00519       const IdType index = hIndexSet_.index( e );
00520       return ((IdType)codim << codimShift) + index;
00521     }
00522 
00524     template< int codim >
00525     IdType subId ( const typename Grid::template Codim< 0 >::Entity &e, int i ) const
00526     {
00527       assert( hIndexSet_.size( codim ) < maxCodimSize );
00528       const IdType index = hIndexSet_.template subIndex< codim >( e, i );
00529       return ((IdType)codim << codimShift) + index;
00530     }
00531   };
00532 
00533 } // namespace Dune
00534 
00535 #endif // HAVE_ALBERTA
00536 
00537 #endif

Generated on Sun Nov 15 22:28:42 2009 for dune-grid by  doxygen 1.5.6