dune-grid  2.1.1
alugrid/3d/indexsets.hh
Go to the documentation of this file.
00001 #ifndef DUNE_ALU3DGRIDINDEXSETS_HH
00002 #define DUNE_ALU3DGRIDINDEXSETS_HH
00003 
00004 //- System includes
00005 #include <vector>
00006 
00007 //- Dune includes
00008 #include <dune/common/stdstreams.hh>
00009 #include <dune/common/bigunsignedint.hh>
00010 
00011 #include <dune/grid/common/grid.hh>
00012 #include <dune/grid/common/indexidset.hh>
00013 
00014 
00015 //- Local includes
00016 #include "alu3dinclude.hh"
00017 #include "topology.hh"
00018 #include "alu3diterators.hh"
00019 
00020 namespace Dune
00021 {
00022 
00023   // External Forward Declarations
00024   // -----------------------------
00025 
00026   template< ALU3dGridElementType, class >
00027   class ALU3dGrid;
00028 
00029   template<int cd, int dim, class GridImp>
00030   class ALU3dGridEntity;
00031 
00032 
00033 
00034   // ALU3dGridHierarchicIndexSet
00035   // ---------------------------
00036 
00038   template< ALU3dGridElementType elType, class Comm >
00039   class ALU3dGridHierarchicIndexSet
00040   : public IndexSet< ALU3dGrid< elType, Comm >, ALU3dGridHierarchicIndexSet< elType, Comm > >
00041   {
00042     typedef ALU3dGridHierarchicIndexSet< elType, Comm > This;
00043 
00044     typedef ALU3dGrid< elType, Comm > GridType;
00045     enum { numCodim = GridType::dimension + 1 };
00046 
00047     friend class ALU3dGrid< elType, Comm >;
00048 
00049     // constructor 
00050     ALU3dGridHierarchicIndexSet( const GridType &grid )
00051     : grid_( grid )
00052     {}
00053 
00054   public:
00055     typedef typename GridType::Traits::template Codim<0>::Entity EntityCodim0Type;
00056   
00058     template <class EntityType>
00059     int index (const EntityType & ep) const
00060     {
00061       enum { cd = EntityType :: codimension };
00062       return index<cd>(ep);
00063     }
00064 
00066     template< int codim >
00067     int index ( const typename GridType::Traits::template Codim< codim >::Entity &entity ) const
00068     {
00069       return GridType::getRealImplementation( entity ).getIndex();
00070     }
00071 
00073     int subIndex ( const EntityCodim0Type &e, int i, unsigned int codim ) const
00074     {
00075       // call method subIndex on real implementation 
00076       return GridType::getRealImplementation( e ).subIndex( i, codim );
00077     }
00078 
00081     int size ( GeometryType type ) const
00082     {
00083       if( elType == tetra && !type.isSimplex() ) return 0;
00084       if( elType == hexa  && !type.isCube() ) return 0;
00085       // return size of hierarchic index set
00086       return this->size(GridType::dimension-type.dim());
00087     }
00088 
00090     int size ( int codim ) const
00091     {
00092       // return size of hierarchic index set
00093       return grid_.hierSetSize(codim);
00094     }
00095 
00097     const std::vector<GeometryType>& geomTypes (int codim) const
00098     {
00099       return grid_.geomTypes(codim);
00100     }
00101 
00103     template <class EntityType>
00104     bool contains (const EntityType &) const { return true; }
00105 
00106   private:
00107     // our Grid 
00108     const GridType & grid_;
00109   };
00110 
00115 
00116   class ALUMacroKey : public ALU3DSPACE Key4<int>  
00117   {
00118     typedef int A; 
00119     typedef ALUMacroKey ThisType;
00120     typedef ALU3DSPACE Key4<A> BaseType;
00121     
00122     public:
00123     ALUMacroKey() : BaseType(-1,-1,-1,-1) {}
00124     ALUMacroKey(const A&a,const A&b,const A&c,const A&d) : BaseType(a,b,c,d) {}
00125     ALUMacroKey(const ALUMacroKey & org ) : BaseType(org) {}
00126     ALUMacroKey & operator = (const ALUMacroKey & org )
00127     {
00128       BaseType::operator = (org);
00129       return *this;
00130     }
00131 
00132     bool operator == (const ALUMacroKey & org) const
00133     {
00134       return ( (this->_a == org._a) && 
00135                (this->_b == org._b) && 
00136                (this->_c == org._c) && 
00137                (this->_d == org._d) ); 
00138     }
00139 
00140     // operator < is already implemented in BaseType
00141     bool operator > (const ALUMacroKey & org) const
00142     {
00143       return ( (!this->operator == (org)) && (!this->operator <(org)) ); 
00144     }
00145 
00146     void print(std::ostream & out) const 
00147     {
00148       out << "[" << this->_a << "," << this->_b << "," << this->_c << "," << this->_d << "]";
00149     }
00150   };
00151 
00152   template <class MacroKeyImp>
00153   class ALUGridId 
00154   {
00155     MacroKeyImp key_;   
00156     int nChild_;
00157     int codim_; 
00158   public:
00159     ALUGridId() : key_() 
00160                 , nChild_(-1) 
00161                 , codim_(-1) 
00162     {}
00163      
00164     ALUGridId(const MacroKeyImp & key, int nChild , int cd) 
00165       : key_(key) , nChild_(nChild)
00166       , codim_(cd)  
00167     {} 
00168      
00169     ALUGridId(const ALUGridId & org ) 
00170       : key_(org.key_) 
00171       , nChild_(org.nChild_)
00172       , codim_(org.codim_) 
00173     {} 
00174 
00175     ALUGridId & operator = (const ALUGridId & org ) 
00176     {
00177       key_    = org.key_;
00178       nChild_ = org.nChild_;
00179       codim_  = org.codim_;
00180       return *this;
00181     }
00182 
00183     bool operator == (const ALUGridId & org) const
00184     {
00185       return equals(org);
00186     }
00187 
00188     bool operator != (const ALUGridId & org) const 
00189     { 
00190       return ! equals(org);
00191     }
00192 
00193     bool operator <= (const ALUGridId & org) const
00194     {
00195       if(equals(org)) return true;
00196       else return lesser(org);
00197     }
00198 
00199     bool operator >= (const ALUGridId & org) const
00200     {
00201       if(equals(org)) return true;
00202       else return ! lesser(org);
00203     }
00204 
00205     bool operator < (const ALUGridId & org) const
00206     {
00207       return lesser(org);
00208     }
00209 
00210     bool operator > (const ALUGridId & org) const
00211     {
00212       return (!equals(org) && ! lesser(org));
00213     }
00214      
00215     const MacroKeyImp & getKey() const { return key_; }
00216     int nChild() const { return nChild_; }
00217     int codim() const  { return codim_; };
00218 
00219     bool isValid () const
00220     {
00221       return ( (nChild_ >= 0) && (codim_  >= 0) );
00222     }
00223 
00224     void reset() 
00225     {
00226       nChild_ = -1;
00227       codim_  = -1;
00228     }
00229 
00230     void print(std::ostream & out) const
00231     {
00232       out << "(" << getKey() << "," << nChild_ << "," << codim_ << ")";
00233     }
00234 
00235   protected:  
00236     // returns true is the id is lesser then org 
00237     bool lesser(const ALUGridId & org) const
00238     {
00239       if(getKey() < org.getKey() ) return true;
00240       if(getKey() > org.getKey() ) return false;
00241       if(getKey() == org.getKey() ) 
00242       {
00243         if(nChild_ == org.nChild_) 
00244         {
00245           return codim_ < org.codim_;
00246         }
00247         else 
00248           return nChild_ < org.nChild_;
00249       }
00250       assert( equals(org) );     
00251       return false;
00252     } 
00253      
00254     // returns true if this id equals org 
00255     bool equals(const ALUGridId & org) const
00256     {
00257       return ( (getKey() == org.getKey() ) && (nChild_ == org.nChild_) 
00258             && (codim_ == org.codim_) );
00259     }
00260   };
00261 
00262   inline std::ostream& operator<< (std::ostream& s, const ALUMacroKey & key) 
00263   {
00264     key.print(s);
00265     return s;
00266   }
00267     
00268   template <class KeyImp> 
00269   inline std::ostream& operator<< (std::ostream& s, const ALUGridId<KeyImp> & id) 
00270   {
00271     id.print(s);
00272     return s;
00273   }
00274 
00275   //*****************************************************************
00276   //
00277   //  --GlobalIdSet 
00278   //
00279   //*****************************************************************
00281   template< ALU3dGridElementType elType, class Comm >
00282   class ALU3dGridGlobalIdSet
00283   : public IdSet< ALU3dGrid< elType, Comm >, ALU3dGridGlobalIdSet< elType, Comm > ,
00284                   typename ALU3dGrid< elType, Comm >::Traits::GlobalIdType >,
00285     public ALU3DSPACE AdaptRestrictProlongType
00286   {
00287     typedef ALU3dGrid< elType, Comm > GridType;
00288     typedef typename GridType::HierarchicIndexSet  HierarchicIndexSetType;
00289     
00290     typedef ALU3dImplTraits< elType, Comm > ImplTraitsType;
00291     typedef typename ImplTraitsType::IMPLElementType IMPLElementType;
00292     typedef typename ImplTraitsType::GEOElementType GEOElementType;
00293     typedef typename ImplTraitsType::GEOFaceType GEOFaceType;
00294     typedef typename ImplTraitsType::GEOEdgeType GEOEdgeType;
00295   
00296     typedef typename ImplTraitsType::GitterImplType GitterImplType;
00297 
00298     typedef typename ImplTraitsType::HElementType HElementType;
00299     typedef typename ImplTraitsType::HFaceType HFaceType;
00300     typedef typename ImplTraitsType::HEdgeType HEdgeType;
00301     typedef typename ImplTraitsType::VertexType VertexType;
00302     typedef typename ImplTraitsType::HBndSegType HBndSegType;
00303 
00304     typedef EntityCount< elType > EntityCountType;
00305 
00306   public:
00308     typedef typename GridType::Traits::GlobalIdType IdType;
00309 
00310   private:
00311     typedef ALUMacroKey MacroKeyType;
00312     
00313     typedef ALUGridId <  MacroKeyType > MacroIdType; // same as IdType
00314     enum { numCodim = GridType::dimension+1 };
00315 
00316     // this means that only up to 300000000 entities are allowed 
00317     typedef typename GridType::Traits::template Codim<0>::Entity EntityCodim0Type;
00318   private:
00319     mutable std::map< int , IdType > ids_[numCodim];
00320     //mutable std::map< int , MacroKeyType > macroKeys_[numCodim];
00321     
00322     // our Grid 
00323     const GridType & grid_;
00324 
00325     // the hierarchicIndexSet 
00326     const HierarchicIndexSetType & hset_;
00327     
00328     int vertexKey_[4];
00329 
00330     int chunkSize_ ;
00331 
00332     enum { startOffSet_ = 0 };
00333     
00334   public:  
00335 
00338     using IdSet < GridType , ALU3dGridGlobalIdSet, IdType > :: subId;
00339 
00341     ALU3dGridGlobalIdSet(const GridType & grid) 
00342       : grid_(grid), hset_(grid.hierarchicIndexSet()) 
00343       , chunkSize_(100)
00344     {
00345       if(elType == hexa) 
00346       {
00347         // see ALUGrid/src/serial/gitter_mgb.cc 
00348         // InsertUniqueHexa 
00349         const int vxKey[4] = {0,1,3,4};
00350         for(int i=0; i<4; i++) vertexKey_[i] = vxKey[i]; 
00351       }
00352       else 
00353       {
00354         assert( elType == tetra );
00355         // see ALUGrid/src/serial/gitter_mgb.cc 
00356         // InsertUniqueTetra 
00357         const int vxKey[4] = {0,1,2,3};
00358         for(int i=0; i<4; i++) vertexKey_[i] = vxKey[i]; 
00359       }
00360       
00361       // setup the id set 
00362       buildIdSet();
00363     }
00364 
00365     virtual ~ALU3dGridGlobalIdSet() {}
00366 
00367     // update id set after adaptation 
00368     void updateIdSet() 
00369     {
00370       // to be revised 
00371       buildIdSet();
00372     }
00373 
00374     // print all ids 
00375     void print () const 
00376     {
00377       for(int i=0 ;i<numCodim; ++i) 
00378       {
00379         std::cout << "*****************************************************\n";
00380         std::cout << "Ids for codim " << i << "\n";
00381         std::cout << "*****************************************************\n";
00382         for(unsigned int k=0; k<ids_[i].size(); ++k)
00383         {
00384           std::cout << "Item[" << i << "," << k <<"] has id " << ids_[i][k] << "\n";
00385         }
00386         std::cout << "\n\n\n";
00387       }
00388     }
00389 
00390     template <class IterType> 
00391     void checkId(const IdType & macroId, const IterType & idIter) const //int codim , unsigned int num ) const 
00392     {
00393 
00394       IdType id = getId(macroId);
00395       for(int i=0 ;i<numCodim; ++i) 
00396       {
00397         typedef typename std::map<int,IdType>::iterator IteratorType;
00398         IteratorType end = ids_[i].end();
00399         for(IteratorType it = ids_[i].begin(); it != end; ++it)
00400         //for(unsigned int k=0; k<ids_[i].size(); ++k)
00401         {
00402           if(idIter == it) continue;
00403           //if((i == codim) && (k == num)) continue; 
00404           const IdType & checkMId = (*it).second; //ids_[i][k];
00405           IdType checkId = getId(checkMId);
00406           if( id == checkId ) 
00407           {
00408             //std::cout << "Check(codim,num = " << codim<< "," << num <<") failed for k="<<k << " codim = " << i << "\n";
00409             std::cout << id << " equals " << checkId << "\n";
00410             assert( id != checkId );
00411             DUNE_THROW(GridError," " << id << " equals " << checkId << "\n");
00412           }
00413           else 
00414           {
00415             bool lesser  = (id < checkId);
00416             bool greater = (id > checkId);
00417             assert( lesser != greater );
00418             if( lesser == greater ) 
00419             {
00420               assert( lesser != greater );
00421               DUNE_THROW(GridError," lesser equals greater of one id ");
00422             }
00423           }
00424         }
00425       }
00426     }
00427 
00428     // check id set for uniqueness 
00429     void uniquenessCheck() const 
00430     {
00431       for(int i=0 ;i<numCodim; i++) 
00432       {
00433         typedef typename std::map<int,IdType>::iterator IteratorType;
00434         IteratorType end = ids_[i].end();
00435         for(IteratorType it = ids_[i].begin(); it != end; ++it)
00436           //unsigned int k=0; k<ids_[i].size(); ++k)
00437         {
00438           const IdType & id = (*it).second; //ids_[i][k];
00439           if( id.isValid() ) 
00440             checkId(id,it);//i,k);
00441         }
00442       }
00443     }
00444 
00445     void setChunkSize( int chunkSize )
00446     {
00447       chunkSize_ = chunkSize;
00448     }
00449     
00450     // creates the id set 
00451     void buildIdSet () 
00452     {
00453       for(int i=0; i<numCodim; ++i)
00454       {
00455         ids_[i].clear();
00456       }
00457       
00458       GitterImplType &gitter = grid_.myGrid();
00459 
00460       // all interior and border vertices 
00461       {
00462         typename ALU3DSPACE AccessIterator< VertexType >::Handle fw( gitter.container() );
00463         for( fw.first (); !fw.done(); fw.next() )
00464         {
00465           int idx = fw.item().getIndex();
00466           ids_[3][idx] = buildMacroVertexId( fw.item() );
00467         }
00468       }
00469       
00470       // all ghost vertices 
00471       {
00472         typedef typename ALU3DSPACE ALU3dGridLevelIteratorWrapper< 3, Ghost_Partition, Comm > IteratorType;
00473         IteratorType fw (grid_ , 0 , grid_.nlinks() );
00474         typedef typename IteratorType :: val_t val_t; 
00475         for (fw.first () ; ! fw.done () ; fw.next ()) 
00476         {
00477           val_t & item = fw.item();
00478           assert( item.first );
00479           VertexType & vx = * (item.first); 
00480           int idx = vx.getIndex();
00481           ids_[3][idx] = buildMacroVertexId( vx );
00482         }
00483       }
00484         
00485       // create ids for all macro edges 
00486       {
00487         typename ALU3DSPACE AccessIterator< HEdgeType >::Handle w( gitter.container() );
00488         for (w.first(); !w.done(); w.next()) 
00489         {
00490           int idx = w.item().getIndex();
00491           ids_[2][idx] = buildMacroEdgeId( w.item() );
00492           buildEdgeIds( w.item() , ids_[2][idx] , startOffSet_ );
00493         }
00494       }
00495       
00496       // all ghost edges 
00497       {
00498         typedef typename ALU3DSPACE ALU3dGridLevelIteratorWrapper< 2, Ghost_Partition, Comm > IteratorType;
00499         IteratorType fw( grid_, 0, grid_.nlinks() );
00500         typedef typename IteratorType :: val_t val_t; 
00501         for (fw.first () ; ! fw.done () ; fw.next ()) 
00502         {
00503           val_t & item = fw.item();
00504           assert( item.first );
00505           HEdgeType & edge = * (item.first); 
00506           int idx = edge.getIndex();
00507           
00508           ids_[2][idx] = buildMacroEdgeId( edge );
00509           buildEdgeIds( edge , ids_[2][idx] , startOffSet_ );
00510         }
00511       }
00512         
00513 
00514       // for all macro faces and all children 
00515       {
00516         typename ALU3DSPACE AccessIterator< HFaceType >::Handle w( gitter.container() );
00517         for (w.first () ; ! w.done () ; w.next ()) 
00518         {
00519           int idx = w.item().getIndex();
00520           ids_[1][idx] = buildMacroFaceId( w.item() );
00521           buildFaceIds( w.item() , ids_[1][idx] , startOffSet_ );
00522         }
00523       }
00524 
00525       // all ghost faces  
00526       {
00527         typedef typename ALU3DSPACE ALU3dGridLevelIteratorWrapper< 1, Ghost_Partition, Comm > IteratorType; 
00528         IteratorType fw (grid_ , 0 , grid_.nlinks() );
00529         typedef typename IteratorType :: val_t val_t; 
00530         for (fw.first () ; ! fw.done () ; fw.next ()) 
00531         {
00532           val_t & item = fw.item();
00533           assert( item.first );
00534           HFaceType & face = * (item.first); 
00535           int idx = face.getIndex();
00536           ids_[1][idx] = buildMacroFaceId( face );
00537           buildFaceIds( face , ids_[1][idx] , startOffSet_ );
00538         }
00539       }
00540         
00541       // for all macro elements and all internal entities
00542       {
00543         typename ALU3DSPACE AccessIterator< HElementType >::Handle w( gitter.container() );
00544         for (w.first () ; ! w.done () ; w.next ()) 
00545         {
00546           int idx = w.item().getIndex();
00547           ids_[0][idx] = buildMacroElementId( w.item() );
00548           buildElementIds( w.item() , ids_[0][idx] , startOffSet_ );
00549         }
00550       }
00551       
00552       // all ghost elements  
00553       {
00554         typedef typename ALU3DSPACE ALU3dGridLevelIteratorWrapper< 0, Ghost_Partition, Comm > IteratorType;
00555         IteratorType fw (grid_ , 0 , grid_.nlinks() );
00556         typedef typename IteratorType :: val_t val_t; 
00557         for (fw.first () ; ! fw.done () ; fw.next ()) 
00558         {
00559           val_t & item = fw.item();
00560           assert( item.second );
00561           HElementType & elem = * ( item.second->getGhost().first ); 
00562           int idx = elem.getIndex();
00563           ids_[0][idx] = buildMacroElementId( elem );
00564           buildElementIds( elem , ids_[0][idx] , startOffSet_ );
00565         }
00566       }
00567 
00568       // check uniqueness of id only in serial, because 
00569       // in parallel some faces and edges of ghost exists more than once
00570       // but have the same id, but not the same index, there for the check
00571       // will fail for ghost elements  
00572 #if ! ALU3DGRID_PARALLEL
00573       // be carefull with this check, it's complexity is O(N^2)
00574       //uniquenessCheck();
00575 #endif
00576     }
00577 
00578     IdType buildMacroVertexId(const VertexType & item )
00579     {
00580       int vx[4] = { item.ident(), -1, -1, -1};
00581       enum {codim = 3 };
00582       MacroKeyType key(vx[0],vx[1],vx[2],vx[3]);
00583       MacroIdType id(key,1, codim + startOffSet_ );
00584       return id;
00585     }
00586 
00587     IdType buildMacroEdgeId(const HEdgeType & item )
00588     {
00589       const GEOEdgeType & edge = static_cast<const GEOEdgeType &> (item);
00590       int vx[4] = {-1,-1,-1,-1};
00591       for(int i=0; i<2; ++i) 
00592       {
00593         vx[i] = edge.myvertex(i)->ident(); 
00594       }
00595       
00596       enum { codim = 2 };
00597       MacroKeyType key(vx[0],vx[1],vx[2],vx[3]);
00598       MacroIdType id( key,1,  codim + startOffSet_ );
00599       return id;
00600     }
00601     
00602     IdType buildMacroFaceId(const HFaceType & item )
00603     {
00604       const GEOFaceType & face = static_cast<const GEOFaceType &> (item);
00605       int vx[4] = {-1,-1,-1,-1};
00606       for(int i=0; i<3; ++i) 
00607       {
00608         vx[i] = face.myvertex(i)->ident(); 
00609       }
00610       
00611       enum { codim = 1 };
00612       MacroKeyType key(vx[0],vx[1],vx[2],vx[3]);
00613       MacroIdType id(key,1,  codim + startOffSet_ );
00614       return id;
00615     }
00616 
00617     IdType buildMacroElementId(const HElementType & item )
00618     {
00619       const GEOElementType & elem = static_cast<const GEOElementType &> (item);
00620       int vx[4] = {-1,-1,-1,-1};
00621       for(int i=0; i<4; ++i) 
00622       {
00623         vx[i] = elem.myvertex(vertexKey_[i])->ident(); 
00624       }
00625       enum { codim = 0 };
00626       MacroKeyType key(vx[0],vx[1],vx[2],vx[3]);
00627       return MacroIdType(key,1,  codim + startOffSet_ );
00628     }
00629 
00630     template <int cd> 
00631     IdType createId(const typename ImplTraitsType::
00632         template Codim<cd>::InterfaceType & item , const IdType & creatorId , int nChild )
00633     {
00634       assert( creatorId.isValid() );
00635        
00636       // we have up to 12 internal hexa faces, therefore need 100 offset 
00637       enum { childOffSet = ((cd == 1) && (elType == hexa)) ? 16 : 8 };
00638       enum { codimOffSet = 4 };
00639 
00640       assert( nChild < childOffSet );
00641       
00642       int newChild = (creatorId.nChild() * childOffSet ) + nChild;
00643       int newCodim = (creatorId.codim()  * codimOffSet ) + ( cd + startOffSet_ );
00644       
00645       IdType newId( creatorId.getKey() , newChild , newCodim );
00646       assert( newId != creatorId );
00647       return newId;
00648     }
00649 
00650     // build ids for all children of this element 
00651     void buildElementIds(const HElementType & item , const IdType & macroId , int nChild)
00652     {
00653       enum { codim = 0 };
00654       ids_[codim][item.getIndex()] = createId<codim>(item,macroId,nChild);
00655 
00656       const IdType & itemId = ids_[codim][item.getIndex()];
00657 
00658       buildInteriorElementIds(item,itemId);
00659     }
00660 
00661     // build ids for all children of this element 
00662     void buildInteriorElementIds(const HElementType & item , const IdType & fatherId)
00663     {
00664       assert( fatherId.isValid() );
00665       
00666       // build id for inner vertex 
00667       {
00668         const VertexType * v = item.innerVertex() ; 
00669         // for tetras there is no inner vertex, therefore check 
00670         if(v) buildVertexIds(*v,fatherId ); 
00671       }
00672       
00673       // build edge ids for all inner edges 
00674       { 
00675         int inneredge = startOffSet_;
00676         for(const HEdgeType * e = item.innerHedge () ; e ; e = e->next ())
00677         {
00678           buildEdgeIds(*e,fatherId,inneredge); 
00679           ++inneredge;
00680         }
00681       }
00682 
00683       // build face ids for all inner faces 
00684       {
00685         int innerface = startOffSet_;
00686         for(const HFaceType * f = item.innerHface () ; f ; f = f->next ())
00687         {
00688           buildFaceIds(*f,fatherId,innerface); 
00689           ++innerface;
00690         }
00691       }
00692 
00693       // build ids of all children 
00694       {       
00695         int numChild = startOffSet_;
00696         for(const HElementType * child = item.down(); child; child =child->next() )
00697         {
00698           //assert( numChild == child->nChild() );
00699           buildElementIds(*child, fatherId, numChild);
00700           ++numChild;
00701         }
00702       }
00703     }
00704 
00705     // build ids for all children of this face 
00706     void buildFaceIds(const HFaceType & face, const IdType & fatherId , int innerFace )
00707     {
00708       enum { codim = 1 };
00709       ids_[codim][face.getIndex()] = createId<codim>(face,fatherId,innerFace); 
00710       const IdType & faceId = ids_[codim][face.getIndex()];
00711       
00712       buildInteriorFaceIds(face,faceId);
00713     }
00714     
00715     // build ids for all children of this face 
00716     void buildInteriorFaceIds(const HFaceType & face, const IdType & faceId)
00717     {
00718       assert( faceId.isValid () );
00719       
00720       // build id for inner vertex 
00721       {
00722         const VertexType * v = face.innerVertex() ; 
00723         //std::cout << "create inner vertex of face " << face.getIndex() << "\n";
00724         if(v) buildVertexIds(*v,faceId ); 
00725       }
00726       
00727       // build ids for all inner edges 
00728       {
00729         int inneredge = startOffSet_;
00730         for (const HEdgeType * e = face.innerHedge () ; e ; e = e->next ()) 
00731         {
00732           buildEdgeIds(*e,faceId ,inneredge ); 
00733           ++inneredge;
00734         }
00735       }
00736       
00737       // build ids for all child faces 
00738       {
00739         int child = startOffSet_;
00740         for(const HFaceType * f = face.down () ; f ; f = f->next ())
00741         {
00742           assert( child == f->nChild()+startOffSet_);
00743           buildFaceIds(*f,faceId,child); 
00744           ++child;
00745         }
00746       }
00747     }
00748     
00749     // build ids for all children of this edge 
00750     void buildEdgeIds(const HEdgeType & edge, const IdType & fatherId , int inneredge)
00751     {
00752       enum { codim = 2 };
00753       ids_[codim][edge.getIndex()] = createId<codim>(edge,fatherId,inneredge); 
00754       const IdType & edgeId = ids_[codim][edge.getIndex()];
00755       buildInteriorEdgeIds(edge,edgeId);
00756     }
00757     
00758     void buildInteriorEdgeIds(const HEdgeType & edge, const IdType & edgeId)
00759     {
00760       assert( edgeId.isValid() );
00761 
00762       // build id for inner vertex 
00763       {
00764         const VertexType * v = edge.innerVertex() ; 
00765         if(v) buildVertexIds(*v,edgeId ); 
00766       }
00767       
00768       // build ids for all inner edges 
00769       {
00770         int child = startOffSet_;
00771         for (const HEdgeType * e = edge.down () ; e ; e = e->next ()) 
00772         {
00773           assert( child == e->nChild()+ startOffSet_ );
00774           buildEdgeIds(*e,edgeId , child ); 
00775           ++child;
00776         }
00777       }
00778     }
00779 
00780     // build id for this vertex  
00781     void buildVertexIds(const VertexType & vertex, const IdType & fatherId )
00782     {
00783       enum { codim = 3 };
00784       // inner vertex number is 1 
00785       ids_[codim][vertex.getIndex()] = createId<codim>(vertex,fatherId,1); 
00786       assert( ids_[codim][vertex.getIndex()].isValid() );
00787     }
00788 
00789     friend class ALU3dGrid< elType, Comm >;
00790 
00791     const IdType & getId(const IdType & macroId) const
00792     {
00793       return macroId;
00794     }
00795 
00796   public:
00798     template <class EntityType>
00799     IdType id (const EntityType & ep) const
00800     {
00801       enum { cd = EntityType :: codimension };
00802       assert( ids_[cd].find( hset_.index(ep) ) != ids_[cd].end() );
00803       const IdType & macroId = ids_[cd][hset_.index(ep)]; 
00804       assert( macroId.isValid() );
00805       return getId(macroId);
00806     }
00807 
00809     template <int codim>
00810     IdType id (const typename GridType:: template Codim<codim> :: Entity & ep) const
00811     {
00812       assert( ids_[codim].find( hset_.index(ep) ) != ids_[codim].end() );
00813       const IdType & macroId = ids_[codim][hset_.index(ep)]; 
00814       assert( macroId.isValid() );
00815       return getId(macroId);
00816     }
00817 
00819     IdType subId ( const EntityCodim0Type &e, int i, unsigned int codim ) const
00820     {
00821       const int hIndex = hset_.subIndex( e, i, codim );
00822       assert( ids_[ codim ].find( hIndex ) != ids_[ codim ].end() );
00823       const IdType &macroId = ids_[ codim ][ hIndex ]; 
00824       assert( macroId.isValid() );
00825       return getId( macroId );
00826     }
00827 
00828     template <int d, ALU3dGridElementType element_t > 
00829     struct BuildIds; 
00830 
00831     template <int d> 
00832     struct BuildIds<d,tetra> 
00833     {
00834       //static const IdType zero;
00835       template <class MyIdSet, class IdStorageType>
00836       static void buildFace(MyIdSet & set, const HElementType & item, int faceNum, 
00837                   IdStorageType & ids )
00838       {
00839         const IMPLElementType & elem = static_cast<const IMPLElementType &> (item);
00840         const HFaceType & face  = *(elem.myhface3(faceNum));
00841         const IdType & id = ids[face.getIndex()];
00842         assert( id.isValid() );
00843         set.buildInteriorFaceIds(face,id);
00844       }
00845     };
00846     
00847     template <int d> 
00848     struct BuildIds<d,hexa> 
00849     {
00850       //static const IdType zero;
00851       template <class MyIdSet, class IdStorageType>
00852       static void buildFace(MyIdSet & set, const HElementType & item, int faceNum, 
00853                   IdStorageType & ids )
00854       {
00855         const IMPLElementType & elem = static_cast<const IMPLElementType &> (item);
00856         const HFaceType & face  = *(elem.myhface4(faceNum));
00857         const IdType & id = ids[face.getIndex()];
00858         assert( id.isValid() );
00859         set.buildInteriorFaceIds(face,id);
00860       }
00861     };
00862     
00863     // create ids for refined elements  
00864     int postRefinement( HElementType & item ) 
00865     {
00866       {
00867         enum { elCodim = 0 };
00868         const IdType & fatherId = ids_[elCodim][item.getIndex()];
00869         assert( fatherId.isValid() );
00870         buildInteriorElementIds(item, fatherId ); 
00871       }
00872 
00873       for(int i=0; i<EntityCountType::numFaces; ++i)
00874       {
00875         enum { faceCodim = 1 };
00876         BuildIds< GridType::dimension, elType >::buildFace(*this,item,i,ids_[faceCodim]);
00877       }
00878       
00879       for(int i=0; i<EntityCountType::numEdges; ++i)
00880       {
00881         enum { edgeCodim = 2 };
00882         const IMPLElementType & elem = static_cast<const IMPLElementType &> (item);
00883         const HEdgeType & edge  = *( elem.myhedge1(i));
00884         const IdType & id = ids_[edgeCodim][edge.getIndex()];
00885         assert( id.isValid() );
00886         buildInteriorEdgeIds(edge,id);
00887       }
00888       return 0;
00889     }
00890 
00891     // dummy functions  
00892     int preCoarsening( HElementType & elem ) 
00893     {
00894       /*
00895       const IdType & fatherId = ids_[0][item.getIndex()];
00896 
00897       removeElementIds(item,fatherId,item.nChild());
00898 
00899       for(int i=0; i<EntityCountType::numFaces; ++i)
00900         BuildIds<dim,elType>::buildFace(*this,item,i,ids_[1]);
00901       
00902       for(int i=0; i<EntityCountType::numEdges; ++i)
00903       {
00904         const IMPLElementType & elem = static_cast<const IMPLElementType &> (item);
00905         const HEdgeType & edge  = *( elem.myhedge1(i));
00906         const HEdgeType * child = edge.down();
00907         assert( child ); 
00908         if( ids_[2][child->getIndex() ] > zero_ ) continue;
00909         buildEdgeIds(edge,ids_[2][edge.getIndex()],0);
00910       }
00911 #ifndef NDEBUG
00912       //uniquenessCheck();
00913 #endif
00914       */
00915       return 0; 
00916     }
00917     
00918     // dummy functions  
00919     int preCoarsening ( HBndSegType & el ) { return 0; }
00920 
00922     int postRefinement ( HBndSegType & el ) { return 0; }
00923 
00924   };
00925 
00926   //***********************************************************
00927   //
00928   //  --LocalIdSet 
00929   //
00930   //***********************************************************
00931 
00933   template< ALU3dGridElementType elType, class Comm >
00934   class ALU3dGridLocalIdSet
00935   : public IdSet< ALU3dGrid< elType, Comm >, ALU3dGridLocalIdSet< elType, Comm >, int >,
00936     public ALU3DSPACE AdaptRestrictProlongType
00937   {
00938     typedef ALU3dGridLocalIdSet< elType, Comm > This;
00939 
00940     typedef ALU3dImplTraits< elType, Comm > ImplTraitsType;
00941     typedef typename ImplTraitsType::HElementType HElementType;
00942     typedef typename ImplTraitsType::HBndSegType HBndSegType;
00943 
00944     typedef ALU3dGrid< elType, Comm > GridType;
00945     typedef typename GridType::HierarchicIndexSet HierarchicIndexSetType;
00946 
00947     // this means that only up to 300000000 entities are allowed 
00948     enum { codimMultiplier = 300000000 };
00949     typedef typename GridType::Traits::template Codim<0>::Entity EntityCodim0Type;
00950  
00951     // create local id set , only for the grid allowed 
00952     ALU3dGridLocalIdSet(const GridType & grid) : hset_(grid.hierarchicIndexSet()) 
00953     {
00954       for( int codim = 0; codim <= GridType::dimension; ++codim )
00955         codimStart_[ codim ] = codim * codimMultiplier;
00956     }
00957 
00958     friend class ALU3dGrid< elType, Comm >;
00959 
00960     // fake method to have the same method like GlobalIdSet 
00961     void updateIdSet() {}
00962 
00963   public:
00965     typedef int IdType;
00966 
00969     using IdSet < GridType , ALU3dGridLocalIdSet, IdType > :: subId;
00970 
00972     template <class EntityType>
00973     int id (const EntityType & ep) const
00974     {
00975       enum { cd = EntityType :: codimension };
00976       assert( hset_.size(cd) < codimMultiplier );
00977       return codimStart_[cd] + hset_.index(ep);
00978     }
00979 
00981     template <int codim>
00982     int id (const typename GridType:: template Codim<codim> :: Entity & ep) const
00983     {
00984       //enum { cd = EntityType :: codimension };
00985       assert( hset_.size(codim) < codimMultiplier );
00986       return codimStart_[codim] + hset_.index(ep);
00987     }
00988 
00990     IdType subId ( const EntityCodim0Type &e, int i, unsigned int codim ) const
00991     {
00992       assert( hset_.size( codim ) < codimMultiplier );
00993       return codimStart_[ codim ] + hset_.subIndex( e, i, codim );
00994     }
00995 
00996     // dummy functions  
00997     int preCoarsening( HElementType & elem )  { return 0; }
00998     // create ids for refined elements  
00999     int postRefinement( HElementType & item )  { return 0; }
01000     
01001     // dummy functions  
01002     int preCoarsening ( HBndSegType & el ) { return 0; }
01003 
01005     int postRefinement ( HBndSegType & el ) { return 0; }
01006 
01007     void setChunkSize( int chunkSize ) {}
01008     
01009   private:
01010     // our HierarchicIndexSet 
01011     const HierarchicIndexSetType & hset_;
01012 
01013     // store start of each codim numbers 
01014     int codimStart_[ GridType::dimension+1 ];
01015   };
01016 
01017 } // end namespace Dune
01018 
01019 #endif // #ifndef DUNE_ALU3DGRIDINDEXSETS_HH