dune-fem  2.4.1-rc
persistencemanager.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_PERSISTENCEMANAGER_HH
2 #define DUNE_FEM_PERSISTENCEMANAGER_HH
3 
4 #include <fstream>
5 #include <list>
6 
7 #include <dune/common/typetraits.hh>
8 
10 #include <dune/fem/io/parameter.hh>
13 
14 namespace Dune
15 {
16 
17  namespace Fem
18  {
19 
90  class PersistenceManager;
91 
97  {
98  typedef PersistentObject ThisType;
99 
100  friend class PersistenceManager;
101 
102  public:
103  virtual ~PersistentObject() {}
105  virtual void backup () const = 0;
107  virtual void restore () = 0;
108 
109  protected:
111  virtual void insertSubData() {}
113  virtual void removeSubData() {}
114 
115  virtual void *pointer ()
116  {
117  return this;
118  }
119  };
120 
121 
122 
123  template< class ObjectType >
125  {
126  static const bool value = Dune::Conversion< ObjectType *, PersistentObject * >::exists;
127  };
128 
129 
130 
137  {
139  template <class ObjectType,bool isPersistent>
140  struct WrapObject;
141 
142  public:
143  // make backup and restore streams exchangeable
144 #ifdef FEM_PERSISTENCEMANAGERSTREAMTRAITS
145  typedef FEM_PERSISTENCEMANAGERSTREAMTRAITS :: BackupStreamType BackupStreamType;
146  typedef FEM_PERSISTENCEMANAGERSTREAMTRAITS :: RestoreStreamType RestoreStreamType;
147  static const bool singleBackupRestoreFile = FEM_PERSISTENCEMANAGERSTREAMTRAITS ::
148  singleBackupRestoreFile ;
149 #else
152  static const bool singleBackupRestoreFile = false ;
153 #endif
154 
155  private:
156  typedef std::list< std::pair< PersistentObject *, unsigned int > > PersistentType;
157  typedef PersistentType::iterator IteratorType;
158 
159  PersistentType objects_;
160  int fileCounter_,lineNo_;
161  std::string path_;
162  std::ifstream inAsciStream_;
163  std::ofstream outAsciStream_;
164  bool closed_,invalid_;
165 
166  BackupStreamType* backupStream_;
167  RestoreStreamType* restoreStream_;
168 
170  : fileCounter_( 0 ),
171  lineNo_(),
172  path_(),
173  closed_( false ),
174  invalid_( false ),
175  backupStream_( 0 ),
176  restoreStream_( 0 )
177  {}
178 
179  PersistenceManager ( const ThisType & );
180  ThisType &operator= ( const ThisType & );
181 
182  BackupStreamType& backupStreamObj ()
183  {
184  assert( backupStream_ );
185  return *backupStream_ ;
186  }
187 
188  RestoreStreamType& restoreStreamObj ()
189  {
190  assert( restoreStream_ );
191  return *restoreStream_ ;
192  }
193 
194  public:
195  template< class ObjectType >
196  void insertObject( ObjectType &object, const bool pushFront = false )
197  {
198  IteratorType end = objects_.end();
199  for( IteratorType it = objects_.begin(); it != end; ++it )
200  {
201  if( it->first->pointer() != &object )
202  continue;
203  ++it->second;
204  return;
205  }
206 
207  // for objects like the grid
208  // we need to allow to add this later
209  if ( closed_ && ! pushFront )
210  {
211 #ifndef NDEBUG
212  std::cerr << "WARNING: new object added to PersistenceManager "
213  << "although backup/restore has been called - "
214  << "Object will be ignored!" << std::endl;
215 #endif
216  return;
217  }
218 
219  PersistentObject *obj =
220  WrapObject< ObjectType, IsPersistent< ObjectType > :: value >
221  :: apply( object );
222 
223  // insert possible sub data
224  obj->insertSubData();
225 
226  if( pushFront )
227  objects_.push_front( std :: make_pair( obj, 1 ) );
228  else
229  objects_.push_back( std :: make_pair( obj, 1 ) );
230  }
231 
232  template< class ObjectType >
233  void removeObject ( ObjectType &object )
234  {
235  IteratorType end = objects_.end();
236  for( IteratorType it = objects_.begin(); it != end; ++it )
237  {
238  if( it->first->pointer() != &object )
239  continue;
240 
241  --it->second;
242  if( it->second == 0 )
243  {
244  if (closed_) invalid_=true;
245  PersistentObject *obj = it->first;
246  // remove possible sub data
247  obj->removeSubData();
248  objects_.erase( it );
250  delete obj;
251  }
252  return;
253  }
254  }
255 
256  void backupObjects ( const std::string& path )
257  {
258  if( invalid_ )
259  {
260 #ifndef NDEBUG
261  std::cerr << "WARNING: backup called although objects "
262  << "have been removed from the PersistenceManager! "
263  << "Backup ignored!" << std::endl;
264 #endif
265  return;
266  }
267  closed_ = true;
268  startBackup( path );
269  typedef PersistentType::iterator IteratorType;
270 
271  for( IteratorType it = objects_.begin(); it != objects_.end(); ++it )
272  it->first->backup();
273 
274  closeStreams();
275  }
276 
277  void restoreObjects ( const std::string &path )
278  {
279  if (invalid_) {
280 #ifndef NDEBUG
281  std::cerr << "WARNING: restore called although objects "
282  << "have been removed from the PersistenceManager! "
283  << "Restore ignored!" << std::endl;
284 #endif
285  return;
286  }
287  closed_ = true;
288  startRestoreImpl( path );
289  typedef PersistentType :: iterator IteratorType;
290 
291  for( IteratorType it = objects_.begin(); it != objects_.end(); ++it )
292  it->first->restore( );
293 
294  closeStreams();
295  }
296 
297  std::string getUniqueFileName ( const std::string &tag )
298  {
299  return generateFilename( path_ + "/" + tag, ++fileCounter_ );
300  }
301 
302  std::string getUniqueTag ( const std::string &tag )
303  {
304  return generateFilename( tag, ++fileCounter_ );
305  }
306 
307  template< class T >
308  void backup ( const std::string &token, const T &value )
309  {
310  backupStreamObj() << token;
311  backupStreamObj() << value;
312  }
313 
314  template< class T >
315  void restore ( const std::string &token, T &value )
316  {
317  std::string readToken ;
318  restoreStreamObj() >> readToken;
319  restoreStreamObj() >> value;
320  if( token != readToken )
321  {
322  DUNE_THROW(InvalidStateException,"wrong object restored in PersistenceManager" << token << " " << readToken );
323  }
324  }
325 
326  public:
328  {
329  static PersistenceManager theInstance;
330  return theInstance;
331  }
332 
333  static BackupStreamType& backupStream()
334  {
335  return instance ().backupStreamObj();
336  }
337 
338  static RestoreStreamType& restoreStream()
339  {
340  return instance ().restoreStreamObj();
341  }
342 
343  static void insert ( PersistentObject &object, const bool pushFront = false )
344  {
345  instance().insertObject( object, pushFront );
346  }
347 
348  static void remove ( PersistentObject &object )
349  {
350  instance().removeObject( object );
351  }
352 
353  static void backup ( const std::string& path )
354  {
355  instance().backupObjects( path );
356  }
357 
358  static void restore ( const std::string& path )
359  {
360  instance().restoreObjects( path );
361  }
362 
363  static void startRestore ( const std::string& path )
364  {
365  instance().startRestoreImpl( path );
366  }
367 
368  static std::string uniqueFileName(const std::string& tag = "" )
369  {
370  return instance().getUniqueFileName( tag );
371  }
372 
373  static std::string uniqueTag(const std::string& tag = "" )
374  {
375  return instance().getUniqueTag( tag );
376  }
377 
378  template< class T >
379  static void backupValue ( const std::string &token, const T &value )
380  {
381  instance().backup( token, value );
382  }
383 
384  template< class T >
385  static void restoreValue ( const std::string &token, T &value )
386  {
387  instance().restore( token, value );
388  }
389 
390  private:
391  const char* myTag() const { return "persistentobjects"; }
392 
393  // create filename for persistent objects
394  std::string createFilename( const std::string& path,
395  const int rank,
396  const int size ) const
397  {
398  std::stringstream s;
399  const int number = ( singleBackupRestoreFile ) ? size : rank ;
400  s << path << myTag() << "." << number ;
401  return s.str();
402  }
403 
404  void startBackup ( const std::string &path )
405  {
406  path_ = path + "/";
407 
408  if( createDirectory( path_ ) )
409  {
410  const int rank = MPIManager :: rank() ;
411  const int size = MPIManager :: size() ;
412  std::string filename( createFilename( path_, rank, size ) );
413 
414  assert( backupStream_ == 0 );
415  backupStream_ = Fem :: StreamFactory<BackupStreamType> :: create( filename );
416 
417  if( rank == 0 )
418  {
419  std::ofstream paramfile( (path_ + "parameter").c_str() );
420  if( paramfile )
421  {
422  // write parameters on rank 0
423  Parameter::write( paramfile, true );
424  }
425  }
426  }
427  else
428  std::cerr << "Error: Unable to create '" << path_ << "'" << std::endl;
429  }
430 
431  void startRestoreImpl ( const std::string &path )
432  {
433  if( restoreStream_ == 0 )
434  {
435  path_ = path + "/";
436  const int rank = MPIManager :: rank();
437  const int size = MPIManager :: size();
438  std::string filename( createFilename( path_, rank, size ) );
439  // create strema with stream factory
440  restoreStream_ = Fem :: StreamFactory<RestoreStreamType> :: create( filename );
441 
442  if( Parameter :: verbose () )
443  std::cout << "Restore from " << filename << std::endl;
444 
445  if( ! restoreStream_ )
446  {
447  std::cout << "Error opening global stream: " << path_+myTag()
448  << std::endl;
449  abort();
450  }
451 
452  // restore parameter
454  Parameter::append(path_ + "parameter");
455  }
456  }
457 
458  void closeStreams ()
459  {
460  if( backupStream_ )
461  {
462  backupStream_->flush();
463  delete backupStream_;
464  backupStream_ = 0;
465  }
466 
467  if( restoreStream_ )
468  {
469  delete restoreStream_;
470  restoreStream_ = 0;
471  }
472  }
473  };
474 
475 
476  // !!!! not accessable outside namespace Dune::Fem ?!?!?!
477  namespace
478  {
479  PersistenceManager &persistenceManager DUNE_UNUSED = PersistenceManager::instance();
480  }
481 
482 
483  template< class ObjectType >
484  inline PersistenceManager &
485  operator<< ( PersistenceManager &pm, ObjectType &object )
486  {
487  static_assert( !TypeTraits< ObjectType >::isPointer, "Do not add pointers to PersistenceManager." );
488  pm.insertObject( object );
489  return pm;
490  }
491 
492 
493  template< class ObjectType >
494  inline PersistenceManager &
495  operator>> ( PersistenceManager &pm, ObjectType &object )
496  {
497  pm.removeObject( object );
498  return pm;
499  }
500 
501 
502  template< class ObjectType >
503  struct PersistenceManager::WrapObject< ObjectType, true >
504  {
505  static PersistentObject *apply( ObjectType &obj )
506  {
507  return &obj;
508  }
509  };
510 
511 
512  template< class ObjectType >
513  struct PersistenceManager::WrapObject< ObjectType, false >
514  : public PersistentObject
515  {
518 
519  protected:
520  ObjectType& obj_;
521  std::string token_;
522 
523  WrapObject( ObjectType &obj )
524  : obj_( obj ),
525  // store unique token of this object
526  token_( "_token"+PersistenceManager::uniqueTag() )
527  {}
528 
529  public:
530  virtual ~WrapObject ()
531  {}
532 
533  virtual void backup () const
534  {
535  PersistenceManager::backupValue( token_, obj_ );
536  }
537 
538  virtual void restore ()
539  {
540  PersistenceManager::restoreValue( token_, obj_ );
541  }
542 
543  protected:
544  virtual void *pointer ()
545  {
546  return &obj_;
547  }
548 
549  public:
550  static PersistentObject *apply ( ObjectType &obj )
551  {
552  return new ThisType( obj );
553  }
554  };
555 
556 
557 
563  : public PersistentObject
564  {
566  typedef PersistentObject BaseType;
567 
568  protected:
570  {
572  }
573 
574  AutoPersistentObject ( const ThisType & )
575  {
577  }
578 
580  {
582  }
583  };
584 
585  } // end namespace Fem
586 
587 } // end namespace Dune
588 
589 #endif // #ifndef DUNE_FEM_PERSISTENCEMANAGER_HH
virtual void removeSubData()
remove possible sub data of object
Definition: persistencemanager.hh:113
AutoPersistentObject()
Definition: persistencemanager.hh:569
void backup(const std::string &token, const T &value)
Definition: persistencemanager.hh:308
virtual ~AutoPersistentObject()
Definition: persistencemanager.hh:579
Definition: persistencemanager.hh:124
virtual void insertSubData()
insert possible sub data of object
Definition: persistencemanager.hh:111
void removeObject(ObjectType &object)
Definition: persistencemanager.hh:233
static int rank()
Definition: mpimanager.hh:116
static void restore(const std::string &path)
Definition: persistencemanager.hh:358
static std::string uniqueFileName(const std::string &tag="")
Definition: persistencemanager.hh:368
friend class PersistenceManager
Definition: persistencemanager.hh:100
static int size()
Definition: mpimanager.hh:121
WrapObject< ObjectType, false > ThisType
Definition: persistencemanager.hh:516
static void startRestore(const std::string &path)
Definition: persistencemanager.hh:363
static RestoreStreamType & restoreStream()
Definition: persistencemanager.hh:338
static void insert(PersistentObject &object, const bool pushFront=false)
Definition: persistencemanager.hh:343
InStreamInterface< StreamTraits > & operator>>(InStreamInterface< StreamTraits > &in, DiscreteFunctionInterface< Impl > &df)
read a discrete function from an input stream
Definition: discretefunction_inline.hh:395
virtual void backup() const
backup persistent object
Definition: persistencemanager.hh:533
class with singleton instance managing all persistent objects
Definition: persistencemanager.hh:136
virtual void restore()=0
restore persistent object
void flush()
flush the stream
Definition: standardstreams.hh:88
std::string token_
Definition: persistencemanager.hh:521
static StreamImpl * create(const std::string &filename, const int rank=MPIManager::rank(), const MPICommunicatorType &mpiComm=MPIHelper::getCommunicator())
return pointer to stream object created by new.
Definition: streams.hh:369
bool createDirectory(const std::string &inName)
create a directory
Definition: io.cc:19
Fem::BinaryFileInStream RestoreStreamType
Definition: persistencemanager.hh:151
std::string getUniqueFileName(const std::string &tag)
Definition: persistencemanager.hh:297
static void append(int &argc, char **argv)
add parameters from the command line RangeType gRight;
Definition: io/parameter.hh:215
virtual void backup() const =0
backup persistent object
std::string getUniqueTag(const std::string &tag)
Definition: persistencemanager.hh:302
constructor
Definition: binarystreams.hh:15
std::string generateFilename(const std::string &fn, int ntime, int precision=6)
Definition: iointerface.hh:47
virtual void restore()
restore persistent object
Definition: persistencemanager.hh:538
void restore(const std::string &token, T &value)
Definition: persistencemanager.hh:315
void restoreObjects(const std::string &path)
Definition: persistencemanager.hh:277
static BackupStreamType & backupStream()
Definition: persistencemanager.hh:333
static PersistentObject * apply(ObjectType &obj)
Definition: persistencemanager.hh:550
Definition: coordinate.hh:4
static PersistentObject * apply(ObjectType &obj)
Definition: persistencemanager.hh:505
static ParameterContainer & container()
Definition: io/parameter.hh:190
static void write(const std::string &filename, const std::string &fileextension="", bool writeAll=true)
write the parameter database to a file
Definition: io/parameter.hh:515
static void backup(const std::string &path)
Definition: persistencemanager.hh:353
std::string path
Definition: readioparams.cc:155
AutoPersistentObject(const ThisType &)
Definition: persistencemanager.hh:574
void insertObject(ObjectType &object, const bool pushFront=false)
Definition: persistencemanager.hh:196
static void restoreValue(const std::string &token, T &value)
Definition: persistencemanager.hh:385
static void remove(PersistentObject &object)
Definition: persistencemanager.hh:348
base class for auto persistent objects
Definition: persistencemanager.hh:562
base class for persistent objects
Definition: persistencemanager.hh:96
static bool verbose()
obtain the cached value for fem.verbose
Definition: io/parameter.hh:444
void backupObjects(const std::string &path)
Definition: persistencemanager.hh:256
virtual ~WrapObject()
Definition: persistencemanager.hh:530
Fem::BinaryFileOutStream BackupStreamType
Definition: persistencemanager.hh:140
virtual void * pointer()
Definition: persistencemanager.hh:115
constructor
Definition: binarystreams.hh:56
WrapObject(ObjectType &obj)
Definition: persistencemanager.hh:523
PersistentObject BaseType
Definition: persistencemanager.hh:517
ObjectType & obj_
Definition: persistencemanager.hh:520
virtual void * pointer()
Definition: persistencemanager.hh:544
virtual ~PersistentObject()
Definition: persistencemanager.hh:103
OutStreamInterface< StreamTraits > & operator<<(OutStreamInterface< StreamTraits > &out, const DiscreteFunctionInterface< Impl > &df)
write a discrete function into an output stream
Definition: discretefunction_inline.hh:375
static void backupValue(const std::string &token, const T &value)
Definition: persistencemanager.hh:379
void clear()
clear all parameters
Definition: container.hh:149
static std::string uniqueTag(const std::string &tag="")
Definition: persistencemanager.hh:373
static PersistenceManager & instance()
Definition: persistencemanager.hh:327