1 #ifndef ALUGRID_GRID_INLINE_HH 2 #define ALUGRID_GRID_INLINE_HH 3 4 // Dune includes 5 #include <dune/common/stdstreams.hh> 6 7 // Local includes 8 #include "alu3dinclude.hh" 9 #include "entity.hh" 10 #include "iterator.hh" 11 #include "datahandle.hh" 12 #include "grid.hh" 13 14 #define alu_inline_tmp inline 15 16 namespace Dune 17 { 18 19 // Implementation of ALU3dGrid 20 // --------------------------- 21 22 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 23 inline ALU3dGrid< dim, dimworld, elType, Comm > ALU3dGrid(const std::string & macroTriangFilename,const MPICommunicatorType mpiComm,const ALUGridVertexProjectionPairType & bndPrj,const ALUGridRefinementType refinementType)24 ::ALU3dGrid ( const std::string ¯oTriangFilename, 25 const MPICommunicatorType mpiComm, 26 const ALUGridVertexProjectionPairType& bndPrj, 27 const ALUGridRefinementType refinementType ) 28 : mygrid_() 29 , maxlevel_( 0 ) 30 , coarsenMarked_( 0 ) 31 , refineMarked_( 0 ) 32 , geomTypes_() //dim+1, std::vector<GeometryType>(1) ) 33 , hIndexSet_ (*this) 34 , globalIdSet_() 35 , localIdSet_( *this ) 36 , levelIndexVec_(1) , leafIndexSet_() 37 , sizeCache_ () 38 , lockPostAdapt_( false ) 39 , vertexProjections_( bndPrj ) 40 , communications_( new Communications( mpiComm ) ) 41 , refinementType_( refinementType ) 42 { 43 // generate geometry storage and geometry type vector 44 makeGeometries(); 45 46 // check macro grid file for keyword 47 checkMacroGridFile( macroTriangFilename ); 48 49 mygrid_.reset( createALUGrid( macroTriangFilename ) ); 50 alugrid_assert ( mygrid_ ); 51 52 dverb << "************************************************" << std::endl; 53 dverb << "Created grid on p=" << comm().rank() << std::endl; 54 dverb << "************************************************" << std::endl; 55 checkMacroGrid (); 56 57 clearIsNewMarkers(); 58 calcExtras(); 59 } // end constructor 60 61 62 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > global_size(int codim) const63 inline int ALU3dGrid< dim, dimworld, elType, Comm >::global_size ( int codim ) const 64 { 65 // return actual size of hierarchical index set 66 // this is always up to date 67 // maxIndex is the largest index used + 1 68 return myGrid().indexManager(codim).getMaxIndex(); 69 } 70 71 72 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > hierSetSize(int codim) const73 inline int ALU3dGrid< dim, dimworld, elType, Comm >::hierSetSize ( int codim ) const 74 { 75 // return actual size of hierarchical index set 76 return myGrid().indexManager(codim).getMaxIndex(); 77 } 78 79 80 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > maxLevel() const81 inline int ALU3dGrid< dim, dimworld, elType, Comm >::maxLevel () const 82 { 83 return maxlevel_; 84 } 85 86 87 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 88 inline typename ALU3dGrid< dim, dimworld, elType, Comm >::GitterImplType & myGrid() const89 ALU3dGrid< dim, dimworld, elType, Comm >::myGrid () const 90 { 91 alugrid_assert ( mygrid_ ); 92 return *mygrid_; 93 } 94 95 // lbegin methods 96 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 97 template< int cd, PartitionIteratorType pitype > 98 inline typename ALU3dGrid< dim, dimworld, elType, Comm >::Traits::template Codim< cd >::template Partition< pitype >::LevelIterator lbegin(int level) const99 ALU3dGrid< dim, dimworld, elType, Comm >::lbegin ( int level ) const 100 { 101 alugrid_assert ( level >= 0 ); 102 // if we dont have this level return empty iterator 103 if( level > maxlevel_ ) 104 return this->template lend<cd,pitype> (level); 105 106 return ALU3dGridLevelIterator< cd, pitype, const ThisType >( *this, level, true ); 107 } 108 109 110 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 111 template< int cd, PartitionIteratorType pitype > 112 inline typename ALU3dGrid< dim, dimworld, elType, Comm >::Traits::template Codim< cd >::template Partition< pitype >::LevelIterator lend(int level) const113 ALU3dGrid< dim, dimworld, elType, Comm >::lend ( int level ) const 114 { 115 alugrid_assert ( level >= 0 ); 116 return ALU3dGridLevelIterator< cd, pitype, const ThisType >( *this, level ); 117 } 118 119 120 // lbegin methods 121 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 122 template< int cd > 123 inline typename ALU3dGrid< dim, dimworld, elType, Comm >::Traits::template Codim< cd >::template Partition< All_Partition >::LevelIterator lbegin(int level) const124 ALU3dGrid< dim, dimworld, elType, Comm >::lbegin ( int level ) const 125 { 126 return this->template lbegin<cd,All_Partition>( level ); 127 } 128 129 130 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 131 template< int cd > 132 inline typename ALU3dGrid< dim, dimworld, elType, Comm >::Traits::template Codim< cd >::template Partition< All_Partition >::LevelIterator lend(int level) const133 ALU3dGrid< dim, dimworld, elType, Comm >::lend ( int level ) const 134 { 135 alugrid_assert ( level >= 0 ); 136 return this->template lend<cd,All_Partition>( level ); 137 } 138 139 140 //*********************************************************** 141 // 142 // leaf methods , first all begin methods 143 // 144 //*********************************************************** 145 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 146 template< int cd, PartitionIteratorType pitype > 147 inline typename ALU3dGrid< dim, dimworld, elType, Comm >::Traits::template Codim< cd >::template Partition< pitype >::LeafIterator leafbegin() const148 ALU3dGrid< dim, dimworld, elType, Comm >::leafbegin () const 149 { 150 return ALU3dGridLeafIterator< cd, pitype, const ThisType >( *this, maxlevel_, true ); 151 } 152 153 154 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 155 template< int cd > 156 inline typename ALU3dGrid< dim, dimworld, elType, Comm >::Traits::template Codim< cd >::LeafIterator leafbegin() const157 ALU3dGrid< dim, dimworld, elType, Comm >::leafbegin () const 158 { 159 return leafbegin< cd, All_Partition> () ; 160 } 161 162 163 //**************************************************************** 164 // 165 // all leaf end methods 166 // 167 //**************************************************************** 168 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 169 template< int cd, PartitionIteratorType pitype > 170 inline typename ALU3dGrid< dim, dimworld, elType, Comm >::Traits::template Codim< cd >::template Partition< pitype >::LeafIterator leafend() const171 ALU3dGrid< dim, dimworld, elType, Comm >::leafend () const 172 { 173 return ALU3dGridLeafIterator<cd, pitype, const MyType> ( *this, maxlevel_); 174 } 175 176 177 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 178 template< int cd > 179 inline typename ALU3dGrid< dim, dimworld, elType, Comm >::Traits::template Codim< cd >::LeafIterator leafend() const180 ALU3dGrid< dim, dimworld, elType, Comm >::leafend () const 181 { 182 return leafend< cd, All_Partition> (); 183 } 184 185 //***************************************************************** 186 187 // mark given entity 188 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 189 inline bool ALU3dGrid< dim, dimworld, elType, Comm > mark(int ref,const typename Traits::template Codim<0>::Entity & entity)190 ::mark ( int ref, const typename Traits::template Codim< 0 >::Entity &entity ) 191 { 192 bool marked = entity.impl().mark( ref, conformingRefinement() ); 193 if(marked) 194 { 195 if(ref > 0) ++refineMarked_; 196 if(ref < 0) ++coarsenMarked_; 197 } 198 return marked; 199 } 200 201 202 // get Mark of given entity 203 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 204 inline int ALU3dGrid< dim, dimworld, elType, Comm > getMark(const typename Traits::template Codim<0>::Entity & entity) const205 ::getMark ( const typename Traits::template Codim< 0 >::Entity &entity ) const 206 { 207 return entity.impl().getMark(); 208 } 209 210 211 // global refine 212 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 213 template< class GridImp, class DataHandle > 214 inline 215 void ALU3dGrid< dim, dimworld, elType, Comm > globalRefine(int refCount,AdaptDataHandleInterface<GridImp,DataHandle> & handle)216 ::globalRefine ( int refCount, AdaptDataHandleInterface< GridImp, DataHandle > &handle ) 217 { 218 for( int count = std::abs(refCount); count > 0; --count ) 219 { 220 const LeafIteratorType end = leafend(); 221 for( LeafIteratorType it = leafbegin(); it != end; ++it ) 222 mark( refCount>0?1:-1 , *it ); 223 adapt( handle ); 224 } 225 } 226 227 228 // adapt grid 229 // --adapt 230 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 231 template< class GridImp, class DataHandle > 232 inline 233 bool ALU3dGrid< dim, dimworld, elType, Comm > adapt(AdaptDataHandleInterface<GridImp,DataHandle> & handle)234 ::adapt ( AdaptDataHandleInterface< GridImp, DataHandle > &handle ) 235 { 236 typedef AdaptDataHandleInterface< GridImp, DataHandle > AdaptDataHandle; 237 238 // true if at least one element was marked for coarsening 239 bool mightCoarse = preAdapt(); 240 241 bool refined = false ; 242 if(globalIdSet_) 243 { 244 // if global id set exists then include into 245 // prolongation process 246 ALU3DSPACE AdaptRestrictProlongGlSet< MyType, AdaptDataHandle, GlobalIdSetImp > 247 rp(*this, 248 handle, 249 *globalIdSet_); 250 251 refined = myGrid().duneAdapt(rp); // adapt grid 252 } 253 else 254 { 255 ALU3DSPACE AdaptRestrictProlongImpl< MyType, AdaptDataHandle > 256 rp(*this, 257 handle); 258 259 refined = myGrid().duneAdapt(rp); // adapt grid 260 } 261 262 if(refined || mightCoarse) 263 { 264 // only calc extras and skip maxLevel calculation, because of 265 // refinement maxLevel was calculated already 266 updateStatus(); 267 268 // no need to call postAdapt here, because markers 269 // are cleand during refinement callback 270 } 271 272 return refined; 273 } 274 275 276 // return Grid name 277 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > name()278 inline std::string ALU3dGrid< dim, dimworld, elType, Comm >::name () 279 { 280 if( elType == hexa ) 281 return "ALUCubeGrid"; 282 else 283 return "ALUSimplexGrid"; 284 } 285 286 287 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 288 alu_inline_tmp size(int level,int codim) const289 int ALU3dGrid< dim, dimworld, elType, Comm >::size ( int level, int codim ) const 290 { 291 // if we dont have this level return 0 292 if( (level > maxlevel_) || (level < 0) ) return 0; 293 294 alugrid_assert ( codim >= 0); 295 alugrid_assert ( codim < dimension+1 ); 296 297 alugrid_assert ( sizeCache_ ); 298 return sizeCache_->size(level,codim); 299 } 300 301 302 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > numBoundarySegments() const303 size_t ALU3dGrid< dim, dimworld, elType, Comm >::numBoundarySegments () const 304 { 305 return macroBoundarySegmentIndexSet().size(); 306 } 307 308 309 // --size 310 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 311 alu_inline_tmp size(int level,GeometryType type) const312 int ALU3dGrid< dim, dimworld, elType, Comm >::size ( int level, GeometryType type ) const 313 { 314 if(elType == tetra && !type.isSimplex()) return 0; 315 if(elType == hexa && !type.isCube ()) return 0; 316 return size( level, dimension - type.dim() ); 317 } 318 319 320 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 321 alu_inline_tmp size(int codim) const322 int ALU3dGrid< dim, dimworld, elType, Comm >::size ( int codim ) const 323 { 324 alugrid_assert ( codim >= 0 ); 325 alugrid_assert ( codim <= dimension ); 326 327 alugrid_assert ( sizeCache_ ); 328 return sizeCache_->size(codim); 329 } 330 331 332 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 333 alu_inline_tmp size(GeometryType type) const334 int ALU3dGrid< dim, dimworld, elType, Comm >::size ( GeometryType type ) const 335 { 336 if(elType == tetra && !type.isSimplex()) return 0; 337 if(elType == hexa && !type.isCube ()) return 0; 338 return size( dimension - type.dim() ); 339 } 340 341 342 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 343 alu_inline_tmp ghostSize(int codim) const344 int ALU3dGrid< dim, dimworld, elType, Comm >::ghostSize ( int codim ) const 345 { 346 return ( ghostCellsEnabled() && codim == 0 ) ? 1 : 0 ; 347 } 348 349 350 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 351 alu_inline_tmp ghostSize(int level,int codim) const352 int ALU3dGrid< dim, dimworld, elType, Comm >::ghostSize ( int level, int codim ) const 353 { 354 return ghostSize( codim ); 355 } 356 357 358 // calc all necessary things that might have changed 359 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 360 alu_inline_tmp updateStatus()361 void ALU3dGrid< dim, dimworld, elType, Comm >::updateStatus() 362 { 363 calcMaxLevel(); 364 calcExtras(); 365 } 366 367 368 // --calcExtras 369 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 370 alu_inline_tmp calcExtras()371 void ALU3dGrid< dim, dimworld, elType, Comm >::calcExtras () 372 { 373 // make sure maxLevel is the same on all processes ???? 374 //alugrid_assert ( maxlevel_ == comm().max( maxlevel_ )); 375 376 sizeCache_.reset( new SizeCacheType (*this) ); 377 378 // unset up2date before recalculating the index sets, 379 // because they will use this feature 380 leafVertexList_.unsetUp2Date(); 381 382 vertexList_.resize( maxlevel_+1 ); 383 levelEdgeList_.resize( maxlevel_+1 ); 384 385 for(int i=0; i<=maxlevel_; ++i) 386 { 387 vertexList_[i].unsetUp2Date(); 388 levelEdgeList_[i].unsetUp2Date(); 389 } 390 391 { 392 //here dimension has to be 3, as this is used ALU internally 393 // was for( int i = 0; i < dimension; ++i ) 394 for( int i = 0; i < 3; ++i ) 395 { 396 ghostLeafList_[i].unsetUp2Date(); 397 ghostLevelList_[i].resize( maxlevel_+1 ); 398 for(int l=0; l<=maxlevel_; ++l) 399 ghostLevelList_[i][l].unsetUp2Date(); 400 } 401 } 402 403 levelIndexVec_.resize( maxlevel_ + 1 ); 404 405 // update all index set that are already in use 406 for(size_t i=0; i<levelIndexVec_.size(); ++i) 407 { 408 if(levelIndexVec_[i]) 409 { 410 levelIndexVec_[i]->calcNewIndex( this->template lbegin<0>( i ), 411 this->template lend<0>( i ) ); 412 } 413 } 414 415 if(leafIndexSet_) 416 { 417 leafIndexSet_->calcNewIndex( this->template leafbegin<0>(), this->template leafend<0>() ); 418 } 419 420 // build global ID set new (to be revised) 421 if( globalIdSet_ ) globalIdSet_->updateIdSet(); 422 423 coarsenMarked_ = 0; 424 refineMarked_ = 0; 425 } 426 427 428 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 429 alu_inline_tmp 430 const typename ALU3dGrid< dim, dimworld, elType, Comm >::Traits::LeafIndexSet & leafIndexSet() const431 ALU3dGrid< dim, dimworld, elType, Comm >::leafIndexSet () const 432 { 433 if(!leafIndexSet_) 434 { 435 leafIndexSet_.reset( new LeafIndexSetImp ( *this, 436 this->template leafbegin<0>(), 437 this->template leafend<0>() ) ); 438 } 439 return *leafIndexSet_; 440 } 441 442 //! get level index set of the grid 443 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 444 alu_inline_tmp 445 const typename ALU3dGrid< dim, dimworld, elType, Comm >::Traits::LevelIndexSet & levelIndexSet(int level) const446 ALU3dGrid< dim, dimworld, elType, Comm >::levelIndexSet (int level) const 447 { 448 assert( (level >= 0) && (level < int( levelIndexVec_.size() )) ); 449 if( ! levelIndexVec_[ level ] ) 450 { 451 levelIndexVec_[ level ] = createLevelIndexSet( level ); 452 } 453 return (*levelIndexVec_[ level ]); 454 } 455 456 /** \brief return instance of level index set 457 \note if index set for this level has not been created then this 458 instance will be deleted once the shared_ptr goes out of scope. 459 */ 460 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 461 alu_inline_tmp 462 std::shared_ptr< typename ALU3dGrid< dim, dimworld, elType, Comm >::LevelIndexSetImp > accessLevelIndexSet(int level) const463 ALU3dGrid< dim, dimworld, elType, Comm >::accessLevelIndexSet ( int level ) const 464 { 465 assert( (level >= 0) && (level < int( levelIndexVec_.size() )) ); 466 if( levelIndexVec_[ level ] ) 467 { 468 return levelIndexVec_[ level ]; 469 } 470 else 471 { 472 return createLevelIndexSet( level ); 473 } 474 } 475 476 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 477 alu_inline_tmp 478 std::shared_ptr< typename ALU3dGrid< dim, dimworld, elType, Comm >::LevelIndexSetImp > createLevelIndexSet(int level) const479 ALU3dGrid< dim, dimworld, elType, Comm >::createLevelIndexSet ( int level ) const 480 { 481 return std::make_shared< LevelIndexSetImp > ( *this, lbegin< 0 >( level ), lend< 0 >( level ), level ); 482 } 483 484 485 // global refine 486 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 487 alu_inline_tmp globalRefine(int refCount)488 void ALU3dGrid< dim, dimworld, elType, Comm >::globalRefine ( int refCount ) 489 { 490 int marker = refCount > 0 ? 1: -1 ; 491 for( int count = std::abs(refCount); count > 0; --count ) 492 { 493 const auto end = leafend< 0, Interior_Partition >(); 494 for( auto it = leafbegin< 0, Interior_Partition >(); it != end; ++it ) 495 { 496 mark( marker, *it ); 497 } 498 preAdapt(); 499 adapt(); 500 postAdapt(); 501 } 502 } 503 504 // preprocess grid 505 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 506 alu_inline_tmp preAdapt()507 bool ALU3dGrid< dim, dimworld, elType, Comm >::preAdapt() 508 { 509 return (coarsenMarked_ > 0); 510 } 511 512 513 // adapt grid 514 template< int dim, int dimworld, ALU3dGridElementType elType, class Comm > 515 alu_inline_tmp adapt()516 bool ALU3dGrid< dim, dimworld, elType, Comm >::adapt () 517 { 518 bool ref = false; 519 520 if( lockPostAdapt_ == true ) 521 { 522 DUNE_THROW(InvalidStateException,"Make sure that postAdapt is called after adapt was called and returned true!"); 523 } 524 525 bool mightCoarse = preAdapt(); 526 // if prallel run, then adapt also global id set 527 if(globalIdSet_) 528 { 529 //std::cout << "Start adapt with globalIdSet prolong \n"; 530 int defaultChunk = newElementsChunk_; 531 int actChunk = refineEstimate_ * refineMarked_; 532 533 // guess how many new elements we get 534 int newElements = std::max( actChunk , defaultChunk ); 535 536 globalIdSet_->setChunkSize( newElements ); 537 ref = myGrid().duneAdapt(*globalIdSet_); // adapt grid 538 } 539 else 540 { 541 ref = myGrid().adaptWithoutLoadBalancing(); 542 } 543 544 // in parallel this is different 545 if( this->comm().size() == 1 ) 546 { 547 ref = ref && refineMarked_ > 0; 548 } 549 550 if(ref || mightCoarse) 551 { 552 // calcs maxlevel and other extras 553 updateStatus(); 554 555 // notify that postAdapt must be called 556 lockPostAdapt_ = true; 557 } 558 return ref; 559 } 560 561 #undef alu_inline_tmp 562 } // end namespace Dune 563 #endif 564