dune-fem 2.8.0
Loading...
Searching...
No Matches
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
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
38namespace 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
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
static ParameterContainer & container()
Definition: io/parameter.hh:193
static std::string commonOutputPath()
obtain common output path
Definition: io/parameter.hh:411
Definition: io/parameter/exceptions.hh:17
bool exists(const std::string &key) const
check, whether a parameter is defined
Definition: reader.hh:44
Definition: griddeclaration.hh:36
general base for time providers
Definition: timeprovider.hh:36