- Home
- About DUNE
- Download
- Documentation
- Community
- Development
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 ¯oId = 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
Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].