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