alugrid/2d/indexsets.hh

00001 #ifndef DUNE_ALU2DGRIDINDEXSETS_HH
00002 #define DUNE_ALU2DGRIDINDEXSETS_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 "alu2dinclude.hh"
00017 
00018 namespace Dune {
00019 
00021   template <class GridImp>
00022   struct ALU2dGridHierarchicIteratorTypes
00023   {
00025     template<int cd>
00026     struct Codim
00027     {
00028       template<PartitionIteratorType pitype>
00029       struct Partition
00030       {
00031         typedef typename GridImp::Traits::template Codim<cd>::template Partition<pitype>::LeafIterator Iterator;
00032       };
00033     };
00034   };
00035 
00036   // Forward declarations
00037   template <int dim, int dimworld>
00038   class ALU2dGrid;
00039 
00040   template<int cd, int dim, class GridImp>
00041   class ALU2dGridEntity;
00042 
00044   template <int dim, int dimworld> 
00045   class ALU2dGridHierarchicIndexSet : 
00046     public IndexSetDefaultImplementation <ALU2dGrid<dim,dimworld>, 
00047       ALU2dGridHierarchicIndexSet<dim,dimworld>, 
00048       ALU2dGridHierarchicIteratorTypes<ALU2dGrid<dim,dimworld> > >
00049   {
00050     typedef ALU2dGrid<dim,dimworld> GridType;
00051     enum { numCodim = dim+1 }; // i.e. 3 
00052 
00053     ALU2dGridHierarchicIndexSet(const GridType & grid) : grid_(grid) 
00054     {
00055     }
00056     friend class ALU2dGrid<dim,dimworld>;
00057         
00058   public:
00059     typedef typename GridType::Traits::template Codim<0>::Entity EntityCodim0Type;
00060   
00062     template <class EntityType>
00063     int index (const EntityType & ep) const
00064     {
00065       enum { cd = EntityType :: codimension };
00066       return (grid_.getRealImplementation(ep)).getIndex();
00067     }
00068 
00070     template <int cd>
00071     int subIndex (const EntityCodim0Type & ep, int i) const
00072     {
00073       const ALU2dGridEntity<0,dim,const GridType> & en = (grid_.getRealImplementation(ep));
00074       return en.template getSubIndex<cd>(i);
00075     }
00076 
00079     int size ( GeometryType type ) const
00080     {
00081       const int codim = dim-type.dim();      
00082       assert( grid_.geomTypes(codim).size() == 1 );
00083       if( type != grid_.geomTypes(codim)[0] ) return 0;
00084       // return size of hierarchic index set
00085       return grid_.hierSetSize(codim);
00086     }
00087 
00089     int size ( int codim ) const
00090     {
00091       // return size of hierarchic index set
00092       return grid_.hierSetSize(codim);
00093     }
00094 
00096     const std::vector<GeometryType>& geomTypes (int codim) const
00097     {
00098       return grid_.geomTypes(codim);
00099     }
00100 
00103     template<int cd, PartitionIteratorType pitype>
00104     typename ALU2dGridHierarchicIteratorTypes<GridType>::template Codim<cd>::
00105       template Partition<pitype>::Iterator end () const
00106     { 
00107       return grid_.template leafend<cd,pitype> ();
00108     } 
00109         
00112     template<int cd, PartitionIteratorType pitype>
00113     typename ALU2dGridHierarchicIteratorTypes<GridType>::template Codim<cd>::
00114       template Partition<pitype>::Iterator begin () const
00115     {       
00116       return grid_.template leafbegin<cd,pitype> ();
00117     }   
00118 
00120     template <class EntityType>
00121     bool contains (const EntityType &) const { return true; }
00122 
00123   private:
00124     // our Grid 
00125     const GridType & grid_;
00126   };
00127 
00128   //*****************************************************************
00129   //
00130   //  --GlobalIdSet 
00131   //
00132   //*****************************************************************
00133   /*
00135   template <int dim, int dimworld> 
00136   class ALU2dGridGlobalIdSet : 
00137     public IdSetDefaultImplementation  < ALU2dGrid<dim,dimworld> , 
00138                    ALU2dGridGlobalIdSet<dim,dimworld> ,
00139                    typename
00140                      ALU2dGrid<dim,dimworld>::Traits::GlobalIdType > 
00141   {
00142     typedef ALU2dGrid<dim,dimworld> GridType;
00143     typedef typename GridType :: HierarchicIndexSet  HierarchicIndexSetType;
00144     
00145     // ??? 
00146     typedef ALU2dImplTraits<elType> ImplTraitsType;
00147     typedef typename ImplTraitsType::IMPLElementType IMPLElementType;
00148     typedef typename ImplTraitsType::GEOFaceType GEOFaceType;
00149     typedef typename ImplTraitsType::GEOEdgeType GEOEdgeType;
00150     
00151     typedef ALU3DSPACE HElementType HElementType;
00152     typedef ALU3DSPACE HFaceType HFaceType;
00153     typedef ALU3DSPACE HEdgeType HEdgeType;
00154     typedef ALU3DSPACE VertexType VertexType;
00155 
00156     enum { vertexShiftBits = 32 };
00157     enum { codimShiftBits  = 2  };
00158     enum { levelShiftBits  = 6  };
00159     enum { nChildShiftBits = 4  };
00160 
00161   public:
00163     typedef typename ALU2dGrid<dim,dimworld>::Traits::GlobalIdType IdType; 
00164 
00165   private:
00166     enum { numCodim = dim+1 };
00167 
00168     // this means that only up to 300000000 entities are allowed 
00169     typedef typename GridType::Traits::template Codim<0>::Entity EntityCodim0Type;
00170 
00172     ALU2dGridGlobalIdSet(const GridType & grid) : grid_(grid), hset_(grid.hierarchicIndexSet()) 
00173     {
00174       if(elType == hexa) 
00175       {
00176         // see ALUGrid/src/serial/gitter_mgb.cc 
00177         // InsertUniqueHexa 
00178         const int vxKey[4] = {0,1,3,4};
00179         for(int i=0; i<4; i++) vertexKey_[i] = vxKey[i]; 
00180       }
00181       else 
00182       {
00183         assert( elType == tetra );
00184         // see ALUGrid/src/serial/gitter_mgb.cc 
00185         // InsertUniqueTetra 
00186         const int vxKey[4] = {0,1,2,3};
00187         for(int i=0; i<4; i++) vertexKey_[i] = vxKey[i]; 
00188       }
00189       
00190       // setup the id set 
00191       buildIdSet();
00192     }
00193 
00194     // update id set after adaptation 
00195     void updateIdSet() 
00196     {
00197       // to be revised 
00198       buildIdSet();
00199     }
00200 
00201     // print all ids 
00202     void print () const 
00203     {
00204       for(int i=0 ;i<numCodim; ++i) 
00205       {
00206         std::cout << "*****************************************************\n";
00207         std::cout << "Ids for codim " << i << "\n";
00208         std::cout << "*****************************************************\n";
00209         for(unsigned int k=0; k<ids_[i].size(); ++k)
00210         {
00211           std::cout << "Item[" << i << "," << k <<"] has id " << ids_[i][k] << "\n";
00212         }
00213         std::cout << "\n\n\n";
00214       }
00215     }
00216 
00217     void checkId(const IdType & id , int codim , unsigned int num ) const 
00218     {
00219       for(int i=0 ;i<numCodim; ++i) 
00220       {
00221         for(unsigned int k=0; k<ids_[i].size(); ++k)
00222         {
00223           if((i == codim) && (k == num)) continue; 
00224           assert(!(id == ids_[i][k]));
00225         }
00226       }
00227     }
00228 
00229     // check id set for uniqueness 
00230     void uniquenessCheck() const 
00231     {
00232       for(int i=0 ;i<numCodim; i++) 
00233       {
00234         for(unsigned int k=0; k<ids_[i].size(); ++k)
00235         {
00236           checkId(ids_[i][k],i,k);
00237         }
00238       }
00239     }
00240 
00241     // creates the id set 
00242     void buildIdSet () 
00243     {
00244       for(int i=0; i<numCodim; ++i)
00245       {
00246         ids_[i].resize( hset_.size(i) );
00247         for(unsigned int k=0; k<ids_[i].size(); ++k)
00248         {
00249           ids_[i][k] = -1;
00250         }
00251       }
00252       
00253       ALU2DSPACE GitterImplType & gitter = const_cast<ALU2DSPACE
00254         GitterImplType &> (grid_.myGrid());
00255 
00256       {
00257         ALU2DSPACE AccessIterator <VertexType>::Handle fw (gitter.container ()) ;
00258         for (fw.first () ; ! fw.done () ; fw.next ()) 
00259         {
00260           int idx = fw.item().getIndex();
00261           ids_[3][idx] = buildVertexId( fw.item() );
00262         }
00263       }
00264         
00265       // create ids for all macro edges 
00266       {
00267         ALU3DSPACE AccessIterator <HEdgeType> :: Handle w (gitter.container ()) ;
00268         for (w.first(); !w.done(); w.next()) 
00269         {
00270           int idx = w.item().getIndex();
00271           ids_[2][idx] = buildEdgeId( w.item() );
00272           buildEdgeIds( w.item() , ids_[2][idx] , 0 );
00273         }
00274       }
00275 
00276       // for all macro faces and all children 
00277       {
00278         ALU3DSPACE AccessIterator <HFaceType>::Handle w (gitter.container ()) ;
00279         for (w.first () ; ! w.done () ; w.next ()) 
00280         {
00281           int idx = w.item().getIndex();
00282           ids_[1][idx] = buildFaceId( w.item() );
00283           buildFaceIds( w.item() , ids_[1][idx] , 0 );
00284         }
00285       }
00286 
00287       // for all macro elements and all internal entities
00288       {
00289         ALU3DSPACE AccessIterator <HElementType> :: Handle w (gitter.container ()) ;
00290         for (w.first () ; ! w.done () ; w.next ()) 
00291         {
00292           int idx = w.item().getIndex();
00293           ids_[0][idx] = buildMacroId( w.item() );
00294           buildElementIds( w.item() , ids_[0][idx] , 0);
00295         }
00296       }
00297 
00298       uniquenessCheck();
00299       //print();
00300     }
00301 
00302     IdType buildVertexId(const VertexType & item )
00303     {
00304       // first the codim 
00305       IdType id(3); 
00306       
00307       // then the four identifying vertex indices 
00308       int idx = item.ident(); 
00309       id = id << vertexShiftBits;
00310       id = id+ IdType(idx);
00311       
00312       //std::cout << "Element[" << elem.getIndex() << "] has id = " <<id<< " key\n";
00313       // create offset 
00314       id = id << 3*vertexShiftBits;
00315       return id;
00316     }
00317 
00318     IdType buildEdgeId(const HEdgeType & item )
00319     {
00320       const GEOEdgeType & elem = static_cast<const GEOEdgeType &> (item);
00321       assert( elem.level () == 0);
00322       //assert( elem.nChild() == 0);
00323 
00324       // first the codim 
00325       IdType id(2); 
00326       
00327       // then the four identifying vertex indices 
00328       for(int i=0; i<2; i++) 
00329       {
00330         int idx = elem.myvertex(i)->ident(); 
00331         id = id << vertexShiftBits;
00332         id = id+ IdType(idx);
00333       }
00334 
00335       // create offset 
00336       id = id << 2*vertexShiftBits;
00337 
00338       //std::cout << "Element[" << elem.getIndex() << "] has id = " <<id<< " key\n";
00339       return id;
00340     }
00341     
00342     IdType buildFaceId(const HFaceType & item )
00343     {
00344       const GEOFaceType & elem = static_cast<const GEOFaceType &> (item);
00345       assert( elem.level () == 0);
00346       //assert( elem.nChild() == 0);
00347 
00348       // first the codim 
00349       IdType id(1); 
00350       
00351       // then the four identifying vertex indices 
00352       for(int i=0; i<3; i++) 
00353       {
00354         int idx = elem.myvertex(i)->ident(); 
00355         id = id << vertexShiftBits;
00356         id = id+ IdType(idx);
00357       }
00358 
00359       // create offset 
00360       id = id << vertexShiftBits;
00361       //std::cout << "Element[" << elem.getIndex() << "] has id = " <<id<< " key\n";
00362       return id;
00363     }
00364 
00365     IdType buildMacroId(const ALU3DSPACE HElementType & item )
00366     {
00367       const IMPLElementType & elem = static_cast<const IMPLElementType &> (item);
00368       assert( elem.level () == 0);
00369       //assert( elem.nChild() == 0);
00370 
00371 
00372       // first the codim 
00373       IdType id(0); 
00374       
00375       // then the four identifying vertex indices 
00376       for(int i=0; i<4; i++) 
00377       {
00378         int idx = elem.myvertex(vertexKey_[i])->ident(); 
00379         id = id << vertexShiftBits;
00380         id = id+ IdType(idx);
00381       }
00382 
00383       //std::cout << "Element[" << elem.getIndex() << "] has id = " <<id<< " key\n";
00384       return id;
00385     }
00386 
00387     template <int cd> 
00388     IdType createId(const typename ImplTraitsType::
00389         template Codim<cd>::InterfaceType & item , const IdType & fatherId , int nChild )
00390     {
00391       // id is fathers id + number of child 
00392       IdType id(fatherId);
00393 
00394       id = id << codimShiftBits; 
00395       id = id + IdType(cd);
00396 
00397       id = id << nChildShiftBits; 
00398       id = id + IdType(nChild);
00399 
00400       //std::cout << "Item<" << cd << ">[" << elem.getIndex() << "] has id = " <<id<< " key\n";
00401       return id;
00402     }
00403 
00404     void buildElementIds(const HElementType & item , const IdType & macroId , int nChild )
00405     {
00406       enum { codim = 0 };
00407       ids_[codim][item.getIndex()] = createId<codim>(item,macroId,nChild);
00408       const IdType & fatherId = ids_[codim][item.getIndex()];
00409       
00410       // build id for inner vertex 
00411       {
00412         const VertexType * v = item.innerVertex() ; 
00413         if(v) buildVertexIds(*v,fatherId ); 
00414       }
00415       
00416       // build edge ids for all inner edges 
00417       { 
00418         int inneredge = 0;
00419         for(const HEdgeType * e = item.innerHedge () ; e ; e = e->next ())
00420         {
00421           buildEdgeIds(*e,fatherId,inneredge); 
00422           ++inneredge;
00423         }
00424       }
00425 
00426       // build face ids for all inner faces 
00427       {
00428         int innerface = 0;
00429         for(const HFaceType * f = item.innerHface () ; f ; f = f->next ())
00430         {
00431           buildFaceIds(*f,fatherId,innerface); 
00432           ++innerface;
00433         }
00434       }
00435 
00436       // build ids of all children 
00437       {       
00438         int numChild = 0;
00439         for(const HElementType * child = item.down(); child; child =child->next() )
00440         {
00441           buildElementIds(*child, fatherId, numChild);
00442           ++numChild;
00443         }
00444       }
00445     }
00446 
00447     void buildFaceIds(const HFaceType & face, const IdType & fatherId , int
00448         innerFace )
00449     {
00450       enum { codim = 1 };
00451       ids_[codim][face.getIndex()] = createId<codim>(face,fatherId,innerFace); 
00452       const IdType & faceId = ids_[codim][face.getIndex()];
00453       // build id for inner vertex 
00454       {
00455         const VertexType * v = face.innerVertex() ; 
00456         if(v) buildVertexIds(*v,faceId ); 
00457       }
00458       
00459       // build ids for all inner edges 
00460       {
00461         int inneredge = 0;
00462         for (const HEdgeType * e = face.innerHedge () ; e ; e = e->next ()) 
00463         {
00464           buildEdgeIds(*e,faceId ,inneredge ); 
00465           ++inneredge;
00466         }
00467       }
00468       
00469       // build ids for all child faces 
00470       {
00471         int child = 0;
00472         for(const HFaceType * f = face.down () ; f ; f = f->next ())
00473         {
00474           buildFaceIds(*f,faceId,child); 
00475           ++child;
00476         }
00477       }
00478     }
00479 
00480     void buildEdgeIds(const HEdgeType & edge, const IdType & fatherId , int inneredge )
00481     {
00482       enum { codim = 2 };
00483       ids_[codim][edge.getIndex()] = createId<codim>(edge,fatherId,inneredge); 
00484       const IdType & edgeId = ids_[codim][edge.getIndex()];
00485 
00486       // build id for inner vertex 
00487       {
00488         const VertexType * v = edge.innerVertex() ; 
00489         if(v) buildVertexIds(*v,edgeId ); 
00490       }
00491       
00492       // build ids for all inner edges 
00493       {
00494         int child = 0;
00495         for (const HEdgeType * e = edge.down () ; e ; e = e->next ()) 
00496         {
00497           buildEdgeIds(*e,edgeId , child ); 
00498           ++child;
00499         }
00500       }
00501     }
00502 
00503     void buildVertexIds(const VertexType & vertex, const IdType & fatherId )
00504     {
00505       enum { codim = 3 };
00506       ids_[codim][vertex.getIndex()] = createId<codim>(vertex,fatherId,0); 
00507     }
00508 
00509     friend class ALU3dGrid<dim,dimworld,elType>;
00510   public:
00512     template <class EntityType>
00513     IdType id (const EntityType & ep) const
00514     {
00515       enum { cd = EntityType :: codimension };
00516       return ids_[cd][hset_.index(ep)];
00517     }
00518 
00520     template <int codim>
00521     IdType id (const typename GridType:: template Codim<codim> :: Entity & ep) const
00522     {
00523       return ids_[codim][hset_.index(ep)];
00524     }
00525 
00527     template <int cd>
00528     IdType subId (const EntityCodim0Type & ep, int i) const
00529     {
00530       return ids_[cd][hset_.template subIndex<cd>(ep,i)];
00531     }
00532 
00533   private:
00534     mutable std::vector< IdType > ids_[numCodim];
00535     // our Grid 
00536     const GridType & grid_;
00537 
00538     // the hierarchicIndexSet 
00539     const HierarchicIndexSetType & hset_;
00540     
00541     int vertexKey_[4];
00542   };
00543 */
00544 
00545   //***********************************************************
00546   //
00547   //  --LocalIdSet 
00548   //
00549   //***********************************************************
00550 
00552   template <int dim, int dimworld> 
00553   class ALU2dGridLocalIdSet : 
00554     public IdSetDefaultImplementation < ALU2dGrid<dim,dimworld> , 
00555                    ALU2dGridLocalIdSet<dim,dimworld> ,
00556                    int > 
00557   {
00558     typedef ALU2dGrid<dim,dimworld> GridType;
00559     typedef typename GridType :: HierarchicIndexSet HierarchicIndexSetType;
00560 
00561     // this means that only up to 300000000 entities are allowed 
00562     enum { codimMultiplier = 300000000 };
00563     typedef typename GridType::Traits::template Codim<0>::Entity EntityCodim0Type;
00564  
00565     // create local id set , only for the grid allowed 
00566     ALU2dGridLocalIdSet(const GridType & grid) : hset_(grid.hierarchicIndexSet()) 
00567     {
00568       for(int i=0; i<dim+1; i++)
00569         codimStart_[i] = i*codimMultiplier; 
00570     }
00571     friend class ALU2dGrid<dim,dimworld>;
00572 
00573     // fake method to have the same method like GlobalIdSet 
00574     void updateIdSet() {}
00575 
00576   public:
00578     typedef int IdType;
00579 
00581     template <class EntityType>
00582     int id (const EntityType & ep) const
00583     {
00584       enum { cd = EntityType :: codimension };
00585       assert( hset_.size(cd) < codimMultiplier );
00586       return codimStart_[cd] + hset_.index(ep);
00587     }
00588 
00590     template <int codim>
00591     int id (const typename GridType:: template Codim<codim> :: Entity & ep) const
00592     {
00593       //enum { cd = EntityType :: codimension };
00594       assert( hset_.size(codim) < codimMultiplier );
00595       return codimStart_[codim] + hset_.index(ep);
00596     }
00597 
00599     template <int cd>
00600     int subId (const EntityCodim0Type & ep, int i) const
00601     {
00602       assert( hset_.size(cd) < codimMultiplier );
00603       return codimStart_[cd] + hset_.template subIndex<cd>(ep,i);
00604     }
00605 
00606   private:
00607     // our HierarchicIndexSet 
00608     const HierarchicIndexSetType & hset_;
00609 
00610     // store start of each codim numbers 
00611     int codimStart_[dim+1]; 
00612   };
00613 
00614 } // end namespace Dune 
00615 
00616 #endif

Generated on 9 Apr 2008 with Doxygen (ver 1.5.2) [logfile].