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 &macroTriangFilename,
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