DUNE-FEM (unstable)

timeprovider.hh
1 #ifndef DUNE_FEM_TIMEPROVIDER_HH
2 #define DUNE_FEM_TIMEPROVIDER_HH
3 
4 #include <cassert>
5 #include <limits>
6 #include <tuple>
7 
8 #include <dune/fem/io/file/persistencemanager.hh>
9 #include <dune/fem/io/parameter.hh>
10 #include <dune/fem/space/common/dofmanager.hh>
11 
12 #include <dune/fem/misc/mpimanager.hh>
13 
14 namespace Dune
15 {
16 
17  namespace Fem
18  {
19 
36  {
37  typedef TimeProviderBase ThisType;
38 
39  public:
40  inline TimeProviderBase ( const ParameterReader &parameter = Parameter::container() )
41  : time_( parameter.getValue( "fem.timeprovider.starttime",
42  static_cast<double>(0.0) ) ),
43  timeStep_( 0 ),
44  dt_( 0.0 ),
45  invdt_( HUGE_VAL ),
46  valid_( false ),
47  dtEstimateValid_( false ),
48  parameter_( parameter )
49  {
50  initTimeStepEstimate();
51  }
52 
53  inline explicit TimeProviderBase ( const double startTime, const ParameterReader &parameter = Parameter::container() )
54  : time_( startTime ),
55  timeStep_( 0 ),
56  dt_( 0.0 ),
57  invdt_( HUGE_VAL ),
58  valid_( false ),
59  dtEstimateValid_( false ),
60  parameter_( parameter )
61  {
62  initTimeStepEstimate();
63  }
64 
65  inline virtual ~TimeProviderBase()
66  {}
67 
68  void backup() const
69  {
70  std::tuple<const double&,const int&,const double&,const bool&,const double&>
71  values(time_,timeStep_,dt_,valid_,dtEstimate_);
72  PersistenceManager::backupValue("timeprovider",values);
73  }
74 
75  void restore()
76  {
77  std::tuple<double&,int&,double&,bool&,double&>
78  values(time_,timeStep_,dt_,valid_,dtEstimate_);
79  PersistenceManager::restoreValue("timeprovider",values);
80  dtEstimateValid_ = true;
81  invdt_ = 1.0 / dt_;
82  }
83 
84 
85  TimeProviderBase ( const ThisType & ) = delete;
86 
87  ThisType &operator= ( const ThisType & ) = delete;
88 
89 
94  inline double time () const
95  {
96  return time_;
97  }
98 
103  inline int timeStep () const
104  {
105  assert( timeStepValid() );
106  return timeStep_;
107  }
108 
113  inline double deltaT () const
114  {
115  assert( timeStepValid() );
116  return dt_;
117  }
118 
123  inline double inverseDeltaT () const
124  {
125  assert( timeStepValid() );
126  return invdt_;
127  }
128 
133  inline double timeStepEstimate () const
134  {
135  return dtEstimate_;
136  }
137 
142  inline void provideTimeStepEstimate ( const double dtEstimate )
143  {
144  dtEstimate_ = std::min( dtEstimate_, dtEstimate );
145  dtEstimateValid_ = true;
146  }
151  inline void provideTimeStepUpperBound ( const double upperBound )
152  {
153  dtUpperBound_ = std::min( dtUpperBound_, upperBound );
154  dtEstimateValid_ = true;
155  }
156 
158  inline void invalidateTimeStep ()
159  {
160  valid_ = false;
161  }
162 
164  inline bool timeStepValid () const
165  {
166  return valid_;
167  }
168 
169  protected:
170  double time_;
171  int timeStep_;
172  double dt_;
173  double invdt_;
174  bool valid_;
175  bool dtEstimateValid_;
176  double dtEstimate_;
177  double dtUpperBound_;
178  ParameterReader parameter_;
179 
180  void advance ()
181  {
182  if( timeStepValid() )
183  {
184  time_ += deltaT();
185  ++timeStep_;
186  }
187  }
188 
189  void initTimeStepEstimate ()
190  {
191  dtEstimate_ = std::numeric_limits< double >::max();
192  dtUpperBound_ = std::numeric_limits< double >::max();
193  dtEstimateValid_ = false;
194  }
195  };
196 
197 
215  template< class Communication = typename MPIManager::Communication >
216  class FixedStepTimeProvider
217  : public TimeProviderBase
218  {
219  typedef FixedStepTimeProvider< Communication > ThisType;
220  typedef TimeProviderBase BaseType;
221 
222  public:
223  typedef Communication CommunicationType;
224 
231  explicit FixedStepTimeProvider ( const double startTime, const double timeStepSize,
232  const CommunicationType &comm,
233  const ParameterReader &parameter = Parameter::container() )
234  : BaseType( startTime, parameter ), comm_( comm )
235  {
236  dt_ = timeStepSize;
237  initTimeStep();
238  }
239 
240  explicit FixedStepTimeProvider ( const double startTime, const double timeStepSize,
241  const ParameterReader &parameter = Parameter::container() )
242  : BaseType( startTime, parameter ), comm_( MPIManager::comm() )
243  {
244  dt_ = timeStepSize;
245  initTimeStep();
246  }
247 
255  explicit FixedStepTimeProvider ( const ParameterReader &parameter = Parameter::container() )
256  : BaseType( parameter.getValue< double>( "fem.timeprovider.starttime", 0.0 ), parameter ), comm_( MPIManager::comm() )
257  {
258  dt_ = parameter.getValidValue< double >("fem.timeprovider.fixedtimestep", [] ( double v ) { return v > 0.0;} );
259  initTimeStep();
260  }
261 
262  explicit FixedStepTimeProvider ( const CommunicationType &comm,
263  const ParameterReader &parameter = Parameter::container() )
264  : BaseType( parameter.getValue< double>( "fem.timeprovider.starttime", 0.0 ), parameter ), comm_( comm )
265  {
266  dt_ = parameter.getValidValue< double >("fem.timeprovider.fixedtimestep", [] ( double v ) { return v > 0.0;} );
267  initTimeStep();
268  }
269  virtual ~FixedStepTimeProvider () {}
270 
271  FixedStepTimeProvider ( const ThisType & ) = delete;
272  FixedStepTimeProvider ( ThisType && ) = delete;
273  ThisType &operator= ( const ThisType & ) = delete;
274  ThisType &operator= ( ThisType && ) = delete;
275 
277  void next ()
278  {
279  if( !timeStepValid() )
280  DUNE_THROW( InvalidStateException, "Invalid Time Step in FixedStepTimeProvider" );
281  advance();
282  initTimeStep();
283  }
284 
285  protected:
286  using BaseType::advance;
287  using BaseType::initTimeStepEstimate;
288  using BaseType::time_;
289  using BaseType::dt_;
290  using BaseType::valid_;
291 
292  inline void initTimeStep ()
293  {
294  valid_ = true;
295  initTimeStepEstimate();
296  }
297 
298  const CommunicationType &comm_;
299  };
300 
301 
402  template< class Communication = typename MPIManager::Communication >
404  : public TimeProviderBase
405  {
407  typedef TimeProviderBase BaseType;
408 
409  public:
411 
412  protected:
413 
414  using BaseType::parameter_;
415 
416  inline double getCflFactor() const
417  {
418  return parameter_.getValidValue( "fem.timeprovider.factor", static_cast<double>(1.0),
419  [] ( double val ) { return val > 0.0; } );
420  }
421 
422  inline int getUpdateStep () const
423  {
424  return parameter_.getValidValue( "fem.timeprovider.updatestep", static_cast<int>(1),
425  [] ( int step ) { return step > 0; } );
426  }
427 
428  public:
433  explicit TimeProvider ( const ParameterReader &parameter = Parameter::container() )
434  : BaseType( parameter ),
435  comm_( MPIManager::comm() ),
436  cfl_( getCflFactor() ),
437  updateStep_( getUpdateStep() ),
438  counter_( updateStep_ )
439  {}
440 
441  explicit TimeProvider ( const CommunicationType &comm, const ParameterReader &parameter = Parameter::container() )
442  : BaseType( parameter ),
443  comm_( comm ),
444  cfl_( getCflFactor() ),
445  updateStep_( getUpdateStep() ),
446  counter_( updateStep_ )
447  {}
448 
454  explicit TimeProvider ( const double startTime,
455  const CommunicationType &comm = MPIManager::comm() )
456  : BaseType( startTime ),
457  comm_( comm ),
458  cfl_( getCflFactor() ),
459  updateStep_( getUpdateStep() ),
460  counter_( updateStep_ )
461  {}
462 
469  TimeProvider ( const double startTime,
470  const double cfl,
471  const CommunicationType &comm = MPIManager::comm() )
472  : BaseType( startTime ),
473  comm_( comm ),
474  cfl_( cfl ),
475  updateStep_( 1 ),
476  counter_( updateStep_ )
477  {}
478 
479  virtual ~TimeProvider()
480  {}
481 
482  TimeProvider ( const ThisType & ) = delete;
483 
484  ThisType &operator= ( const ThisType & ) = delete;
485 
488  inline void init ()
489  {
490  initTimeStep( dtEstimate_ );
491  }
492 
498  inline void init ( const double timeStep )
499  {
500  initTimeStep( timeStep );
501  }
502 
508  inline void next ()
509  {
510  assert( this->dtEstimateValid_ );
511  advance();
512  initTimeStep( dtEstimate_ );
513  }
514 
523  inline void next ( const double timeStep )
524  {
525  advance();
526  initTimeStep(timeStep);
527  }
528 
532  inline double factor () const
533  {
534  return cfl_;
535  }
536 
537  protected:
538  using BaseType::advance;
539  using BaseType::initTimeStepEstimate;
540 
541  void initTimeStep ( const double dtEstimate )
542  {
543  // increase counter
544  ++counter_ ;
545 
546  if( counter_ >= updateStep_ )
547  {
548  // set timestep estimate
549  dt_ = std::min(cfl_ * dtEstimate,dtUpperBound_);
550  dt_ = comm_.min( dt_ );
551  invdt_ = 1.0 / dt_;
552  valid_ = (dt_ > 0.0);
553  // reset counter
554  counter_ = 0;
555  }
556 
557  initTimeStepEstimate();
558  }
559 
560  public:
566  inline void restore ( const double time, const int timeStep )
567  {
568  time_ = time;
569  timeStep_ = timeStep;
570  }
571 
572  inline virtual void backup () const
573  {
575  }
576 
577  inline virtual void restore ()
578  {
580  const_cast< double & >( cfl_ ) = getCflFactor();
581  }
582 
583  protected:
584  using BaseType::dt_;
585  using BaseType::invdt_;
586  using BaseType::dtEstimate_;
587  using BaseType::dtUpperBound_;
588  using BaseType::valid_;
589  using BaseType::timeStep_;
590 
591  const CommunicationType& comm_;
592  const double cfl_;
593  const int updateStep_;
594  int counter_;
595  };
596 
597 
598 
606  template< class Grid >
608  : public TimeProvider< typename Grid::Traits::Communication >
609  {
612 
613  // type of DofManager for sequence number
615 
616  public:
617  typedef typename Grid::Traits::Communication CommunicationType;
618 
619  explicit GridTimeProvider ( const Grid &grid )
620  : BaseType( grid.comm() ),
621  dm_( DofManagerType ::instance( grid ) ),
622  sequence_( -1 )
623  {}
624 
625  GridTimeProvider ( const double startTime,
626  const Grid &grid )
627  : BaseType( startTime, grid.comm() ),
628  dm_( DofManagerType ::instance( grid ) ),
629  sequence_( -1 )
630  {}
631 
632  GridTimeProvider ( const double startTime,
633  const double cfl,
634  const Grid &grid )
635  : BaseType( startTime, cfl, grid.comm() ),
636  dm_( DofManagerType ::instance( grid ) ),
637  sequence_( -1 )
638  {}
639 
640  virtual ~GridTimeProvider() {}
641 
642  protected:
643  using BaseType :: counter_ ;
644  using BaseType :: updateStep_ ;
645 
646  // this initTimeStep method also check the sequence number
647  // in case the grid has changed due to adaptivity
648  void initTimeStep ( const double dtEstimate )
649  {
650  const int currentSequence = dm_.sequence();
651  // check sequence number
652  if( sequence_ != currentSequence )
653  {
654  // if sequence number changed, update in any case
655  counter_ = updateStep_ ;
656  sequence_ = currentSequence ;
657  }
658 
659  // call initTimeStep on base class
660  BaseType :: initTimeStep( dtEstimate );
661  }
662 
663  const DofManagerType& dm_;
664  int sequence_ ;
665  };
666 
667  } // namespace Fem
668 
669 } // namespace Dune
670 
671 #endif // #ifndef DUNE_FEM_TIMEPROVIDER_HH
Collective communication interface and sequential default implementation.
Definition: communication.hh:100
T min(const T &in) const
Compute the minimum of the argument over all processes and return the result in every process....
Definition: communication.hh:228
base class for auto persistent objects
Definition: persistencemanager.hh:580
Definition: dofmanager.hh:786
the same functionality as the Dune::TimeProvider.
Definition: timeprovider.hh:609
base class for persistent objects
Definition: persistencemanager.hh:101
general base for time providers
Definition: timeprovider.hh:36
double timeStepEstimate() const
obtain current estimate on time step
Definition: timeprovider.hh:133
void restore()
restore persistent object
Definition: timeprovider.hh:75
double time() const
obtain the current time
Definition: timeprovider.hh:94
int timeStep() const
obtain number of the current time step
Definition: timeprovider.hh:103
void provideTimeStepEstimate(const double dtEstimate)
set time step estimate to minimum of given value and internal time step estiamte
Definition: timeprovider.hh:142
bool timeStepValid() const
return if this time step should be used
Definition: timeprovider.hh:164
double deltaT() const
obtain the size of the current time step
Definition: timeprovider.hh:113
void provideTimeStepUpperBound(const double upperBound)
set upper bound for time step to minimum of given value and internal bound
Definition: timeprovider.hh:151
double inverseDeltaT() const
obtain the size of the inverse of the current time step
Definition: timeprovider.hh:123
void backup() const
backup persistent object
Definition: timeprovider.hh:68
void invalidateTimeStep()
count current time step a not valid
Definition: timeprovider.hh:158
manager for global simulation time of time-dependent solutions
Definition: timeprovider.hh:405
void init()
init dt with time step estimate
Definition: timeprovider.hh:488
void next()
goto next time step
Definition: timeprovider.hh:508
void init(const double timeStep)
init dt with provided time step
Definition: timeprovider.hh:498
TimeProvider(const double startTime, const double cfl, const CommunicationType &comm=MPIManager::comm())
constructor taking start time and CFL constant
Definition: timeprovider.hh:469
TimeProvider(const ParameterReader &parameter=Parameter::container())
default constructor
Definition: timeprovider.hh:433
TimeProvider(const double startTime, const CommunicationType &comm=MPIManager::comm())
constructor taking start time
Definition: timeprovider.hh:454
virtual void restore()
restore persistent object
Definition: timeprovider.hh:577
void restore(const double time, const int timeStep)
restore time and timestep from outside (i.e. from former calculation)
Definition: timeprovider.hh:566
void next(const double timeStep)
goto next time step
Definition: timeprovider.hh:523
virtual void backup() const
backup persistent object
Definition: timeprovider.hh:572
double factor() const
return the global factor number
Definition: timeprovider.hh:532
Grid abstract base class.
Definition: grid.hh:375
const Communication & comm() const
return const reference to a communication object. The return type is a model of Dune::Communication.
Definition: grid.hh:722
static ThisType & instance(const GridType &grid)
obtain a reference to the DofManager for a given grid
Definition: dofmanager.hh:1251
int sequence() const
return number of sequence, if dofmanagers memory was changed by calling some method like resize,...
Definition: dofmanager.hh:1007
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:484
constexpr auto min
Function object that returns the smaller of the given values.
Definition: hybridutilities.hh:506
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)