dune-fem  2.4.1-rc
common/adaptmanager.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_ADAPTMANAGER_HH
2 #define DUNE_FEM_ADAPTMANAGER_HH
3 
4 //- system includes
5 #include <string>
6 
7 //- local includes
8 #include <dune/common/timer.hh>
11 
17 
19 #include <dune/fem/io/parameter.hh>
22 
23 
24 namespace Dune
25 {
26 
27  namespace Fem
28  {
29 
59  {
60  public:
63 
66 
70  virtual void adapt ()
71  {
72  //std::cout << "called AdaptationManagerInterface::adapt()" << std::endl;
73  if(am_) am_->adapt();
74  else
75  {
76  std::cerr << "WARNING: AdaptationManagerInterface::adapt: no adaptation manager assigned! \n";
77  }
78  }
79 
83  virtual bool adaptive () const
84  {
85  return (am_) ? (am_->adaptive()) : false;
86  }
87 
91  virtual const char * methodName() const
92  {
93  return (am_) ? (am_->methodName()) : "unknown method";
94  }
95 
100  {
102  am_ = const_cast<AdaptationManagerInterface *> (&am);
103  return (*this);
104  }
105 
107  virtual bool loadBalance ()
108  {
109  return (am_) ? (am_->loadBalance()) : false;
110  }
111 
113  virtual int balanceCounter () const
114  {
115  return (am_) ? (am_->balanceCounter()) : 0;
116  }
117 
119  virtual double adaptationTime () const
120  {
121  return 0.0;
122  }
123 
124  private:
127  };
128 
130  template <class GridType>
132  {
133  public:
135  enum AdaptationMethodType { none = 0,
136  generic = 1,
137  callback = 2
138  };
139 
140  public:
148  AdaptationMethod ( const GridType &grid, const ParameterReader &parameter = Parameter::container() )
149  : adaptationMethod_(generic)
150  {
151  const bool output = ( Parameter :: verbose() );
152  int am = 1;
153  const std::string methodNames [] = { "none", "generic", "callback" };
154  am = parameter.getEnum("fem.adaptation.method", methodNames, am);
155  init(am,output);
156  }
157  private:
158  void init(int am,const bool output)
159  {
160 
161  // chose adaptation method
162  if(am == 2) adaptationMethod_ = callback;
163  else if(am == 1) adaptationMethod_ = generic;
164  else adaptationMethod_ = none;
165 
166  // for structred grid adaptation is disabled
168  {
169  adaptationMethod_ = none;
170  if( output )
171  {
172  std::cerr << "WARNING: AdaptationMethod: adaptation disabled for structured grid! \n";
173  }
174  }
175 
176  if( output )
177  {
178  std::cout << "Created AdaptationMethod: adaptation method = " << methodName() << std::endl;
179  }
180  }
181  public:
183  virtual ~AdaptationMethod () {}
184 
186  virtual const char * methodName() const
187  {
188  switch (adaptationMethod_) {
189  case generic: return "generic";
190  case callback: return "callback";
191  case none: return "no adaptation";
192  default: return "unknown method";
193  }
194  }
195 
197  virtual bool adaptive () const { return adaptationMethod_ != none; }
198 
199  protected:
202  };
203 
209  template <class GridType, class RestProlOperatorImp >
212  public ObjPointerStorage
213  {
216 
217  template <class AdaptManager, class GridImp, bool isGoodGrid>
218  struct CallAdaptationMethod
219  {
220  template <class DofManagerImp, class RPOpImp>
221  static void adapt(const AdaptManager& am, GridImp & grid,
222  DofManagerImp& dm , RPOpImp& rpop,
223  AdaptationMethodType adaptMethod)
224  {
225  // use generic adapt method
226  if( adaptMethod == BaseType :: generic )
227  {
228  am.template genericAdapt<All_Partition> ();
229  return ;
230  }
231 
232  // use grid call back adapt method
233  if( adaptMethod == BaseType :: callback )
234  {
235  // combine dof manager and restrict prolong operator
237 
238  // create new handle
239  RPType restrictProlongHandle ( dm , rpop );
240 
241  // reserve memory
242  restrictProlongHandle.initialize();
243 
244  // call grid adaptation
245  grid.adapt( restrictProlongHandle );
246 
247  // do compress (if not already called)
248  restrictProlongHandle.finalize();
249  return ;
250  }
251  }
252  };
253 
254  template <class AdaptManager, class GridImp>
255  struct CallAdaptationMethod<AdaptManager,GridImp,false>
256  {
257  template <class DofManagerImp, class RPOpImp>
258  static void adapt(const AdaptManager& am, GridImp & grid,
259  DofManagerImp& dm , RPOpImp& rpop,
260  AdaptationMethodType adaptMethod)
261  {
262  // use generic adapt method
263  if(adaptMethod != BaseType :: none )
264  {
265  // use partition type All_Partition,
266  // since we also need to iterate on ghosts
267  // for wasChanged information gathering
268  am.template genericAdapt<All_Partition> ();
269  return ;
270  }
271  }
272  };
273 
276 
279 
280  public:
281  typedef typename GridType :: Traits :: LocalIdSet LocalIdSet;
282 
292  AdaptationManagerBase ( GridType &grid, RestProlOperatorImp &rpOp, const ParameterReader &parameter = Parameter::container() )
293  : BaseType( grid, parameter ),
294  grid_( grid ),
295  dm_( DofManagerType::instance( grid_ ) ),
296  rpOp_( rpOp ),
297  adaptTime_( 0.0 ),
298  wasChanged_( false )
299  {}
300 
303 
307  RestProlOperatorImp & getRestProlOp ()
308  {
309  return rpOp_;
310  }
311 
319  virtual void adapt ()
320  {
321  // make sure this is only called in single thread mode
323 
324  // get stopwatch
325  Dune::Timer timer;
326 
327  const bool supportsCallback = Capabilities :: supportsCallbackAdaptation< GridType > :: v;
328  CallAdaptationMethod< ThisType, GridType, supportsCallback >
329  :: adapt(*this,grid_,dm_,rpOp_,this->adaptationMethod_);
330 
331  // take time
332  adaptTime_ = timer.elapsed();
333  }
334 
336  virtual bool loadBalance ()
337  {
338  return false;
339  }
340 
342  virtual int balanceCounter () const
343  {
344  return 0;
345  }
346 
348  virtual double adaptationTime() const
349  {
350  return adaptTime_;
351  }
352 
353  protected:
354  static DofManagerType& getDofManager(const GridType& grid)
355  {
356  return DofManagerType :: instance( grid );
357  }
358 
359  private:
365  template <PartitionIteratorType pitype>
366  void genericAdapt () const
367  {
368  // call pre-adapt, returns true if at least
369  // one element is marked for coarsening
370  bool restr = grid_.preAdapt();
371 
372  // get macro grid view
373  typedef typename GridType::template Partition< All_Partition > :: LevelGridView MacroGridView ;
374  typedef typename MacroGridView :: template Codim<0>::
375  template Partition<pitype> :: Iterator MacroIterator;
376 
377  // reset flag
378  wasChanged_ = false ;
379 
380  if(restr)
381  {
382  // get macro grid view
383  MacroGridView macroView = grid_.levelGridView( 0 );
384 
385  // make a hierarchical to insert all elements
386  // that are father of elements that might be coarsened
387 
388  {
389  // get macro iterator
390  MacroIterator endit = macroView.template end<0,pitype> ();
391  for(MacroIterator it = macroView.template begin<0,pitype>();
392  it != endit; ++it )
393  {
394  hierarchicRestrict( *it , dm_.indexSetRestrictProlongNoResize() );
395  }
396  }
397 
398  // if at least one element was found for restriction
399  if( wasChanged_ )
400  {
401  // now resize memory
402  dm_.resizeForRestrict();
403 
404  // now project all data to fathers
405  {
406  // get macro iterator
407  MacroIterator endit = macroView.template end<0,pitype> ();
408  for(MacroIterator it = macroView.template begin<0,pitype>();
409  it != endit; ++it )
410  {
411  hierarchicRestrict( *it , rpOp_ );
412  }
413  }
414  }
415  }
416 
417  // adapt grid due to preset markers
418  // returns true if at least one element was refined
419  const bool refined = grid_.adapt();
420 
421  // if coarsening or refinement was done
422  // adjust sizes
423  if( refined || restr )
424  {
425  // resizes the index sets (insert all new indices)
426  // and resizes the memory
427  dm_.resize();
428  }
429 
430  // in case elements were created do prolongation
431  if( refined )
432  {
433  // get macro grid view
434  MacroGridView macroView = grid_.levelGridView( 0 );
435 
436  // make run through grid to project data
437  MacroIterator endit = macroView.template end<0,pitype> ();
438  for(MacroIterator it = macroView.template begin<0,pitype>();
439  it != endit; ++it )
440  {
441  hierarchicProlong( *it , rpOp_ );
442  }
443  }
444 
445  // notifyGlobalChange make wasChanged equal on all cores
446  if( dm_.notifyGlobalChange( wasChanged_ ) )
447  {
448  // compress index sets and data
449  // this will increase the sequence counter
450  dm_.compress();
451  }
452 
453  // do cleanup
454  grid_.postAdapt();
455  }
456 
457  private:
459  template <class EntityType, class RestrictOperatorType >
460  bool hierarchicRestrict ( const EntityType& entity, RestrictOperatorType & restop ) const
461  {
462  if( ! entity.isLeaf() )
463  {
464  // true means we are going to restrict data
465  bool doRestrict = true;
466 
467  // check partition type
468  const bool isGhost = entity.partitionType() == GhostEntity ;
469 
470  // if the children have children then we have to go deeper
471  const int childLevel = entity.level() + 1;
472  typedef typename EntityType::HierarchicIterator HierarchicIterator;
473 
474  // check all children first
475  {
476  const HierarchicIterator endit = entity.hend( childLevel );
477  for(HierarchicIterator it = entity.hbegin( childLevel ); it != endit; ++it)
478  {
479  doRestrict &= hierarchicRestrict( *it , restop );
480  }
481  }
482 
483  // if doRestrict is still true, restrict data
484  if(doRestrict)
485  {
486  // we did at least one restriction
487  wasChanged_ = true;
488 
489  // do not restrict the solution on ghosts, this will
490  // fail, but we still need the wasChanged info, so simply
491  // calling hierarchicRestrict on interior won't work either
492  if( ! isGhost )
493  {
494  // true for first child, otherwise false
495  bool initialize = true;
496  const HierarchicIterator endit = entity.hend( childLevel );
497  for(HierarchicIterator it = entity.hbegin( childLevel ); it != endit; ++it)
498  {
499  // restrict solution
500  restop.restrictLocal( entity, *it , initialize);
501  // reset initialize flag
502  initialize = false;
503  }
504  }
505  }
506  }
507 
508  // if all children return mightBeCoarsened,
509  // then doRestrict on father remains true
510  return entity.mightVanish();
511  }
512 
513  template <class EntityType, class ProlongOperatorType >
514  void hierarchicProlong ( const EntityType &entity, ProlongOperatorType & prolop ) const
515  {
516  typedef typename EntityType::HierarchicIterator HierarchicIterator;
517 
518  // NOTE: initialize not working here
519  // because we call hierarchically
520 
521  // first call on this element
522  bool initialize = true;
523 
524  // check partition type
525  const bool isGhost = entity.partitionType() == GhostEntity ;
526 
527  const int maxLevel = grid_.maxLevel();
528  const HierarchicIterator endit = entity.hend( maxLevel );
529  for( HierarchicIterator it = entity.hbegin( maxLevel ); it != endit; ++it )
530  {
531  // should only get here on non-leaf entities
532  assert( !entity.isLeaf() );
533 
534  const EntityType & son = *it;
535  if( son.isNew() )
536  {
537  // the grid was obviously changed if we get here
538  wasChanged_ = true ;
539 
540  // do not prolong the solution on ghosts, this will
541  // fail, but we still need the wasChanged info, so simply
542  // calling hierarchicRestrict on interior won't work either
543  if( ! isGhost )
544  {
545  EntityType vati = make_entity( son.father() );
546  prolop.prolongLocal( vati , son , initialize );
547  initialize = false;
548  }
549  }
550  }
551  }
552 
553  protected:
555  GridType &grid_;
556 
558  DofManagerType &dm_;
559 
561  RestProlOperatorImp &rpOp_;
562 
564  double adaptTime_;
565 
567  mutable bool wasChanged_;
568  };
569 
571  template <class KeyType, class ObjectType>
573  {
574  static ObjectType* createObject(const KeyType& key)
575  {
576  return new ObjectType(0);
577  }
578  static void deleteObject(ObjectType* obj)
579  {
580  delete obj;
581  }
582  };
583 
589  template <class GridType, class RestProlOperatorImp>
593  {
594  // type of key
595  typedef const GridType* KeyType;
596  // object type
597  typedef size_t ObjectType;
598  // type of factory
600 
601  // type of singleton list
603 
606 
607  mutable CommunicationManagerList commList_;
608  double balanceTime_ ;
609 
610  // reference counter to ensure only one instance per grid exists
611  ObjectType& referenceCounter_;
612 
613  // do not copy
615 
616  public:
626  AdaptationManager ( GridType &grid, RestProlOperatorImp &rpOp, int balanceCounter, const ParameterReader &parameter = Parameter::container() )
627  : BaseType(grid,rpOp, parameter)
628  , Base2Type( grid, rpOp, balanceCounter, parameter )
629  , commList_(rpOp)
630  , balanceTime_( 0.0 )
631  , referenceCounter_( ProviderType :: getObject( &grid ) )
632  {
633  if( ++referenceCounter_ > 1 )
634  DUNE_THROW(InvalidStateException,"Only one instance of AdaptationManager allowed per grid instance");
635  }
636 
637  AdaptationManager ( GridType &grid, RestProlOperatorImp &rpOp, const ParameterReader &parameter = Parameter::container() )
638  : BaseType(grid,rpOp, parameter)
639  , Base2Type( grid, rpOp, parameter )
640  , commList_(rpOp)
641  , balanceTime_( 0.0 )
642  , referenceCounter_( ProviderType :: getObject( &grid ) )
643  {
644  if( ++referenceCounter_ > 1 )
645  DUNE_THROW(InvalidStateException,"Only one instance of AdaptationManager allowed per grid instance");
646  }
647 
650  {
651  -- referenceCounter_;
652  ProviderType :: removeObject( referenceCounter_ );
653  }
654 
656  virtual bool loadBalance ()
657  {
658  // call load balance
659  return Base2Type :: loadBalance();
660  }
661 
663  virtual int balanceCounter () const
664  {
665  return Base2Type :: balanceCounter ();
666  }
667 
669  virtual double loadBalanceTime() const
670  {
671  return balanceTime_;
672  }
673 
675  virtual void adapt ()
676  {
677  // adapt grid
678  BaseType :: adapt ();
679 
680  // if adaptation is enabled
681  if( this->adaptive() )
682  {
683  // get stopwatch
684  Dune::Timer timer;
685 
686  // do load balancing
687  loadBalance ();
688 
689  // exchange all modified data
690  // this also rebuilds the dependecy cache of the
691  // cached communication manager if used
692  commList_.exchange();
693 
694  // get time
695  this->balanceTime_ = timer.elapsed();
696  }
697  }
698  };
699 
706  {
712  template <class GridType>
713  static void apply(GridType& grid, const int step)
714  {
715  typedef DofManager< GridType > DofManagerType;
716  DofManagerType& dm = DofManagerType :: instance(grid);
717  grid.globalRefine(step);
718  grid.loadBalance();
719  dm.resize();
720  dm.compress();
721  }
722  };
729  struct LocalRefine
730  {
735  template <class GridType>
736  static void apply(GridType& grid)
737  {
738  typedef DofManager< GridType > DofManagerType;
739  DofManagerType& dm = DofManagerType :: instance(grid);
740  grid.preAdapt();
741  grid.adapt();
742  grid.postAdapt();
743  grid.loadBalance();
744  dm.resize();
745  dm.compress();
746  }
747  };
748 
751  } // namespace Fem
752 
753 } // namespace Dune
754 
755 #endif // #ifndef DUNE_FEM_ADAPTMANAGER_HH
void exchange() const
Definition: communicationmanager.hh:382
virtual int balanceCounter() const
return number of cycles since last application of load balance
Definition: common/adaptmanager.hh:113
AdaptationManagerInterface & operator=(const AdaptationManagerInterface &am)
Assignment operator, pointer to adaptation manager is stored.
Definition: common/adaptmanager.hh:99
GridType & grid_
corresponding grid
Definition: common/adaptmanager.hh:555
double adaptTime_
time that adaptation took
Definition: common/adaptmanager.hh:564
virtual double loadBalanceTime() const
time that last load balance cycle took
Definition: common/adaptmanager.hh:669
virtual void adapt()
on call of this method the internal adaptation operator is called.
Definition: common/adaptmanager.hh:70
AdaptationMethodType
type of adaptation method
Definition: common/adaptmanager.hh:135
Definition: misc/capabilities.hh:152
Proxy class to DependencyCache which is singleton per space.
Definition: communicationmanager.hh:294
virtual const char * methodName() const
returns name of adaptation method
Definition: common/adaptmanager.hh:91
Definition: misc/capabilities.hh:109
virtual double adaptationTime() const
time that last adaptation cycle took
Definition: common/adaptmanager.hh:348
A class with one static method apply to globally refine a grid. All index sets are adapted to the new...
Definition: common/adaptmanager.hh:705
virtual void adapt()
according to adaption method parameter the adaption procedure is done, 0 == no adaptation 1 == generi...
Definition: common/adaptmanager.hh:319
virtual bool loadBalance()
call load balance, returns true if grid was changed
Definition: common/adaptmanager.hh:107
DofManagerType & dm_
DofManager corresponding to grid.
Definition: common/adaptmanager.hh:558
Singleton list for key/object pairs.
Definition: singletonlist.hh:49
AdaptationManagerBase(GridType &grid, RestProlOperatorImp &rpOp, const ParameterReader &parameter=Parameter::container())
constructor of AdaptationManagerBase The following optional parameter can be used 0 == none...
Definition: common/adaptmanager.hh:292
virtual ~AdaptationManagerInterface()
destructor
Definition: common/adaptmanager.hh:65
Definition: datacollector.hh:45
AdaptationManagerInterface class.
Definition: common/adaptmanager.hh:58
virtual const char * methodName() const
returns name of adaptation method
Definition: common/adaptmanager.hh:186
AdaptationManagerInterface()
default constructor
Definition: common/adaptmanager.hh:62
Dune::EntityPointer< Grid, Implementation >::Entity make_entity(const Dune::EntityPointer< Grid, Implementation > &entityPointer)
Definition: compatibility.hh:23
virtual ~AdaptationManagerBase()
destructor
Definition: common/adaptmanager.hh:302
Definition: objpointer.hh:37
virtual double adaptationTime() const
time that last adaptation cycle took
Definition: common/adaptmanager.hh:119
AdaptationManager(GridType &grid, RestProlOperatorImp &rpOp, const ParameterReader &parameter=Parameter::container())
Definition: common/adaptmanager.hh:637
virtual bool loadBalance()
call load balance, returns true if grid was changed
Definition: common/adaptmanager.hh:656
virtual bool loadBalance()
default load balancing method which does nothing
Definition: common/adaptmanager.hh:336
RestProlOperatorImp & getRestProlOp()
Definition: common/adaptmanager.hh:307
static void apply(GridType &grid, const int step)
apply global refinement and also adjust index sets and managed dof storage. However, user data stored before is lost.
Definition: common/adaptmanager.hh:713
Definition: coordinate.hh:4
This class manages the adaptation process. If the method adapt is called, then the grid is adapted an...
Definition: common/adaptmanager.hh:210
AdaptationManager(GridType &grid, RestProlOperatorImp &rpOp, int balanceCounter, const ParameterReader &parameter=Parameter::container())
constructor of AdaptationManager The following optional parameters from the Dune::Parameter class are...
Definition: common/adaptmanager.hh:626
AdaptationMethod is a simple adaptation method reader class.
Definition: common/adaptmanager.hh:131
Interface class for load balancing.
Definition: loadbalancer.hh:36
static ParameterContainer & container()
Definition: io/parameter.hh:190
virtual bool adaptive() const
returns true if adaptation manager as adaptation method different to NONE
Definition: common/adaptmanager.hh:83
GridType::Traits::LocalIdSet LocalIdSet
Definition: common/adaptmanager.hh:281
static void apply(GridType &grid)
apply local refinement and also adjust index sets and managed dof storage. However, user data stored before is lost.
Definition: common/adaptmanager.hh:736
virtual int balanceCounter() const
default load balancing counter is zero
Definition: common/adaptmanager.hh:342
interfaces and wrappers needed for the callback adaptation provided by AlbertaGrid and ALUGrid ...
A class with one static method apply for invoking the local adaptation procedure on a given grid inst...
Definition: common/adaptmanager.hh:729
RestProlOperatorImp & rpOp_
Restriction and Prolongation Operator.
Definition: common/adaptmanager.hh:561
static bool verbose()
obtain the cached value for fem.verbose
Definition: io/parameter.hh:444
static DofManagerType & getDofManager(const GridType &grid)
Definition: common/adaptmanager.hh:354
AdaptationMethod(const GridType &grid, const ParameterReader &parameter=Parameter::container())
constructor of AdaptationMethod The following optional parameters are used 0 == none, 1 == generic, 2 == call back (only AlbertaGrid and ALUGrid)AdaptationMethod: 1 # default value
Definition: common/adaptmanager.hh:148
This class manages the adaptation process. If the method adapt is called, then the grid is adapted an...
Definition: loadbalancer.hh:69
bool wasChanged_
flag for restriction
Definition: common/adaptmanager.hh:567
AdaptationMethodType adaptationMethod_
method identifier
Definition: common/adaptmanager.hh:201
Definition: adaptcallbackhandle.hh:23
static ObjectType * createObject(const KeyType &key)
Definition: common/adaptmanager.hh:574
This class manages the adaptation process including a load balancing after the adaptation step...
Definition: common/adaptmanager.hh:590
static bool singleThreadMode()
returns true if program is operating on one thread currently
Definition: threadmanager.hh:217
virtual ~AdaptationMethod()
virtual destructor
Definition: common/adaptmanager.hh:183
virtual bool adaptive() const
returns true if adaptation manager as adaptation method different to NONE
Definition: common/adaptmanager.hh:197
virtual int balanceCounter() const
return number of cycles since last application of load balance
Definition: common/adaptmanager.hh:663
virtual void adapt()
on call of this method the internal adaptation operator is called.
Definition: common/adaptmanager.hh:675
~AdaptationManager()
destructor decreasing reference counter
Definition: common/adaptmanager.hh:649
factory class to create adaptation manager reference counter
Definition: common/adaptmanager.hh:572
static void deleteObject(ObjectType *obj)
Definition: common/adaptmanager.hh:578