DUNE-FEM (unstable)

persistencemanager.hh
1#ifndef DUNE_FEM_PERSISTENCEMANAGER_HH
2#define DUNE_FEM_PERSISTENCEMANAGER_HH
3
4#include <fstream>
5#include <iostream>
6#include <list>
7#include <sstream>
8#include <string>
9#include <type_traits>
10#include <utility>
11
12#include <dune/fem/io/file/iointerface.hh>
13#include <dune/fem/io/parameter.hh>
14#include <dune/fem/io/streams/binarystreams.hh>
15#include <dune/fem/io/streams/tuples.hh>
16#include <dune/fem/storage/singleton.hh>
17
18namespace Dune
19{
20
21 namespace Fem
22 {
23
94 class PersistenceManager;
95
101 {
103
104 friend class PersistenceManager;
105
106 public:
107 virtual ~PersistentObject() {}
109 virtual void backup () const = 0;
111 virtual void restore () = 0;
112
113 protected:
115 virtual void insertSubData() {}
117 virtual void removeSubData() {}
118
119 virtual void *pointer ()
120 {
121 return this;
122 }
123 };
124
125
126
127 template< class ObjectType >
128 struct IsPersistent
129 {
130 static const bool value = std::is_convertible< ObjectType *, PersistentObject * >::value;
131 };
132
133
134
141 {
143 template <class ObjectType,bool isPersistent>
144 struct WrapObject;
145
146 public:
147 // make backup and restore streams exchangeable
148#ifdef FEM_PERSISTENCEMANAGERSTREAMTRAITS
149 typedef FEM_PERSISTENCEMANAGERSTREAMTRAITS :: BackupStreamType BackupStreamType;
150 typedef FEM_PERSISTENCEMANAGERSTREAMTRAITS :: RestoreStreamType RestoreStreamType;
151 static const bool singleBackupRestoreFile = FEM_PERSISTENCEMANAGERSTREAMTRAITS ::
152 singleBackupRestoreFile ;
153#else
154 typedef Fem :: BinaryFileOutStream BackupStreamType ;
155 typedef Fem :: BinaryFileInStream RestoreStreamType ;
156 static const bool singleBackupRestoreFile = false ;
157#endif
158
159 private:
160 typedef std::list< std::pair< PersistentObject *, unsigned int > > PersistentType;
161 typedef PersistentType::iterator IteratorType;
162
163 PersistentType objects_;
164 int fileCounter_,lineNo_;
165 std::string path_;
166 std::ifstream inAsciStream_;
167 std::ofstream outAsciStream_;
168 bool closed_,invalid_;
169
170 BackupStreamType* backupStream_;
171 RestoreStreamType* restoreStream_;
172
174 : fileCounter_( 0 ),
175 lineNo_(),
176 path_(),
177 closed_( false ),
178 invalid_( false ),
179 backupStream_( 0 ),
180 restoreStream_( 0 )
181 {}
182
183 PersistenceManager ( const ThisType & );
184 ThisType &operator= ( const ThisType & );
185
186 BackupStreamType& backupStreamObj ()
187 {
188 assert( backupStream_ );
189 return *backupStream_ ;
190 }
191
192 RestoreStreamType& restoreStreamObj ()
193 {
194 assert( restoreStream_ );
195 return *restoreStream_ ;
196 }
197
198 public:
199 template< class ObjectType >
200 void insertObject( ObjectType &object, const bool pushFront = false )
201 {
202 IteratorType end = objects_.end();
203 for( IteratorType it = objects_.begin(); it != end; ++it )
204 {
205 if( it->first->pointer() != &object )
206 continue;
207 ++it->second;
208 return;
209 }
210
211 // for objects like the grid
212 // we need to allow to add this later
213 if ( closed_ && ! pushFront )
214 {
215#ifndef NDEBUG
216 std::cerr << "WARNING: new object added to PersistenceManager "
217 << "although backup/restore has been called - "
218 << "Object will be ignored!" << std::endl;
219#endif
220 return;
221 }
222
223 PersistentObject *obj =
224 WrapObject< ObjectType, IsPersistent< ObjectType > :: value >
225 :: apply( object );
226
227 // insert possible sub data
228 obj->insertSubData();
229
230 if( pushFront )
231 objects_.push_front( std :: make_pair( obj, 1 ) );
232 else
233 objects_.push_back( std :: make_pair( obj, 1 ) );
234 }
235
236 template< class ObjectType >
237 void removeObject ( ObjectType &object )
238 {
239 IteratorType end = objects_.end();
240 for( IteratorType it = objects_.begin(); it != end; ++it )
241 {
242 if( it->first->pointer() != &object )
243 continue;
244
245 --it->second;
246 if( it->second == 0 )
247 {
248 if (closed_) invalid_=true;
249 PersistentObject *obj = it->first;
250 // remove possible sub data
251 obj->removeSubData();
252 objects_.erase( it );
253 if( !IsPersistent< ObjectType > :: value )
254 delete obj;
255 }
256 return;
257 }
258 }
259
260 void backupObjects ( const std::string& path )
261 {
262 if( invalid_ )
263 {
264#ifndef NDEBUG
265 std::cerr << "WARNING: backup called although objects "
266 << "have been removed from the PersistenceManager! "
267 << "Backup ignored!" << std::endl;
268#endif
269 return;
270 }
271 closed_ = true;
272 startBackup( path );
273 typedef PersistentType::iterator IteratorType;
274
275 for( IteratorType it = objects_.begin(); it != objects_.end(); ++it )
276 it->first->backup();
277
278 closeStreams();
279 }
280
281 void restoreObjects ( const std::string &path )
282 {
283 if (invalid_) {
284#ifndef NDEBUG
285 std::cerr << "WARNING: restore called although objects "
286 << "have been removed from the PersistenceManager! "
287 << "Restore ignored!" << std::endl;
288#endif
289 return;
290 }
291 closed_ = true;
292 startRestoreImpl( path );
293 typedef PersistentType :: iterator IteratorType;
294
295 for( IteratorType it = objects_.begin(); it != objects_.end(); ++it )
296 it->first->restore( );
297
298 closeStreams();
299 }
300
301 std::string getUniqueFileName ( const std::string &tag )
302 {
303 return generateFilename( path_ + "/" + tag, ++fileCounter_ );
304 }
305
306 std::string getUniqueTag ( const std::string &tag )
307 {
308 return generateFilename( tag, ++fileCounter_ );
309 }
310
311 template< class T >
312 void backup ( const std::string &token, const T &value )
313 {
314 backupStreamObj() << token;
315 backupStreamObj() << value;
316 }
317
318 template< class T >
319 void restore ( const std::string &token, T &value )
320 {
321 std::string readToken ;
322 restoreStreamObj() >> readToken;
323 restoreStreamObj() >> value;
324 if( token != readToken )
325 {
326 DUNE_THROW(InvalidStateException,"wrong object restored in PersistenceManager" << token << " " << readToken );
327 }
328 }
329
331 void reset()
332 {
333 closeStreams(); // flush and close streams
334 objects_.clear(); // clear all objects
335 path_.clear();
336 lineNo_ = 0;
337 closed_ = false;
338 invalid_ = false;
339 }
340
341 public:
343
345 {
347 }
348
349 static BackupStreamType& backupStream()
350 {
351 return instance ().backupStreamObj();
352 }
353
354 static RestoreStreamType& restoreStream()
355 {
356 return instance ().restoreStreamObj();
357 }
358
359 static void insert ( PersistentObject &object, const bool pushFront = false )
360 {
361 instance().insertObject( object, pushFront );
362 }
363
364 static void remove ( PersistentObject &object )
365 {
366 instance().removeObject( object );
367 }
368
369 static void backup ( const std::string& path )
370 {
371 instance().backupObjects( path );
372 }
373
374 static void restore ( const std::string& path )
375 {
376 instance().restoreObjects( path );
377 }
378
379 static void startRestore ( const std::string& path )
380 {
381 instance().startRestoreImpl( path );
382 }
383
384 static std::string uniqueFileName(const std::string& tag = "" )
385 {
386 return instance().getUniqueFileName( tag );
387 }
388
389 static std::string uniqueTag(const std::string& tag = "" )
390 {
391 return instance().getUniqueTag( tag );
392 }
393
394 template< class T >
395 static void backupValue ( const std::string &token, const T &value )
396 {
397 instance().backup( token, value );
398 }
399
400 template< class T >
401 static void restoreValue ( const std::string &token, T &value )
402 {
403 instance().restore( token, value );
404 }
405
406 private:
407 const char* myTag() const { return "persistentobjects"; }
408
409 // create filename for persistent objects
410 std::string createFilename( const std::string& path,
411 const int rank,
412 const int size ) const
413 {
414 std::stringstream s;
415 const int number = ( singleBackupRestoreFile ) ? size : rank ;
416 s << path << myTag() << "." << number ;
417 return s.str();
418 }
419
420 void startBackup ( const std::string &path )
421 {
422 path_ = path + "/";
423
424 if( createDirectory( path_ ) )
425 {
426 const int rank = MPIManager :: rank() ;
427 const int size = MPIManager :: size() ;
428 std::string filename( createFilename( path_, rank, size ) );
429
430 assert( backupStream_ == 0 );
431 backupStream_ = Fem :: StreamFactory<BackupStreamType> :: create( filename );
432
433 if( rank == 0 )
434 {
435 std::ofstream paramfile( (path_ + "parameter").c_str() );
436 if( paramfile )
437 {
438 // write parameters on rank 0
439 Parameter::write( paramfile, true );
440 }
441 }
442 }
443 else
444 std::cerr << "Error: Unable to create '" << path_ << "'" << std::endl;
445 }
446
447 void startRestoreImpl ( const std::string &path )
448 {
449 if( restoreStream_ == 0 )
450 {
451 path_ = path + "/";
452 const int rank = MPIManager :: rank();
453 const int size = MPIManager :: size();
454 std::string filename( createFilename( path_, rank, size ) );
455 // create strema with stream factory
456 restoreStream_ = Fem :: StreamFactory<RestoreStreamType> :: create( filename );
457
458 if( Parameter :: verbose () )
459 std::cout << "Restore from " << filename << std::endl;
460
461 if( ! restoreStream_ )
462 {
463 std::cout << "Error opening global stream: " << path_+myTag()
464 << std::endl;
465 abort();
466 }
467
468 // restore parameter
469 Parameter::container().clear();
470 Parameter::append(path_ + "parameter");
471 }
472 }
473
474 void closeStreams ()
475 {
476 if( backupStream_ )
477 {
478 backupStream_->flush();
479 delete backupStream_;
480 backupStream_ = 0;
481 }
482
483 if( restoreStream_ )
484 {
485 delete restoreStream_;
486 restoreStream_ = 0;
487 }
488 }
489 };
490
491
492 // !!!! not accessable outside namespace Dune::Fem ?!?!?!
493 namespace
494 {
495 PersistenceManager &persistenceManager __attribute__((unused)) = PersistenceManager::instance();
496 }
497
498
499 template< class ObjectType >
500 inline PersistenceManager &
501 operator<< ( PersistenceManager &pm, ObjectType &object )
502 {
503 static_assert( !std::is_pointer< ObjectType >::value, "Do not add pointers to PersistenceManager." );
504 pm.insertObject( object );
505 return pm;
506 }
507
508
509 template< class ObjectType >
510 inline PersistenceManager &
511 operator>> ( PersistenceManager &pm, ObjectType &object )
512 {
513 pm.removeObject( object );
514 return pm;
515 }
516
517
518 template< class ObjectType >
519 struct PersistenceManager::WrapObject< ObjectType, true >
520 {
521 static PersistentObject *apply( ObjectType &obj )
522 {
523 return &obj;
524 }
525 };
526
527
528 template< class ObjectType >
529 struct PersistenceManager::WrapObject< ObjectType, false >
530 : public PersistentObject
531 {
532 typedef WrapObject< ObjectType, false > ThisType;
533 typedef PersistentObject BaseType;
534
535 protected:
536 ObjectType& obj_;
537 std::string token_;
538
539 WrapObject( ObjectType &obj )
540 : obj_( obj ),
541 // store unique token of this object
542 token_( "_token"+PersistenceManager::uniqueTag() )
543 {}
544
545 public:
546 virtual ~WrapObject ()
547 {}
548
549 virtual void backup () const
550 {
551 PersistenceManager::backupValue( token_, obj_ );
552 }
553
554 virtual void restore ()
555 {
556 PersistenceManager::restoreValue( token_, obj_ );
557 }
558
559 protected:
560 virtual void *pointer ()
561 {
562 return &obj_;
563 }
564
565 public:
566 static PersistentObject *apply ( ObjectType &obj )
567 {
568 return new ThisType( obj );
569 }
570 };
571
572
573
579 : public PersistentObject
580 {
583
584 protected:
586 {
587 PersistenceManager::insert( *this );
588 }
589
591 {
592 PersistenceManager::insert( *this );
593 }
594
595 virtual ~AutoPersistentObject ()
596 {
597 PersistenceManager::remove( *this );
598 }
599 };
600
601 } // end namespace Fem
602
603} // end namespace Dune
604
605#endif // #ifndef DUNE_FEM_PERSISTENCEMANAGER_HH
base class for auto persistent objects
Definition: persistencemanager.hh:580
Definition: binarystreams.hh:57
Definition: binarystreams.hh:16
static bool verbose()
obtain the cached value for fem.verbose with default verbosity level 2
Definition: parameter.hh:466
static void append(int &argc, char **argv)
add parameters from the command line RangeType gRight;
Definition: parameter.hh:219
class with singleton instance managing all persistent objects
Definition: persistencemanager.hh:141
void reset()
clear all objects registered to PersistenceManager
Definition: persistencemanager.hh:331
base class for persistent objects
Definition: persistencemanager.hh:101
virtual void insertSubData()
insert possible sub data of object
Definition: persistencemanager.hh:115
virtual void backup() const =0
backup persistent object
virtual void restore()=0
restore persistent object
virtual void removeSubData()
remove possible sub data of object
Definition: persistencemanager.hh:117
return singleton instance of given Object type.
Definition: singleton.hh:93
static DUNE_EXPORT Object & instance(Args &&... args)
return singleton instance of given Object type.
Definition: singleton.hh:123
void flush()
flush the stream
Definition: standardstreams.hh:88
Default exception if a function was called while the object is not in a valid state for that function...
Definition: exceptions.hh:281
Stream & operator>>(Stream &stream, std::tuple< Ts... > &t)
Read a std::tuple.
Definition: streamoperators.hh:43
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)