alugrid/3d/indexsets.hh

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

Generated on 6 Nov 2008 with Doxygen (ver 1.5.6) [logfile].