DUNE-FEM (unstable)

dataoutput.hh
1#ifndef DUNE_FEM_DATAOUTPUT_HH
2#define DUNE_FEM_DATAOUTPUT_HH
3
4#include <fstream>
5#include <iostream>
6#include <limits>
7#include <memory>
8#include <string>
9#include <type_traits>
10#include <tuple>
11#include <utility>
12#include <vector>
13
14#ifndef USE_VTKWRITER
15#define USE_VTKWRITER 1
16#endif
17
18#include <dune/common/hybridutilities.hh>
20
21#include <dune/fem/common/utility.hh>
22#include <dune/fem/function/adaptivefunction.hh>
23#include <dune/fem/gridpart/adaptiveleafgridpart.hh>
24#include <dune/fem/io/file/iointerface.hh>
25#include <dune/fem/io/file/iotuple.hh>
26#include <dune/fem/io/file/vtkio.hh>
27#include <dune/fem/io/parameter.hh>
28#include <dune/fem/operator/projection/vtxprojection.hh>
29#include <dune/fem/quadrature/cachingquadrature.hh>
30#include <dune/fem/solver/timeprovider.hh>
31#include <dune/fem/space/common/loadbalancer.hh>
32#include <dune/fem/space/common/interpolate.hh>
33#include <dune/fem/gridpart/adaptiveleafgridpart.hh>
34#include <dune/fem/space/lagrange.hh>
35
36#ifndef ENABLE_VTXPROJECTION
37#define ENABLE_VTXPROJECTION 1
38#endif
39
40#if USE_VTKWRITER
41#include <dune/fem/io/file/vtkio.hh>
42#if ENABLE_VTXPROJECTION
43#include <dune/fem/operator/projection/vtxprojection.hh>
44#endif // #if ENABLE_VTXPROJECTION
45#endif // #if USE_VTKWRITER
46
47#ifndef USE_GRAPE
48#define USE_GRAPE HAVE_GRAPE
49#endif
50
51#if USE_GRAPE
52#include <dune/grid/io/visual/grapedatadisplay.hh>
53#endif
54
55namespace Dune
56{
57
58 namespace Fem
59 {
60
70#ifndef DOXYGEN
71 : public LocalParameter< DataOutputParameters, DataOutputParameters >
72#endif
73 {
74 protected:
75 const std::string keyPrefix_;
76 ParameterReader parameter_;
77
78 public:
79 explicit DataOutputParameters ( std::string keyPrefix, const ParameterReader &parameter = Parameter::container() )
80 : keyPrefix_( std::move( keyPrefix ) ), parameter_( parameter )
81 {}
82
83 explicit DataOutputParameters ( const ParameterReader &parameter = Parameter::container() )
84 : keyPrefix_( "fem.io." ), parameter_( parameter )
85 {}
86
88 virtual std::string path() const
89 {
90 return parameter().getValue< std::string >( keyPrefix_ + "path", "./" );
91 }
92
93 virtual std::string absolutePath () const
94 {
95 std::string absPath = parameter().getValue< std::string >( "fem.prefix", "." ) + "/";
96 const std::string relPath = path();
97 if( relPath != "./" )
98 absPath += relPath;
99 return absPath;
100 }
101
103 virtual std::string prefix () const
104 {
105 return parameter().getValue< std::string >( keyPrefix_ + "datafileprefix", "" );
106 }
107
109 virtual int outputformat () const
110 {
111 static const std::string formatTable[]
112 = { "vtk-cell", "vtk-vertex", "sub-vtk-cell", "binary" , "gnuplot" , "none" };
113 int format = parameter().getEnum( keyPrefix_ + "outputformat", formatTable, 0 );
114 return format;
115 }
116
117 virtual bool conformingoutput () const
118 {
119 return parameter().getValue< bool >( keyPrefix_ + "conforming", false );
120 }
121
123 virtual bool grapedisplay () const
124 {
125#if USE_GRAPE
126 return (parameter().getValue( keyPrefix_ + "grapedisplay", 0 ) == 1);
127#else
128 return false;
129#endif
130 }
131
133 virtual double savestep () const
134 {
135 return parameter().getValue< double >( keyPrefix_ + "savestep", 0 );
136 }
137
139 virtual int savecount () const
140 {
141 return parameter().getValue< int >( keyPrefix_ + "savecount", 0 );
142 }
143
145 virtual int subsamplingLevel() const
146 {
147 return parameter().getValue< int >( keyPrefix_ + "subsamplinglevel", 1 );
148 }
149
151 virtual int startcounter () const
152 {
153 return 0;
154 }
155
157 virtual int startcall () const
158 {
159 return 0;
160 }
161
163 virtual double startsavetime () const
164 {
165 return 0.0;
166 }
167
170 virtual bool willWrite ( bool write ) const
171 {
172 return write;
173 }
174
177 virtual bool writeMode() const
178 {
179 return true ;
180 }
181
182 const ParameterReader &parameter () const noexcept { return parameter_; }
183 };
184
185
186
194 template< class GridImp, class DataImp >
196 : public IOInterface
197 {
199
200#if USE_VTKWRITER
201 template< class VTKIOType >
202 struct VTKListEntry
203 {
204 virtual ~VTKListEntry ()
205 {}
206 virtual void add ( VTKIOType & ) const = 0;
207
208 protected:
209 VTKListEntry ()
210 {}
211 };
212
213#if ENABLE_VTXPROJECTION
214 template< class VTKIOType, class DFType >
215 class VTKFunc;
216
217 template< class VTKOut >
218 struct VTKOutputerLagrange;
219#endif // #if ENABLE_VTXPROJECTION
220
221 template< class VTKOut >
222 struct VTKOutputerDG;
223#endif // #if USE_VTKWRITER
224
225 template< class GridPartType >
226 class GnuplotOutputer;
227
228 struct FileWriter
229 {
230 FileWriter ( std::string name )
231 : file_( name )
232 {
233 if( !file_ )
234 std::cout << "could not write file: " << name << std::endl;
235 }
236
237 void operator() ( const std::string &s ) { file_ << s << std::endl; }
238
239 protected:
240 std::ofstream file_;
241 };
242
243 struct PVDWriter
244 : public FileWriter
245 {
246 PVDWriter ( std::string name )
247 : FileWriter( name )
248 {
249 file_ << "<?xml version=\"1.0\"?>" << std::endl;
250 file_ << "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">" << std::endl;
251 file_ << " <Collection>" << std::endl;
252 }
253
254 ~PVDWriter ()
255 {
256 file_ << " </Collection>" << std::endl;
257 file_ << "</VTKFile>" << std::endl;
258 }
259
260 void operator() ( double sequenceStamp, std::string filename )
261 {
262 // cH: only use the basename of filename, Paraview will
263 // prepend the leading path correctly, if the pvd-file
264 // resides in the same directory as the data files.
265 auto pos = filename.find_last_of( '/' );
266 if( pos != filename.npos )
267 filename = filename.substr( pos+1, filename.npos );
268 static_cast< FileWriter & >( *this )( " <DataSet timestep=\"" + std::to_string( sequenceStamp ) + "\" group=\"\" part=\"0\" file=\"" + filename + "\"/>" );
269 }
270
271 private:
272 std::ofstream file_;
273 };
274
275 public:
276 enum OutputFormat { vtk = 0, vtkvtx = 1, subvtk = 2 , binary = 3, gnuplot = 4, none = 5 };
277
279 typedef GridImp GridType;
281 typedef DataImp OutPutDataType;
282
283 public:
290 DataOutput ( const GridType &grid, OutPutDataType &data, std::unique_ptr< const DataOutputParameters > parameters );
291
298 DataOutput ( const GridType &grid, OutPutDataType &data, const DataOutputParameters &parameter )
299 : DataOutput( grid, data, std::unique_ptr< const DataOutputParameters >( parameter.clone() ) )
300 {}
301
302 DataOutput ( const GridType &grid, OutPutDataType &data, const ParameterReader &parameter = Parameter::container() )
303 : DataOutput( grid, data, DataOutputParameters( parameter ) )
304 {}
305
313 DataOutput ( const GridType &grid, OutPutDataType &data, const TimeProviderBase &tp, std::unique_ptr< const DataOutputParameters > parameters )
314 : DataOutput( grid, data, std::move( parameters ) )
315 {
316 consistentSaveStep( tp );
317 }
318
326 DataOutput ( const GridType &grid, OutPutDataType &data, const TimeProviderBase &tp, const DataOutputParameters &parameter )
327 : DataOutput( grid, data, tp, std::unique_ptr< const DataOutputParameters >( parameter.clone() ) )
328 {}
329
330 DataOutput ( const GridType &grid, OutPutDataType &data, const TimeProviderBase &tp, const ParameterReader &parameter = Parameter::container() )
331 : DataOutput( grid, data, tp, DataOutputParameters( parameter ) )
332 {}
333
334 void consistentSaveStep ( const TimeProviderBase &tp ) const;
335
336 public:
338 virtual bool willWrite ( const TimeProviderBase &tp ) const
339 {
340 // make save step consistent
341 consistentSaveStep( tp );
342
343 const double saveTimeEps = 2*std::numeric_limits< double >::epsilon()*saveTime_;
344 const bool writeStep = (saveStep_ > 0) && (tp.time() - saveTime_ >= -saveTimeEps);
345 const bool writeCount = (saveCount_ > 0) && (writeCalls_ % saveCount_ == 0);
346 return param_->willWrite( writeStep || writeCount );
347 }
348
350 virtual bool willWrite () const
351 {
352 return param_->willWrite( (saveCount_ > 0) && (writeCalls_ % saveCount_ == 0) );
353 }
354
358 void write( const std::string& outstring ) const
359 {
360 if( willWrite() )
361 writeData( writeCalls_, outstring );
362 ++writeCalls_;
363 }
364
366 void write() const
367 {
368 if( willWrite() )
369 writeData( writeCalls_, "" );
370 ++writeCalls_;
371 }
372
377 void write(const TimeProviderBase& tp, const std::string& outstring ) const
378 {
379 if( willWrite(tp) )
380 writeData( tp.time(), outstring );
381 ++writeCalls_;
382 }
383
387 void write( const TimeProviderBase& tp ) const
388 {
389 write( tp, "" );
390 }
391
396 void writeData ( double sequenceStamp, const std::string &outstring ) const;
397
401 void writeData ( double sequenceStamp ) const
402 {
403 writeData( sequenceStamp, "" );
404 }
405
407 virtual const char* myClassName () const
408 {
409 return "DataOutput";
410 }
411
413 const std::string &path () const
414 {
415 return path_;
416 }
417
419 int writeStep() const
420 {
421 return writeStep_;
422 }
423
425 int writeCalls() const
426 {
427 return writeCalls_;
428 }
429
431 double saveTime() const
432 {
433 return saveTime_;
434 }
435
436 protected:
437 auto getGridPart() const
438 {
439 static constexpr bool isNotEmpty = std::tuple_size< DataImp >::value > 0;
440 return getGridPart( std::integral_constant< bool, isNotEmpty > () );
441 }
442
443 auto getGridPart( std::integral_constant< bool, false > ) const
444 {
445 typedef Dune::Fem::LeafGridPart< GridType > GridPartType;
446 return GridPartType( const_cast<GridType&> (grid_) );
447 }
448
449 auto getGridPart( std::integral_constant< bool, true > ) const
450 {
451 return std::get< 0 >( data_ )->gridPart();
452 }
453
454#if USE_VTKWRITER
455 std::string writeVTKOutput () const;
456#endif
457
458 std::string writeGnuPlotOutput () const;
459
461 virtual void writeBinaryData ( const double ) const
462 {
463 DUNE_THROW(NotImplemented, "Format 'binary' not supported by DataOutput, use DataWriter instead." );
464 }
465
467 virtual void display () const
468 {
469 if( grapeDisplay_ )
470 grapeDisplay( data_ );
471 }
472
474 template< class OutputTupleType >
475 void grapeDisplay ( OutputTupleType &data ) const;
476
479 OutPutDataType data_;
480
481 // name for data output
482 std::string path_;
483 std::string datapref_;
484 // use grape display
485 bool grapeDisplay_;
486
487 // counter for sequence of files
488 mutable int writeStep_;
489 // counter for call to write
490 mutable int writeCalls_;
491 // next point in time to save data
492 mutable double saveTime_;
493 // time interval to save files
494 double saveStep_;
495 // number of write call between writting files
496 int saveCount_;
497 // grape, vtk or ...
498 OutputFormat outputFormat_;
499 bool conformingOutput_;
500 std::unique_ptr< FileWriter > sequence_;
501 std::unique_ptr< PVDWriter > pvd_;
502 std::unique_ptr< const DataOutputParameters > param_;
503 };
504
505
506
507 // DataOutput::VTKFunc
508 // -------------------
509
510#if USE_VTKWRITER
511#if ENABLE_VTXPROJECTION
512 template< class GridImp, class DataImp >
513 template< class VTKIOType, class DFType >
514 class DataOutput< GridImp, DataImp >::VTKFunc
515 : public VTKListEntry< VTKIOType >
516 {
517 typedef typename VTKIOType::GridPartType GridPartType;
518 typedef typename DFType::FunctionSpaceType FunctionSpaceType;
519
521 typedef AdaptiveDiscreteFunction< LagrangeSpaceType > NewFunctionType;
522
523 public:
524 VTKFunc ( const GridPartType &gridPart, const DFType &df )
525 : df_( df ),
526 space_( const_cast< GridPartType & >( gridPart ) )
527 {}
528
529 virtual void add ( VTKIOType &vtkio ) const
530 {
531 func_.reset( new NewFunctionType( df_.name()+"vtx-prj" , space_ ) );
532 if( df_.continuous() )
533 {
534 interpolate( df_, *func_ );
535 }
536 else
537 {
538 WeightDefault<GridPartType> weight;
539 VtxProjectionImpl::project( df_, *func_, weight );
540 }
541 vtkio.addVertexData( *func_ );
542 }
543
544 VTKFunc ( const VTKFunc & ) = delete;
545
546 private:
547 const DFType& df_;
548 LagrangeSpaceType space_;
549 mutable std::unique_ptr<NewFunctionType> func_;
550 };
551#endif // #if ENABLE_VTXPROJECTION
552#endif // #if USE_VTKWRITER
553
554
555
556 // DataOutput::VTKOutputerDG
557 // -------------------------
558
559#if USE_VTKWRITER
560 template< class GridImp, class DataImp >
561 template< class VTKOut >
562 struct DataOutput< GridImp, DataImp >::VTKOutputerDG
563 {
564 template< class... Args >
565 explicit VTKOutputerDG ( bool conforming, Args &&... args )
566 : conforming_( conforming ), vtkOut_( std::forward< Args >( args )... )
567 {}
568
569 template< typename ... T >
570 void forEach ( const std::tuple< T ... >& data )
571 {
572 Hybrid::forEach( std::make_index_sequence< sizeof...( T ) >{},
573 [&]( auto i ) {
574 auto df( std::get< i >( data ) );
575 if( df )
576 {
577 if( conforming_ || ( df->order() == 0 ) )
578 vtkOut_.addCellData( *df );
579 else
580 vtkOut_.addVertexData( *df );
581 }
582 });
583 }
584
585 template< typename T >
586 void forEach ( const T& data )
587 {
588 std::tuple< T > tup( data );
589 forEach( tup );
590 }
591
592 std::string write ( bool parallel, const std::string &name, const std::string &path )
593 {
594 return (parallel ? vtkOut_.pwrite( name, path, "." ) : vtkOut_.write( name ));
595 }
596
597 private:
598 bool conforming_;
599 VTKOut vtkOut_;
600 };
601#endif // #if USE_VTKWRITER
602
603
604
605 // DataOutput::VTKOutputerLagrange
606 // -------------------------------
607
608#if USE_VTKWRITER
609#if ENABLE_VTXPROJECTION
610 template< class GridImp, class DataImp >
611 template< class VTKOut >
612 struct DataOutput< GridImp, DataImp >::VTKOutputerLagrange
613 {
615 template< class... Args >
616 explicit VTKOutputerLagrange ( Args &&... args )
617 : vtkOut_( std::forward< Args >( args )... )
618 {}
619
620 template< typename ... T >
621 void forEach ( const std::tuple< T ... >& data )
622 {
623 Hybrid::forEach( std::make_index_sequence< sizeof...( T ) >{},
624 [&]( auto i ) {
625 auto df( std::get< i >( data ) );
626 if( df )
627 {
628 typedef typename std::remove_pointer< decltype( df ) >::type DFType;
629 vec_.emplace_back( new VTKFunc< VTKOut, DFType >( vtkOut_.gridPart(), *df ) );
630 vec_.back()->add( vtkOut_ );
631 }
632 });
633 }
634
635 template< typename T >
636 void forEach ( const T& data )
637 {
638 std::tuple< T > tup( data );
639 forEach( tup );
640 }
641
642 std::string write ( bool parallel, const std::string &name, const std::string &path )
643 {
644 return (parallel ? vtkOut_.pwrite( name, path, "." ) : vtkOut_.write( name ));
645 }
646
647 private:
648 std::vector< std::unique_ptr< VTKListEntry< VTKOut > > > vec_;
649 VTKOut vtkOut_;
650 };
651#endif // #if ENABLE_VTXPROJECTION
652#endif // #if USE_VTKWRITER
653
654
655
656 // DataOutput::GnuplotOutputer
657 // ---------------------------
658 template< class GridImp, class DataImp >
659 template< class GridPartType >
660 class DataOutput< GridImp, DataImp >::GnuplotOutputer
661 {
662 typedef typename GridPartType::template Codim< 0 >::IteratorType::Entity Entity;
663 std::ostream& out_;
664 CachingQuadrature<GridPartType,0> &quad_;
665 int i_;
666 const Entity& en_;
667
668 public:
670 GnuplotOutputer ( std::ostream& out,
671 CachingQuadrature<GridPartType,0> &quad,
672 int i,
673 const Entity &en )
674 : out_(out), quad_(quad), i_(i), en_(en)
675 {}
676
677 template< typename ... T >
678 void forEach ( const std::tuple< T ... >& data )
679 {
680 Hybrid::forEach( std::make_index_sequence< sizeof...( T ) >{},
681 [&]( auto i ) {
682 auto df( std::get< i >( data ));
683 if( df )
684 {
685 ConstLocalFunction<std::decay_t<decltype(*df)> > lf(*df);
686 lf.bind(en_);
687 typedef typename std::remove_pointer< decltype( df ) >::type DFType;
688 typename DFType::FunctionSpaceType::RangeType u;
689 lf.evaluate( quad_[ i_ ], u );
690
691 constexpr int dimRange = DFType::FunctionSpaceType::dimRange;
692 for( auto k = 0; k < dimRange; ++k )
693 out_ << " " << u[ k ];
694 lf.unbind();
695 }
696 });
697 }
698
699 template< typename T >
700 void forEach ( const T& data )
701 {
702 std::tuple< T > tup( data );
703 forEach( tup );
704 }
705
706 };
707
708
709
710 // Implementation of DataOutput
711 // ----------------------------
712 template< class GridImp, class DataImp >
715 std::unique_ptr< const DataOutputParameters > parameters )
716 : grid_( grid ),
717 data_( data ),
718 writeStep_(0),
719 writeCalls_(0),
720 saveTime_(0),
721 saveStep_(-1),
722 saveCount_(-1),
723 outputFormat_(vtkvtx),
724 conformingOutput_( false ),
725 param_( std::move( parameters ) )
726 {
727 const bool writeMode = param_->writeMode();
728 path_ = param_->absolutePath();
729
730 // create path if not already exists
731 if( writeMode )
732 IOInterface :: createGlobalPath ( grid_.comm(), path_ );
733
734 // add prefix for data file
735 datapref_ += param_->prefix();
736
737 auto outputFormat = param_->outputformat();
738 switch( outputFormat )
739 {
740 case 0: outputFormat_ = vtk; break;
741 case 1: outputFormat_ = vtkvtx; break;
742 case 2: outputFormat_ = subvtk; break;
743 case 3: outputFormat_ = binary; break;
744 case 4: outputFormat_ = gnuplot; break;
745 case 5: outputFormat_ = none; break;
746 default:
747 DUNE_THROW(NotImplemented,"DataOutput::init: wrong output format");
748 }
749
750 conformingOutput_ = param_->conformingoutput();
751
752 grapeDisplay_ = param_->grapedisplay();
753
754 // get parameters for data writing
755 saveStep_ = param_->savestep();
756 saveCount_ = param_->savecount();
757
758 // set initial quantities
759 writeStep_ = param_->startcounter();
760 writeCalls_ = param_->startcall();
761 saveTime_ = param_->startsavetime();
762
763 if( writeMode )
764 {
765 // only write series file for VTK output
766 if ( Parameter :: verbose() && outputFormat_ < binary )
767 {
768 sequence_.reset( new FileWriter( path_ + "/" + datapref_ + ".series" ) );
769 pvd_.reset( new PVDWriter( path_ + "/" + datapref_ + ".pvd" ) );
770 }
771
772 // write parameter file
773 Parameter::write("parameter.log");
774 }
775 }
776
777
778 template< class GridImp, class DataImp >
780 ::consistentSaveStep ( const TimeProviderBase &tp ) const
781 {
782 // set old values according to new time
783 if( saveStep_ > 0 )
784 {
785 const auto oldTime = tp.time() - saveStep_;
786 while( saveTime_ <= oldTime )
787 {
788 ++writeStep_;
789 saveTime_ += saveStep_;
790 }
791 }
792 }
793
794
795 template< class GridImp, class DataImp >
797 ::writeData ( double sequenceStamp, const std::string &outstring ) const
798 {
799 std::string filename;
800 // check online display
801 display();
802 switch( outputFormat_ )
803 {
804 // if no output was chosen just return
805 case none: break ;
806 case binary: writeBinaryData( sequenceStamp ); break;
807 case vtk :
808 case vtkvtx :
809 case subvtk :
810#if USE_VTKWRITER
811 // write data in vtk output format
812 filename = writeVTKOutput();
813 break;
814#else
815 DUNE_THROW(NotImplemented,"DataOutput::write: VTKWriter was disabled by USE_VTKWRITER 0");
816#endif // #if USE_VTKWRITER
817 case gnuplot : filename = writeGnuPlotOutput(); break;
818 default:
819 DUNE_THROW(NotImplemented,"DataOutput::write: wrong output format = " << outputFormat_);
820 }
821
822 if( outputFormat_ != none )
823 {
824 if( sequence_ )
825 (*sequence_)( std::to_string( writeStep_ ) + " " + filename + " " + std::to_string( sequenceStamp ) + outstring );
826
827 if( pvd_ )
828 (*pvd_)( sequenceStamp, filename );
829
830 if( Parameter::verbose() )
831 {
832 // only write info for proc 0, otherwise on large number of procs
833 // this is to much output
834 std::cout << myClassName() << "[" << grid_.comm().rank() << "]::write data"
835 << " writestep=" << writeStep_
836 << " sequenceStamp=" << sequenceStamp
837 << outstring
838 << std::endl;
839 }
840 }
841
842 saveTime_ += saveStep_;
843 ++writeStep_;
844 }
845
846#if USE_VTKWRITER
847 template< class GridImp, class DataImp >
848 inline std::string DataOutput< GridImp, DataImp >::writeVTKOutput () const
849 {
850 std::string filename;
851 // check whether to use vertex data of discontinuous data
852 const bool vertexData = (outputFormat_ == vtkvtx);
853
854 // check whether we have parallel run
855 const bool parallel = (grid_.comm().size() > 1);
856
857 // generate filename, with path only for serial run
858 auto name = generateFilename( (parallel ? datapref_ : path_ + "/" + datapref_ ), writeStep_ );
859
860 // get GridPart
861 const auto& gridPart = getGridPart();
862 typedef typename std::decay< decltype( gridPart ) >::type GridPartType;
863
864 if( vertexData )
865 {
866#if ENABLE_VTXPROJECTION
867 // create vtk output handler
868 VTKOutputerLagrange< VTKIO< GridPartType > > io( gridPart, VTK::conforming, param_->parameter() );
869
870 // add all functions
871 io.forEach( data_ );
872
873 // write all data
874 filename = io.write( parallel, name, path_ );
875#endif
876 }
877 else if ( outputFormat_ == vtk )
878 {
879 // create vtk output handler
880 VTKOutputerDG< VTKIO< GridPartType > > io( conformingOutput_, gridPart, conformingOutput_ ? VTK::conforming : VTK::nonconforming, param_->parameter() );
881
882 // add all functions
883 io.forEach( data_ );
884
885 // write all data
886 filename = io.write( parallel, name, path_ );
887 }
888 else if ( outputFormat_ == subvtk )
889 {
890 // create vtk output handler
891 VTKOutputerDG< SubsamplingVTKIO < GridPartType > > io( conformingOutput_, gridPart, static_cast< unsigned int >( param_->subsamplingLevel() ), param_->parameter() );
892
893 // add all functions
894 io.forEach( data_ );
895
896 // write all data
897 filename = io.write( parallel, name, path_ );
898 }
899 return filename;
900 }
901#endif // #if USE_VTKWRITER
902
903
904 template< class GridImp, class DataImp >
905 inline std::string DataOutput< GridImp, DataImp >::writeGnuPlotOutput () const
906 {
907 // generate filename
908 auto name = generateFilename( path_ + "/" + datapref_, writeStep_ );
909 name += ".gnu";
910 std::ofstream gnuout(name.c_str());
911 gnuout << std::scientific << std::setprecision( 16 );
912
913 // start iteration
914 const auto& gridPart = getGridPart();
915 typedef typename std::decay< decltype( gridPart ) >::type GridPartType;
916 for( const auto& entity : elements( gridPart ) )
917 {
918 CachingQuadrature< GridPartType, 0 > quad( entity, 1 );
919 for( decltype(quad.nop()) i = 0; i < quad.nop(); ++i )
920 {
921 const auto x = entity.geometry().global( quad.point( i ) );
922 for( auto k = 0; k < x.dimension; ++k )
923 gnuout << (k > 0 ? " " : "") << x[ k ];
924 GnuplotOutputer< GridPartType > io( gnuout, quad, i, entity );
925 io.forEach( data_ );
926 gnuout << std::endl;
927 }
928 }
929 return name;
930 }
931
932
933#if USE_GRAPE
934 template< class GridImp, class DataImp >
935 template< class OutputTupleType >
936 inline void DataOutput< GridImp, DataImp >::grapeDisplay ( OutputTupleType &data ) const
937 {
938 GrapeDataDisplay<GridType> grape(grid_);
939 IOTuple<OutPutDataType>::addToDisplay(grape,data);
940 grape.display();
941 }
942#else
943 template< class GridImp, class DataImp >
944 template< class OutputTupleType >
945 inline void DataOutput< GridImp, DataImp >::grapeDisplay ( OutputTupleType &data ) const
946 {
947 std::cerr << "WARNING: HAVE_GRAPE == 0, but grapeDisplay == true, recompile with grape support for online display!" << std::endl;
948 }
949#endif
950
951
952
953 namespace Impl
954 {
955
956 // makeIOTuple
957 // -----------
958
959 template< class DF >
960 inline static auto makeSingleIOTuple ( DF &&df, PriorityTag< 1 > )
961 -> std::enable_if_t< std::is_reference< DF >::value && std::is_base_of< Fem::HasLocalFunction, std::decay_t< DF > >::value,
962 std::tuple< std::decay_t< DF > * > >
963 {
964 return std::make_tuple( &df );
965 }
966
967 template< class DF >
968 inline static auto makeSingleIOTuple ( DF &&df, PriorityTag< 0 > )
969 -> std::tuple<>
970 {
971 return {};
972 }
973
974 template< class... Args >
975 inline static auto makeIOTuple ( Args &&... args )
976 {
977 return std::tuple_cat( makeSingleIOTuple( std::forward< Args >( args ), PriorityTag< 42 >() )... );
978 }
979
980
981
982 // getDataOutputParameters
983 // -----------------------
984
985 inline static auto getSingleDataOutputParameters ( std::unique_ptr< const DataOutputParameters > parameters )
986 {
987 return std::make_tuple( std::move( parameters ) );
988 }
989
990 inline static auto getSingleDataOutputParameters ( const DataOutputParameters &parameters )
991 {
992 return std::make_tuple( std::unique_ptr< const DataOutputParameters >( parameters.clone() ) );
993 }
994
995 inline static auto getSingleDataOutputParameters ( const ParameterReader &parameter )
996 {
997 return std::make_tuple( std::make_unique< const DataOutputParameters >( parameter ) );
998 }
999
1000 template< class Arg >
1001 inline static auto getSingleDataOutputParameters ( Arg &&arg, PriorityTag< 1 > )
1002 -> decltype( getSingleDataOutputParameters( std::declval< Arg >() ) )
1003 {
1004 return getSingleDataOutputParameters( std::forward< Arg >( arg ) );
1005 }
1006
1007 template< class Arg >
1008 inline static std::tuple<> getSingleDataOutputParameters ( Arg &&arg, PriorityTag< 0 > )
1009 {
1010 return {};
1011 }
1012
1013 template< class... Args >
1014 inline static auto getDataOutputParametersTuple ( Args &&... args )
1015 -> decltype( std::tuple_cat( getSingleDataOutputParameters( std::declval< Args >(), PriorityTag< 42 >() )... ) )
1016 {
1017 return std::tuple_cat( getSingleDataOutputParameters( std::forward< Args >( args ), PriorityTag< 42 >() )... );
1018 }
1019
1020 template< class... Args >
1021 inline static auto getDataOutputParameters ( Args &&... args )
1022 -> std::enable_if_t< (std::tuple_size< decltype( getDataOutputParametersTuple( std::declval< Args >()... ) ) >::value == 0), std::unique_ptr< const DataOutputParameters > >
1023 {
1024 return std::make_unique< const DataOutputParameters >( Parameter::container() );
1025 }
1026
1027 template< class... Args >
1028 inline static auto getDataOutputParameters ( Args &&... args )
1029 -> std::enable_if_t< (std::tuple_size< decltype( getDataOutputParametersTuple( std::declval< Args >()... ) ) >::value > 0), std::unique_ptr< const DataOutputParameters > >
1030 {
1031 static_assert( (std::tuple_size< decltype( Impl::getDataOutputParametersTuple( std::declval< Args >()... ) ) >::value == 1), "Cannot pass multiple DataOutputParameters to DataOutput" );
1032 return std::get< 0 >( getDataOutputParametersTuple( std::forward< Args >( args )... ) );
1033 }
1034
1035
1036
1037 // ValidDataOutputArgument
1038 // -----------------------
1039
1040 template< class Arg, class = void >
1041 struct ValidDataOutputArgument
1042 : public std::false_type
1043 {};
1044
1045 template< class DF >
1046 struct ValidDataOutputArgument< DF, std::enable_if_t< std::is_base_of< Fem::HasLocalFunction, std::decay_t< DF > >::value > >
1047 : public std::true_type
1048 {};
1049
1050 template< class Arg >
1051 struct ValidDataOutputArgument< Arg, void_t< decltype( getSingleDataOutputParameters( std::declval< Arg >() ) ) > >
1052 : public std::true_type
1053 {};
1054
1055 } // namespace Impl
1056
1057
1058
1059 // dataOutput
1060 // ----------
1061
1062 template< class Grid, class... Args, std::enable_if_t< Std::And( Impl::ValidDataOutputArgument< Args >::value... ), int > = 0 >
1063 inline static auto dataOutput ( const Grid &grid, Args &&... args )
1064 {
1065 auto ioTuple = Impl::makeIOTuple( std::forward< Args >( args )... );
1066 auto parameters = Impl::getDataOutputParameters( std::forward< Args >( args )... );
1067 return DataOutput< Grid, decltype( ioTuple ) >( grid, ioTuple, std::move( parameters ) );
1068 }
1069
1070 template< class Grid, class... Args, std::enable_if_t< Std::And( Impl::ValidDataOutputArgument< Args >::value... ), int > = 0 >
1071 inline static auto dataOutput ( const Grid &grid, const TimeProviderBase &tp, Args &&... args )
1072 {
1073 auto ioTuple = Impl::makeIOTuple( std::forward< Args >( args )... );
1074 auto parameters = Impl::getDataOutputParameters( std::forward< Args >( args )... );
1075 return DataOutput< Grid, decltype( ioTuple ) >( grid, ioTuple, tp, std::move( parameters ) );
1076 }
1077
1078 } // namespace Fem
1079
1080} // namespace Dune
1081
1082#endif // #ifndef DUNE_FEM_DATAOUTPUT_HH
Definition: adaptivefunction.hh:48
Implementation of the Dune::Fem::IOInterface. This class manages data output. Available output format...
Definition: dataoutput.hh:197
DataOutput(const GridType &grid, OutPutDataType &data, const TimeProviderBase &tp, const DataOutputParameters &parameter)
Constructor creating data writer.
Definition: dataoutput.hh:326
const std::string & path() const
return output path name
Definition: dataoutput.hh:413
void write() const
write given data to disc, evaluates parameter savecount
Definition: dataoutput.hh:366
int writeCalls() const
return write calls
Definition: dataoutput.hh:425
DataOutput(const GridType &grid, OutPutDataType &data, const TimeProviderBase &tp, std::unique_ptr< const DataOutputParameters > parameters)
Constructor creating data writer.
Definition: dataoutput.hh:313
GridImp GridType
type of grid used
Definition: dataoutput.hh:279
void writeData(double sequenceStamp) const
write data with a given sequence stamp
Definition: dataoutput.hh:401
void write(const std::string &outstring) const
write given data to disc, evaluates parameter savecount
Definition: dataoutput.hh:358
void grapeDisplay(OutputTupleType &data) const
display data with grape
Definition: dataoutput.hh:945
virtual void display() const
display data with grape
Definition: dataoutput.hh:467
DataImp OutPutDataType
type of data tuple
Definition: dataoutput.hh:281
int writeStep() const
return write step
Definition: dataoutput.hh:419
void writeData(double sequenceStamp, const std::string &outstring) const
write data with a given sequence stamp and outstring
Definition: dataoutput.hh:797
virtual bool willWrite(const TimeProviderBase &tp) const
returns true if data will be written on next write call
Definition: dataoutput.hh:338
double saveTime() const
return save time
Definition: dataoutput.hh:431
void write(const TimeProviderBase &tp, const std::string &outstring) const
write given data to disc, evaluates parameter savecount and savestep
Definition: dataoutput.hh:377
virtual bool willWrite() const
returns true if data will be written on next write call
Definition: dataoutput.hh:350
virtual const char * myClassName() const
print class name
Definition: dataoutput.hh:407
virtual void writeBinaryData(const double) const
write binary data
Definition: dataoutput.hh:461
DataOutput(const GridType &grid, OutPutDataType &data, const DataOutputParameters &parameter)
Constructor creating data output class.
Definition: dataoutput.hh:298
const GridType & grid_
type of this class
Definition: dataoutput.hh:478
DataOutput(const GridType &grid, OutPutDataType &data, std::unique_ptr< const DataOutputParameters > parameters)
Constructor creating data output class.
Definition: dataoutput.hh:714
void write(const TimeProviderBase &tp) const
write given data to disc, evaluates parameter savecount and savestep
Definition: dataoutput.hh:387
A vector valued function space.
Definition: functionspace.hh:60
IOInterface to write data to hard disk.
Definition: iointerface.hh:156
static void createGlobalPath(const CommunicatorType &comm, const std::string &path)
create global path for data output
Definition: iointerface.hh:262
static bool verbose()
obtain the cached value for fem.verbose with default verbosity level 2
Definition: parameter.hh:466
general base for time providers
Definition: timeprovider.hh:36
double time() const
obtain the current time
Definition: timeprovider.hh:94
Default exception for dummy implementations.
Definition: exceptions.hh:263
@ conforming
Output conforming data.
Definition: common.hh:73
typename Impl::voider< Types... >::type void_t
Is void for all valid input types. The workhorse for C++11 SFINAE-techniques.
Definition: typetraits.hh:40
static void interpolate(const GridFunction &u, DiscreteFunction &v)
perform native interpolation of a discrete function space
Definition: interpolate.hh:54
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
constexpr GeometryType none(unsigned int dim)
Returns a GeometryType representing a singular of dimension dim.
Definition: type.hh:471
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:256
Dune namespace.
Definition: alignedallocator.hh:13
STL namespace.
Parameter class for Dune::Fem::DataOutput.
Definition: dataoutput.hh:73
virtual int outputformat() const
format of output (fem.io.outputformat)
Definition: dataoutput.hh:109
virtual int savecount() const
save data every savecount calls to write method (fem.io.savecount)
Definition: dataoutput.hh:139
virtual int subsamplingLevel() const
save data every subsamplingLevel (fem.io.subsamplinglevel)
Definition: dataoutput.hh:145
virtual int startcounter() const
number for first data file (no parameter available)
Definition: dataoutput.hh:151
virtual int startcall() const
number of first call (no parameter available)
Definition: dataoutput.hh:157
virtual double startsavetime() const
value of first save time (no parameter available)
Definition: dataoutput.hh:163
virtual bool willWrite(bool write) const
Definition: dataoutput.hh:170
virtual std::string prefix() const
base of file name for data file (fem.io.datafileprefix)
Definition: dataoutput.hh:103
virtual std::string path() const
path where the data is stored (always relative to fem.prefix)
Definition: dataoutput.hh:88
virtual double savestep() const
save data every savestep interval (fem.io.savestep)
Definition: dataoutput.hh:133
virtual bool writeMode() const
Definition: dataoutput.hh:177
virtual bool grapedisplay() const
use online grape display (fem.io.grapedisplay)
Definition: dataoutput.hh:123
Helper class for tagging priorities.
Definition: typeutilities.hh:87
Helper class for tagging priorities.
Definition: typeutilities.hh:73
Utilities for type computations, constraining overloads, ...
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)