dune-fem  2.8-git
iointerface.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_IOINTERFACE_HH
2 #define DUNE_FEM_IOINTERFACE_HH
3 
4 //- system includes
5 #include <dirent.h>
6 #include <iostream>
7 #include <iomanip>
8 #include <sstream>
9 #include <utility>
10 #include <sys/stat.h>
11 #include <sys/types.h>
12 
13 
14 //- Dune includes
15 #include <dune/common/exceptions.hh>
16 #include <dune/grid/yaspgrid.hh>
17 #include <dune/grid/io/file/dgfparser/dgfparser.hh>
18 
19 
20 // defines Parameter
21 #include <dune/fem/io/parameter.hh>
22 
23 // binary data io
24 #include <dune/fem/io/io.hh>
25 
27 
28 // if grape was configured then include headers
29 #if HAVE_GRAPE
30 #include <dune/grid/io/visual/grapedatadisplay.hh>
31 #endif
32 
33 #include <dune/grid/yaspgrid.hh>
34 #if HAVE_DUNE_SPGRID
35 #include <dune/grid/spgrid.hh>
36 #endif
37 
38 namespace Dune
39 {
40 
41  namespace Fem
42  {
43 
44  // generateFilename
45  // ----------------
46 
47  inline std::string generateFilename ( const std::string &fn,
48  int ntime,
49  int precision = 6 )
50  {
51  std::ostringstream name;
52  name << fn << std::setw( precision ) << std::setfill( '0' ) << ntime;
53  return name.str();
54  }
55 
56 
57 
58  class TimeProviderBase;
59 
161  class IOInterface {
162 
163  protected:
166 
167  public:
169  virtual ~IOInterface () {}
170 
174  virtual void writeData ( double sequenceStamp ) const = 0;
175 
179  virtual void write( const TimeProviderBase& tp ) const = 0;
180 
183  virtual void write() const = 0;
184 
186  static std::string defaultGridKey ( int dimension, bool check = true )
187  {
188  return defaultGridKey( dimension, Parameter::container(), check );
189  }
190 
191  static std::string defaultGridKey ( int dimension, const ParameterReader &parameter, bool check = true )
192  {
193  return defaultGridKey( "fem.io.macroGridFile", dimension, parameter, check );
194  }
195 
196  static std::string defaultGridKey ( std::string base, int dimension, bool check = true )
197  {
198  return defaultGridKey( std::move( base ), dimension, Parameter::container(), check );
199  }
200 
202  static std::string defaultGridKey ( std::string base, int dimension, const ParameterReader &parameter, bool check = true )
203  {
204  const std::string oldGridKey( base );
205 
206  std::ostringstream gridKeyStream;
207  gridKeyStream << oldGridKey << "_" << dimension << "d";
208  const std::string newGridKey( gridKeyStream.str() );
209 
210  // check for old parameter
211  if( parameter.exists( oldGridKey ) )
212  {
213  if( parameter.exists( newGridKey ) )
214  {
215  std::cerr << "WARNING: ignoring `" << oldGridKey << "' because `"
216  << newGridKey << "' was also found in parameter file." << std::endl;
217  return newGridKey;
218  }
219  else
220  {
221  std::cerr << "WARNING: change `" << oldGridKey << "' to `" << newGridKey
222  << "' in parameter file." << std::endl;
223  return oldGridKey;
224  }
225  }
226 
227  // check for parameter with dimension
228  if( check && !parameter.exists( newGridKey ) )
229  {
230  std::cerr << "ERROR: Parameter `" << newGridKey << "' not found." << std::endl;
231  DUNE_THROW( ParameterNotFound, "Parameter `" << newGridKey << "' not found." );
232  }
233  return newGridKey;
234  }
235 
237  static void createPath ( const std::string &path )
238  {
239  if( !createDirectory( path ) )
240  std::cerr << "Failed to create path `" << path << "'." << std::endl;
241  }
242 
244  static std::string createPathName(const std::string& pathPref, int rank )
245  {
246  std::string path(pathPref);
247 
248  // add proc number to path
249  {
250  path += "_";
251  std::stringstream rankDummy;
252  rankDummy << rank;
253  path += rankDummy.str();
254  }
255  return path;
256  }
257 
260  static std::string readPath()
261  {
263  }
264 
266  template <class CommunicatorType>
267  static void createGlobalPath(const CommunicatorType& comm,
268  const std::string& path)
269  {
270  // only rank 0 creates global dir
271  if( comm.rank() <= 0 )
272  {
273  // create directory
274  if( !createDirectory( path ) )
275  std::cerr << "Failed to create path `" << path << "'." << std::endl;
276  }
277 
278  // wait for all procs to arrive here
279  comm.barrier ();
280  }
281 
282  // copy path to filename and add a slash if necessary
283  static std::string copyPathToFilename( const std::string& path )
284  {
285  // first proc creates directory
286  std::string filename( path );
287 
288  const char lastToken = filename.c_str()[ filename.size() - 1 ];
289  const char* slash = "/";
290  // add / if necessary
291  if( lastToken != slash[0] )
292  filename += "/";
293 
294  return filename;
295  }
296 
297  // creates path and processor sub pathes
298  template <class CommunicatorType>
299  static std::string createPath(const CommunicatorType& comm,
300  const std::string& pathPrefix,
301  const std::string& dataPrefix,
302  const int step,
303  const bool alsoCreateRankPath = true )
304  {
305  // first proc creates directory
306  std::string filename( copyPathToFilename( pathPrefix ));
307 
308  filename += dataPrefix;
309  std::string path = generateFilename( filename, step );
310 
311  // create global path
312  createGlobalPath( comm, path );
313 
314  // also create path for each rank
315  if( alsoCreateRankPath )
316  {
317  // append path with p for proc
318  path += "/p";
319 
320  // create path if not exists
321  path = createPathName( path, comm.rank() );
322 
323  // create path if not exits
324  if( !createDirectory( path ) )
325  std::cerr << "Failed to create path `" << path << "'." << std::endl;
326  }
327  return path;
328  }
329 
330  // creates path and processor sub pathes
331  static std::string createRecoverPath(
332  const std::string& pathPrefix,
333  const int rank,
334  const std::string& dataPrefix,
335  const int step,
336  const bool alsoUseRankPath = true )
337  {
338  // first proc creates directory
339  std::string filename( copyPathToFilename( pathPrefix ));
340 
341  filename += dataPrefix;
342  std::string path = generateFilename( filename, step );
343 
344  if( alsoUseRankPath )
345  {
346  // append path with p for proc
347  path += "/p";
348 
349  // create proc dir
350  return createPathName( path , rank );
351  }
352  else
353  return path;
354  }
355 
357  template <class GridImp>
358  static void writeMacroGrid(const GridImp& grid,
359  std::ostream& out,
360  const std::string& macroname,
361  const std::string& path,
362  const std::string& prefix,
363  const bool writeSubFiles = false )
364  {
365  // do nothing if SaveParallelCartesianGrid is not specified
367 
368  // create file descriptor
369  std::ifstream gridin(macroname.c_str());
370  if( !gridin)
371  {
372  std::cerr << "Couldn't open file `" << macroname << "' ! \n";
373  return ;
374  }
375 
376  // read interval information of structured grid
377  dgf::IntervalBlock interval(gridin);
378  if(!interval.isactive())
379  {
380  std::cerr<<"Did not find IntervalBlock in macro grid file `" << macroname << "' ! \n";
381  return;
382  }
383 
384  std::string filename(path);
385  filename += "/";
386  filename += prefix;
387  filename += "_grid";
388 
389  saveCartesianGrid( grid, out, interval, filename, writeSubFiles );
390  return;
391  }
392 
394  template <class GridImp>
395  static void copyMacroGrid(const GridImp& g,
396  const std::string& macroGrid,
397  const std::string& orgPath,
398  const std::string& destPath,
399  const std::string& prefix)
400  {
401  // do nothing if SaveParallelCartesianGrid is not specified
403 
404  if( macroGrid != "" )
405  {
406  std::string destFilename(destPath);
407  destFilename += "/";
408  destFilename += prefix;
409  destFilename += "_grid.macro";
410 
411  std::ofstream file( destFilename.c_str() );
412  if( file.is_open() )
413  file << macroGrid;
414  else
415  {
416  if( Parameter :: verbose () )
417  std::cerr << "Unable to open: '" << destFilename << "'." << std::endl;
418  }
419  }
420  }
421 
422  protected:
424  static std::string strRank(const int rank)
425  {
426  std::stringstream tmp;
427  tmp << "." << rank;
428  return tmp.str();
429  }
430 
431  template <class Grid>
433  {
434  static const bool saveMacroGrid = false ;
435  typedef FieldVector<int, Grid::dimension> iTupel;
436 
437  static void getCoordinates(const Grid&, const iTupel& , iTupel&, iTupel& ,iTupel& )
438  {
439  DUNE_THROW(NotImplemented,"SaveParallelCartesianGrid not implemented for choosen GridType");
440  }
441  };
442 
443  template < int dim, class CoordCont >
444  struct SaveParallelCartesianGrid< YaspGrid< dim, CoordCont > >
445  {
446  static const bool saveMacroGrid = true ;
448  typedef FieldVector<int, dim> iTupel;
449 
450  static void getCoordinates(const Grid& grid, const iTupel& anz,
451  iTupel& origin, iTupel& originInterior,
452  iTupel& lengthInterior )
453  {
454  // Yasp only can do origin = 0
455  origin = 0;
456 
457  enum { tag = Grid::tag };
458  YLoadBalance< dim > loadBalancer;
459  Torus< typename Grid::CollectiveCommunication, dim > torus( grid.comm(), tag, anz, &loadBalancer );
460  torus.partition( torus.rank(), origin, anz, originInterior, lengthInterior );
461  }
462  };
463 
464 #if HAVE_DUNE_SPGRID
465  template< class ct, int dim, template< int > class Strategy, class Comm >
466  struct SaveParallelCartesianGrid< SPGrid< ct, dim, Strategy, Comm > >
467  {
468  static const bool saveMacroGrid = true;
469 
470  typedef SPGrid< ct, dim, Strategy, Comm > Grid;
471  typedef FieldVector< int, dim > iTupel;
472 
473  static void getCoordinates( const Grid &grid, const iTupel &anz,
474  iTupel &origin, iTupel &originInterior,
475  iTupel &lengthInterior )
476  {
477 #if HAVE_MPI
478  typedef typename Grid::MultiIndex MultiIndex;
479  const MultiIndex begin = grid.gridLevel( 0 ).localCube().begin();
480  const MultiIndex end = grid.gridLevel( 0 ).localCube().end();
481  for( int i = 0; i < dim; ++i )
482  {
483  originInterior[ i ] = begin[ i ];
484  lengthInterior[ i ] = end[ i ] - begin[ i ];
485  }
486 #endif // #if HAVE_MPI
487  }
488  };
489 #endif // #if HAVE_DUNE_SPGRID
490 
492  template <class GridImp>
493  static void saveCartesianGrid (const GridImp& grid,
494  std::ostream& out,
495  dgf::IntervalBlock& intervalBlock,
496  std::string filename,
497  const bool writeSubFiles )
498  {
499  enum { dimension = GridImp :: dimension };
500  const int rank = grid.comm().rank();
501 
502  FieldVector<double,dimension> lang;
503  FieldVector<int,dimension> anz;
504  FieldVector<double,dimension> h;
505  FieldVector<int,dimension> orig;
506 
507  if( intervalBlock.numIntervals() != 1 )
508  {
509  std::cerr << "Warning: Only 1 interval block is handled by "
510  << "IOInterface::saveMacroGridImp" << std::endl;
511  }
512 
513  typedef typename dgf::IntervalBlock::Interval Interval;
514  const Interval &interval = intervalBlock.get( 0 );
515  for( int i = 0; i < dimension; ++i )
516  {
517  orig[ i ] = interval.p[ 0 ][ i ];
518  lang[ i ] = interval.p[ 1 ][ i ] - interval.p[ 0 ][ i ];
519  anz[ i ] = interval.n[ i ];
520  h[ i ] = lang[ i ] / anz[ i ];
521  }
522 
523  // write sub grid for this rank
524  {
525  std::string subfilename;
526  if( writeSubFiles )
527  {
528  subfilename = filename;
529  // add rank
530  subfilename += strRank(rank);
531  }
532 
533 #if HAVE_MPI
534  {
535  typedef FieldVector<int,dimension> iTupel;
536 
537  // origin is zero
538  iTupel o( orig );
539 
540  iTupel o_interior;
541  iTupel s_interior;
542 
544  getCoordinates( grid, anz, o, o_interior, s_interior );
545 
546  FieldVector<double,dimension> origin;
547  for(int i=0; i<dimension; ++i)
548  origin[ i ] = o[ i ];
549 
550  FieldVector<double,dimension> sublang(0.0);
551  for(int i=0; i<dimension; ++i)
552  {
553  origin[i] = o_interior[i] * h[i];
554  sublang[i] = origin[i] + (s_interior[i] * h[i]);
555  }
556 
557  writeStructuredGrid(subfilename,out,origin,sublang,s_interior);
558  }
559 #else
560  {
561  // in serial this should be zero
562  assert( rank == 0 );
563  FieldVector<double,dimension> zero(0.0);
564  writeStructuredGrid(subfilename,out,zero,lang,anz);
565  }
566 #endif
567  }
568 
569  // write global grid on rank 0
570  if (rank == 0 )
571  {
572  // write global file for recovery
573  filename += ".global";
574  FieldVector<double,dimension> zero(0.0);
575  std::stringstream dummy;
576  writeStructuredGrid(filename,dummy,zero,lang,anz);
577  }
578  }
579 
580  template <int dimension>
581  static void writeToStream(std::ostream& file,
582  const FieldVector<double,dimension>& origin,
583  const FieldVector<double,dimension>& lang,
584  const FieldVector<int,dimension>& anz)
585  {
586  file << "DGF" << std::endl;
587  file << "Interval" << std::endl;
588  // write first point
589  for(int i=0;i<dimension; ++i)
590  {
591  file << origin[i] << " ";
592  }
593  file << std::endl;
594  // write second point
595  for(int i=0;i<dimension; ++i)
596  {
597  file << lang[i] << " ";
598  }
599  file << std::endl;
600  // write number of intervals in each direction
601  for(int i=0;i<dimension; ++i)
602  {
603  file << anz[i] << " ";
604  }
605  file << std::endl;
606  file << "#" << std::endl;
607 
608  file << "BoundaryDomain" << std::endl;
609  file << "default 1" << std::endl;
610  file << "#" << std::endl;
611  }
612 
614  template <int dimension>
615  static void writeStructuredGrid(const std::string& filename,
616  std::ostream& out,
617  const FieldVector<double,dimension>& origin,
618  const FieldVector<double,dimension>& lang,
619  const FieldVector<int,dimension>& anz)
620  {
621  writeToStream( out, origin, lang, anz);
622 
623  if( filename != "" )
624  {
625  std::ofstream file (filename.c_str());
626  if( file.is_open())
627  {
628  writeToStream( file, origin, lang, anz);
629  }
630  else
631  {
632  std::cerr << "Couldn't open file `" << filename << "' !\n";
633  }
634  }
635  }
636  }; // end class IOInterface
637 
638  } // end namespace Fem
639 
640 } // end namespace Dune
641 #endif // #ifndef DUNE_FEM_IOINTERFACE_HH
std::string path
Definition: readioparams.cc:156
Definition: bindguard.hh:11
bool createDirectory(const std::string &inName)
create a directory
Definition: io.cc:19
std::string generateFilename(const std::string &fn, int ntime, int precision=6)
Definition: iointerface.hh:47
IOInterface to write data to hard disk.
Definition: iointerface.hh:161
static void copyMacroGrid(const GridImp &g, const std::string &macroGrid, const std::string &orgPath, const std::string &destPath, const std::string &prefix)
if grid is structured grid, write macro file
Definition: iointerface.hh:395
static std::string strRank(const int rank)
create string containing rank
Definition: iointerface.hh:424
static void createGlobalPath(const CommunicatorType &comm, const std::string &path)
create global path for data output
Definition: iointerface.hh:267
static std::string createRecoverPath(const std::string &pathPrefix, const int rank, const std::string &dataPrefix, const int step, const bool alsoUseRankPath=true)
Definition: iointerface.hh:331
static std::string createPath(const CommunicatorType &comm, const std::string &pathPrefix, const std::string &dataPrefix, const int step, const bool alsoCreateRankPath=true)
Definition: iointerface.hh:299
static std::string defaultGridKey(int dimension, const ParameterReader &parameter, bool check=true)
Definition: iointerface.hh:191
static std::string defaultGridKey(int dimension, bool check=true)
return FEM key for macro grid reading
Definition: iointerface.hh:186
static void saveCartesianGrid(const GridImp &grid, std::ostream &out, dgf::IntervalBlock &intervalBlock, std::string filename, const bool writeSubFiles)
write my partition as macro grid
Definition: iointerface.hh:493
static void createPath(const std::string &path)
create given path in combination with rank
Definition: iointerface.hh:237
virtual void writeData(double sequenceStamp) const =0
write data with a given sequence stamp
virtual void write() const =0
write given data to disc, evaluates parameter savecount
static void writeToStream(std::ostream &file, const FieldVector< double, dimension > &origin, const FieldVector< double, dimension > &lang, const FieldVector< int, dimension > &anz)
Definition: iointerface.hh:581
virtual ~IOInterface()
destructor
Definition: iointerface.hh:169
static std::string readPath()
Definition: iointerface.hh:260
static std::string defaultGridKey(std::string base, int dimension, bool check=true)
Definition: iointerface.hh:196
virtual void write(const TimeProviderBase &tp) const =0
write given data to disc, evaluates parameter savecount and savestep
static std::string defaultGridKey(std::string base, int dimension, const ParameterReader &parameter, bool check=true)
return FEM key for macro grid reading
Definition: iointerface.hh:202
static std::string copyPathToFilename(const std::string &path)
Definition: iointerface.hh:283
static void writeStructuredGrid(const std::string &filename, std::ostream &out, const FieldVector< double, dimension > &origin, const FieldVector< double, dimension > &lang, const FieldVector< int, dimension > &anz)
write structured grid as DGF file
Definition: iointerface.hh:615
static std::string createPathName(const std::string &pathPref, int rank)
create given path in combination with rank
Definition: iointerface.hh:244
static void writeMacroGrid(const GridImp &grid, std::ostream &out, const std::string &macroname, const std::string &path, const std::string &prefix, const bool writeSubFiles=false)
if grid is structured grid, write macro file
Definition: iointerface.hh:358
IOInterface()
default constructor
Definition: iointerface.hh:165
FieldVector< int, Grid::dimension > iTupel
Definition: iointerface.hh:435
static void getCoordinates(const Grid &, const iTupel &, iTupel &, iTupel &, iTupel &)
Definition: iointerface.hh:437
static const bool saveMacroGrid
Definition: iointerface.hh:434
FieldVector< int, dim > iTupel
Definition: iointerface.hh:448
static void getCoordinates(const Grid &grid, const iTupel &anz, iTupel &origin, iTupel &originInterior, iTupel &lengthInterior)
Definition: iointerface.hh:450
YaspGrid< dim, CoordCont > Grid
Definition: iointerface.hh:447
Definition: io/parameter/exceptions.hh:17
bool exists(const std::string &key) const
check, whether a parameter is defined
Definition: reader.hh:44
static bool verbose()
obtain the cached value for fem.verbose
Definition: io/parameter.hh:445
static std::string commonOutputPath()
obtain common output path
Definition: io/parameter.hh:411
static ParameterContainer & container()
Definition: io/parameter.hh:193
Definition: griddeclaration.hh:36
general base for time providers
Definition: timeprovider.hh:36