vtkwriter.hh

Go to the documentation of this file.
00001 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002 // vi: set et ts=4 sw=2 sts=2:
00003 
00004 #ifndef DUNE_VTKWRITER_HH
00005 #define DUNE_VTKWRITER_HH
00006 
00007 #include <cstring>
00008 #include <iostream>
00009 #include <string>
00010 #include <fstream>
00011 #include <sstream>
00012 #include <iomanip>
00013 
00014 #include <vector>
00015 #include <list>
00016 
00017 #include <dune/common/deprecated.hh>
00018 #include <dune/common/exceptions.hh>
00019 #include <dune/common/indent.hh>
00020 #include <dune/common/iteratorfacades.hh>
00021 #include <dune/common/path.hh>
00022 #include <dune/common/shared_ptr.hh>
00023 #include <dune/grid/common/mcmgmapper.hh>
00024 #include <dune/grid/common/genericreferenceelements.hh>
00025 #include <dune/grid/common/gridenums.hh>
00026 #include <dune/grid/io/file/vtk/common.hh>
00027 #include <dune/grid/io/file/vtk/dataarraywriter.hh>
00028 #include <dune/grid/io/file/vtk/function.hh>
00029 #include <dune/grid/io/file/vtk/pvtuwriter.hh>
00030 #include <dune/grid/io/file/vtk/streams.hh>
00031 #include <dune/grid/io/file/vtk/vtuwriter.hh>
00032 
00050 namespace Dune
00051 {
00060   template< class GridView >
00061   class VTKWriter {
00062     // extract types
00063     typedef typename GridView::Grid Grid;
00064     typedef typename Grid::ctype DT;
00065     enum { n = GridView::dimension };
00066     enum { w = GridView::dimensionworld };
00067 
00068     typedef typename GridView::template Codim< 0 >::Entity Cell;
00069     typedef typename GridView::template Codim< n >::Entity Vertex;
00070     typedef Cell Entity;
00071     
00072     typedef typename GridView::IndexSet IndexSet;
00073     
00074     static const PartitionIteratorType VTK_Partition = InteriorBorder_Partition;
00075     
00076     typedef typename GridView::template Codim< 0 >
00077       ::template Partition< VTK_Partition >::Iterator
00078       GridCellIterator;
00079     typedef typename GridView::template Codim< n >
00080       ::template Partition< VTK_Partition >::Iterator
00081       GridVertexIterator;
00082     
00083     typedef MultipleCodimMultipleGeomTypeMapper< GridView, MCMGVertexLayout > VertexMapper;
00084 
00085   public:
00086     typedef Dune::VTKFunction<Grid> VTKFunction;
00087     typedef shared_ptr< Dune::VTKFunction<Grid> > VTKFunctionPtr;
00088 
00089   protected:
00090     typedef typename std::list<VTKFunctionPtr>::const_iterator FunctionIterator;
00091     
00093 
00098     class CellIterator : public GridCellIterator
00099     {
00100     public:
00102       CellIterator(const GridCellIterator & x) : GridCellIterator(x) {};
00105       const FieldVector<DT,n> position() const
00106         {
00107             return GenericReferenceElements<DT,n>::general((*this)->type()).position(0,0);
00108         }
00109     };
00110 
00111     CellIterator cellBegin() const
00112     {
00113       return gridView_.template begin< 0, VTK_Partition >();
00114     }
00115 
00116     CellIterator cellEnd() const
00117     {
00118       return gridView_.template end< 0, VTK_Partition >();
00119     }
00120     
00122 
00136     class VertexIterator :
00137       public ForwardIteratorFacade<VertexIterator, const Entity, const Entity&, int>
00138     {
00139       GridCellIterator git;
00140       GridCellIterator gend;
00141       VTK::DataMode datamode;
00142       // Index of the currently visited corner within the current element.
00143       // NOTE: this is in Dune-numbering, in contrast to CornerIterator.
00144       int cornerIndexDune;
00145       const VertexMapper & vertexmapper;
00146       std::vector<bool> visited;
00147       // in conforming mode, for each vertex id (as obtained by vertexmapper)
00148       // hold its number in the iteration order (VertexIterator)
00149       int offset;
00150     protected:
00151       void basicIncrement ()
00152       {
00153         if( git == gend )
00154           return;
00155         ++cornerIndexDune;
00156         const int numCorners = git->template count< n >();
00157         if( cornerIndexDune == numCorners )
00158         {
00159           offset += numCorners;
00160           cornerIndexDune = 0;
00161 
00162           ++git;
00163           while( (git != gend) && (git->partitionType() != InteriorEntity) )
00164             ++git;
00165         }
00166       }
00167     public:
00168       VertexIterator(const GridCellIterator & x,
00169                      const GridCellIterator & end,
00170                      const VTK::DataMode & dm,
00171                      const VertexMapper & vm) :
00172         git(x), gend(end), datamode(dm), cornerIndexDune(0),
00173         vertexmapper(vm), visited(vm.size(), false),
00174         offset(0)
00175         {
00176           if (datamode == VTK::conforming && git != gend)
00177             visited[vertexmapper.map(*git,cornerIndexDune,n)] = true;
00178         };
00179       void increment ()
00180         {
00181           switch (datamode)
00182           {
00183           case VTK::conforming:
00184             while(visited[vertexmapper.map(*git,cornerIndexDune,n)])
00185             {
00186               basicIncrement();
00187               if (git == gend) return;
00188             }
00189             visited[vertexmapper.map(*git,cornerIndexDune,n)] = true;
00190             break;
00191           case VTK::nonconforming:
00192             basicIncrement();
00193             break;
00194           }
00195        }
00196       bool equals (const VertexIterator & cit) const
00197         {
00198           return git == cit.git
00199             && cornerIndexDune == cit.cornerIndexDune
00200             && datamode == cit.datamode;
00201         }
00202       const Entity& dereference() const
00203         {
00204           return *git;
00205         }
00207       int localindex () const
00208         {
00209           return cornerIndexDune;
00210         }
00212       const FieldVector<DT,n> & position () const
00213         {
00214           return GenericReferenceElements<DT,n>::general(git->type())
00215             .position(cornerIndexDune,n);
00216         }
00217     };    
00218     
00219     VertexIterator vertexBegin () const
00220     {
00221       return VertexIterator( gridView_.template begin< 0, VTK_Partition >(),
00222                              gridView_.template end< 0, VTK_Partition >(),
00223                              datamode, *vertexmapper );
00224     }
00225 
00226     VertexIterator vertexEnd () const
00227     {
00228       return VertexIterator( gridView_.template end< 0, VTK_Partition >(),
00229                              gridView_.template end< 0, VTK_Partition >(),
00230                              datamode, *vertexmapper );
00231     }
00232     
00234 
00248     class CornerIterator :
00249       public ForwardIteratorFacade<CornerIterator, const Entity, const Entity&, int>
00250     {
00251       GridCellIterator git;
00252       GridCellIterator gend;
00253       VTK::DataMode datamode;
00254       // Index of the currently visited corner within the current element.
00255       // NOTE: this is in VTK-numbering, in contrast to VertexIterator.
00256       int cornerIndexVTK;
00257       const VertexMapper & vertexmapper;
00258       // in conforming mode, for each vertex id (as obtained by vertexmapper)
00259       // hold its number in the iteration order of VertexIterator (*not*
00260       // CornerIterator)
00261       const std::vector<int> & number;
00262       // holds the number of corners of all the elements we have seen so far,
00263       // excluding the current element
00264       int offset;
00265 
00266     public:
00267       CornerIterator(const GridCellIterator & x,
00268                      const GridCellIterator & end,
00269                      const VTK::DataMode & dm,
00270                      const VertexMapper & vm,
00271                      const std::vector<int> & num) :
00272         git(x), gend(end), datamode(dm), cornerIndexVTK(0),
00273         vertexmapper(vm),
00274         number(num), offset(0) {};
00275       void increment ()
00276       {
00277         if( git == gend )
00278           return;
00279         ++cornerIndexVTK;
00280         const int numCorners = git->template count< n >();
00281         if( cornerIndexVTK == numCorners )
00282         {
00283           offset += numCorners;
00284           cornerIndexVTK = 0;
00285 
00286           ++git;
00287           while( (git != gend) && (git->partitionType() != InteriorEntity) )
00288             ++git;
00289         }
00290       }
00291       bool equals (const CornerIterator & cit) const
00292         {
00293           return git == cit.git
00294             && cornerIndexVTK == cit.cornerIndexVTK
00295             && datamode == cit.datamode;
00296         }
00297       const Entity& dereference() const
00298         {
00299           return *git;
00300         }
00302 
00306       int id () const
00307         {
00308           switch (datamode)
00309           {
00310           case VTK::conforming:
00311             return
00312               number[vertexmapper.map(*git,VTK::renumber(*git,cornerIndexVTK),
00313                                       n)];
00314           case VTK::nonconforming:
00315             return offset + VTK::renumber(*git,cornerIndexVTK);
00316           default:
00317             DUNE_THROW(IOError,"VTKWriter: unsupported DataMode" << datamode);
00318           }
00319         }
00320     };
00321     
00322     CornerIterator cornerBegin () const
00323     {
00324       return CornerIterator( gridView_.template begin< 0, VTK_Partition >(),
00325                              gridView_.template end< 0, VTK_Partition >(),
00326                              datamode, *vertexmapper, number );
00327     }
00328     
00329     CornerIterator cornerEnd () const
00330     {
00331       return CornerIterator( gridView_.template end< 0, VTK_Partition >(),
00332                              gridView_.template end< 0, VTK_Partition >(),
00333                              datamode, *vertexmapper, number );
00334     }    
00335 
00336   public:
00344     explicit VTKWriter ( const GridView &gridView,
00345                          VTK::DataMode dm = VTK::conforming )
00346     : gridView_( gridView ),
00347       datamode( dm )
00348     { }
00349 
00354     void addCellData (const VTKFunctionPtr & p)
00355       {
00356         celldata.push_back(p);
00357       }
00358 
00364       void addCellData (VTKFunction* p) // DUNE_DEPRECATED
00365       {
00366         celldata.push_back(VTKFunctionPtr(p));
00367       }
00368 
00384     template<class V>
00385     void addCellData (const V& v, const std::string &name, int ncomps = 1)
00386     {
00387       typedef P0VTKFunction<GridView, V> Function;
00388       for (int c=0;c<ncomps;++c) {
00389         std::stringstream compName;
00390         compName << name;
00391         if (ncomps>1)
00392           compName << "[" << c << "]";
00393         VTKFunction* p = new Function(gridView_, v, compName.str(), ncomps, c);
00394         celldata.push_back(VTKFunctionPtr(p));
00395       }
00396     }
00397 
00403       void addVertexData (VTKFunction* p) // DUNE_DEPRECATED
00404       {
00405         vertexdata.push_back(VTKFunctionPtr(p));
00406       }
00407 
00412     void addVertexData (const VTKFunctionPtr & p)
00413       {
00414         vertexdata.push_back(p);
00415       }
00416 
00432     template<class V>
00433     void addVertexData (const V& v, const std::string &name, int ncomps=1)
00434     {
00435       typedef P1VTKFunction<GridView, V> Function;
00436       for (int c=0;c<ncomps;++c) {
00437         std::stringstream compName;
00438         compName << name;
00439         if (ncomps>1)
00440           compName << "[" << c << "]";
00441         VTKFunction* p = new Function(gridView_, v, compName.str(), ncomps, c);
00442         vertexdata.push_back(VTKFunctionPtr(p));
00443       }
00444     }
00445 
00447     void clear ()
00448       {
00449         celldata.clear();
00450         vertexdata.clear();
00451       }
00452 
00454     virtual ~VTKWriter ()
00455       {
00456         this->clear();
00457       }
00458 
00470     std::string write ( const std::string &name,
00471                         VTK::OutputType type = VTK::ascii )
00472     {
00473       return write( name, type, gridView_.comm().rank(), gridView_.comm().size() );
00474     }
00475 
00502     std::string pwrite ( const std::string & name,  const std::string & path, const std::string & extendpath,
00503                          VTK::OutputType type = VTK::ascii )
00504     {
00505       return pwrite( name, path, extendpath, type, gridView_.comm().rank(), gridView_.comm().size() );
00506     }
00507 
00508   protected:
00510 
00521     std::string getParallelPieceName(const std::string& name,
00522                                      const std::string& path,
00523                                      int commRank, int commSize) const
00524     {
00525       std::ostringstream s;
00526       if(path.size() > 0) {
00527         s << path;
00528         if(path[path.size()-1] != '/')
00529           s << '/';
00530       }
00531       s << 's' << std::setw(4) << std::setfill('0') << commSize << ':';
00532       s << 'p' << std::setw(4) << std::setfill('0') << commRank << ':';
00533       s << name;
00534       if(GridView::dimension > 1)
00535         s << ".vtu";
00536       else
00537         s << ".vtp";
00538       return s.str();
00539     }
00540 
00542 
00552     std::string getParallelHeaderName(const std::string& name,
00553                                       const std::string& path,
00554                                       int commSize) const
00555     {
00556       std::ostringstream s;
00557       if(path.size() > 0) {
00558         s << path;
00559         if(path[path.size()-1] != '/')
00560           s << '/';
00561       }
00562       s << 's' << std::setw(4) << std::setfill('0') << commSize << ':';
00563       s << name;
00564       if(GridView::dimension > 1)
00565         s << ".pvtu";
00566       else
00567         s << ".pvtp";
00568       return s.str();
00569     }
00570 
00572 
00584     std::string getSerialPieceName(const std::string& name,
00585                                    const std::string& path) const
00586     {
00587       static const std::string extension =
00588         GridView::dimension == 1 ? ".vtp" : ".vtu";
00589 
00590       return concatPaths(path, name+extension);
00591     }
00592 
00608     std::string write ( const std::string &name,
00609                         VTK::OutputType type,
00610                         const int commRank,
00611                         const int commSize )
00612     {
00613       // in the parallel case, just use pwrite, it has all the necessary
00614       // stuff, so we don't need to reimplement it here.
00615       if(commSize > 1)
00616         return pwrite(name, "", "", type, commRank, commSize);
00617 
00618       // make data mode visible to private functions
00619       outputtype = type;
00620 
00621       // generate filename for process data
00622       std::string pieceName = getSerialPieceName(name, "");
00623 
00624       // write process data
00625       std::ofstream file;
00626       file.open( pieceName.c_str(), std::ios::binary );
00627       if (! file.is_open())
00628         DUNE_THROW(IOError, "Could not write to piece file " << pieceName);
00629       writeDataFile( file );
00630       file.close();
00631 
00632       return pieceName;
00633     }
00634 
00636 
00659     std::string pwrite(const std::string& name, const std::string& path,
00660                        const std::string& extendpath,
00661                        VTK::OutputType ot, const int commRank,
00662                        const int commSize )
00663       {
00664         // make data mode visible to private functions
00665         outputtype=ot;
00666 
00667         // do some magic because paraview can only cope with relative pathes to piece files
00668         std::ofstream file;
00669         std::string piecepath = concatPaths(path, extendpath);
00670         std::string relpiecepath = relativePath(path, piecepath);
00671 
00672         // write this processes .vtu/.vtp piece file
00673         std::string fullname = getParallelPieceName(name, piecepath, commRank,
00674                                                     commSize);
00675         file.open(fullname.c_str(),std::ios::binary);
00676         if (! file.is_open())
00677           DUNE_THROW(IOError, "Could not write to piecefile file " << fullname);
00678         writeDataFile(file);
00679         file.close();
00680         gridView_.comm().barrier();
00681 
00682         // if we are rank 0, write .pvtu/.pvtp parallel header
00683         fullname = getParallelHeaderName(name, path, commSize);
00684         if( commRank  ==0 )
00685         {
00686           file.open(fullname.c_str());
00687           if (! file.is_open())
00688             DUNE_THROW(IOError, "Could not write to parallel file " << fullname);
00689           writeParallelHeader(file,name,relpiecepath, commSize );
00690           file.close();
00691         }
00692         gridView_.comm().barrier();
00693         return fullname;
00694       }
00695 
00696   private:
00698 
00715     void writeParallelHeader(std::ostream& s, const std::string& piecename,
00716                              const std::string& piecepath, const int commSize)
00717       {
00718         VTK::FileType fileType =
00719           (n == 1) ? VTK::polyData : VTK::unstructuredGrid;
00720 
00721         VTK::PVTUWriter writer(s, fileType);
00722 
00723         writer.beginMain();
00724 
00725         // PPointData
00726         {
00727           std::string scalars;
00728           for (FunctionIterator it=vertexdata.begin(); it!=vertexdata.end();
00729                ++it)
00730             if ((*it)->ncomps()==1)
00731             {
00732               scalars = (*it)->name();
00733               break;
00734             }
00735           std::string vectors;
00736           for (FunctionIterator it=vertexdata.begin(); it!=vertexdata.end();
00737                ++it)
00738             if ((*it)->ncomps()>1)
00739             {
00740               vectors = (*it)->name();
00741               break;
00742             }
00743           writer.beginPointData(scalars, vectors);
00744         }
00745         for (FunctionIterator it=vertexdata.begin(); it!=vertexdata.end();
00746              ++it)
00747           writer.addArray<float>((*it)->name(), (*it)->ncomps()>1?3:1);
00748         writer.endPointData();
00749 
00750         // PCellData
00751         {
00752           std::string scalars;
00753           for (FunctionIterator it=celldata.begin(); it!=celldata.end();
00754                ++it)
00755             if ((*it)->ncomps()==1)
00756             {
00757               scalars = (*it)->name();
00758               break;
00759             }
00760           std::string vectors;
00761           for (FunctionIterator it=celldata.begin(); it!=celldata.end();
00762                ++it)
00763             if ((*it)->ncomps()>1)
00764             {
00765               vectors = (*it)->name();
00766               break;
00767             }
00768           writer.beginCellData(scalars, vectors);
00769         }
00770         for (FunctionIterator it=celldata.begin(); it!=celldata.end(); ++it)
00771           writer.addArray<float>((*it)->name(), (*it)->ncomps()>1?3:1);
00772         writer.endCellData();
00773 
00774         // PPoints
00775         writer.beginPoints();
00776         writer.addArray<float>("Coordinates", 3);
00777         writer.endPoints();
00778 
00779         // Pieces
00780         for( int i = 0; i < commSize; ++i )
00781         {
00782           const std::string& fullname = getParallelPieceName(piecename,
00783                                                              piecepath, i,
00784                                                              commSize);
00785           writer.addPiece(fullname);
00786         }
00787 
00788         writer.endMain();
00789       }
00790 
00792     void writeDataFile (std::ostream& s)
00793       {
00794         VTK::FileType fileType =
00795           (n == 1) ? VTK::polyData : VTK::unstructuredGrid;
00796 
00797         VTK::VTUWriter writer(s, outputtype, fileType);
00798 
00799         // Grid characteristics
00800         vertexmapper = new VertexMapper( gridView_ );
00801         if (datamode == VTK::conforming)
00802         {
00803           number.resize(vertexmapper->size());
00804           for (std::vector<int>::size_type i=0; i<number.size(); i++) number[i] = -1;
00805         }
00806         countEntities(nvertices, ncells, ncorners);
00807 
00808         writer.beginMain(ncells, nvertices);
00809         writeAllData(writer);
00810         writer.endMain();
00811 
00812         // write appended binary data section
00813         if(writer.beginAppended())
00814           writeAllData(writer);
00815         writer.endAppended();
00816 
00817         delete vertexmapper; number.clear();
00818       }
00819 
00820     void writeAllData(VTK::VTUWriter& writer) {
00821       // PointData
00822       writeVertexData(writer);
00823 
00824       // CellData
00825       writeCellData(writer);
00826 
00827       // Points
00828       writeGridPoints(writer);
00829 
00830       // Cells
00831       writeGridCells(writer);
00832     }
00833 
00834   protected:
00835     std::string getFormatString() const
00836       {
00837           if (outputtype==VTK::ascii)
00838               return "ascii";
00839           if (outputtype==VTK::base64)
00840               return "binary";
00841           if (outputtype==VTK::appendedraw)
00842               return "appended";
00843           if (outputtype==VTK::appendedbase64)
00844               return "appended";
00845           DUNE_THROW(IOError, "VTKWriter: unsupported OutputType" << outputtype);
00846       }
00847       
00848     std::string getTypeString() const
00849       {
00850           if (n==1)
00851               return "PolyData";
00852           else
00853               return "UnstructuredGrid";
00854       }
00855       
00857     virtual void countEntities(int &nvertices, int &ncells, int &ncorners)
00858       {
00859         nvertices = 0;
00860         ncells = 0;
00861         ncorners = 0;
00862         for (CellIterator it=cellBegin(); it!=cellEnd(); ++it)
00863         {
00864           ncells++;
00865           // because of the use of vertexmapper->map(), this iteration must be
00866           // in the order of Dune's numbering.
00867           for (int i=0; i<it->template count<n>(); ++i)
00868           {
00869             ncorners++;
00870             if (datamode == VTK::conforming)
00871             {
00872               int alpha = vertexmapper->map(*it,i,n);
00873               if (number[alpha]<0)
00874                 number[alpha] = nvertices++;
00875             }
00876             else
00877             {
00878               nvertices++;
00879             }
00880           }
00881         }
00882       }
00883 
00885     virtual void writeCellData(VTK::VTUWriter& writer)
00886       {
00887         if(celldata.size() == 0)
00888           return;
00889 
00890         std::string scalars = "";
00891         for (FunctionIterator it=celldata.begin(); it!=celldata.end(); ++it)
00892           if ((*it)->ncomps()==1)
00893           {
00894             scalars = (*it)->name();
00895             break;
00896           }
00897         std::string vectors = "";
00898         for (FunctionIterator it=celldata.begin(); it!=celldata.end(); ++it)
00899           if ((*it)->ncomps()>1)
00900           {
00901             vectors = (*it)->name();
00902             break;
00903           }
00904 
00905         writer.beginCellData(scalars, vectors);
00906         for (FunctionIterator it=celldata.begin(); it!=celldata.end(); ++it)
00907         {
00908           // vtk file format: a vector data always should have 3 comps (with
00909           // 3rd comp = 0 in 2D case)
00910           unsigned writecomps = (*it)->ncomps();
00911           if(writecomps == 2) writecomps = 3;
00912           shared_ptr<VTK::DataArrayWriter<float> > p
00913             (writer.makeArrayWriter<float>((*it)->name(), writecomps,
00914                                             ncells));
00915           if(!p->writeIsNoop())
00916             for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00917             {
00918               for (int j=0; j<(*it)->ncomps(); j++)
00919                 p->write((*it)->evaluate(j,*i,i.position()));
00920               // vtk file format: a vector data always should have 3 comps
00921               // (with 3rd comp = 0 in 2D case)
00922               for (unsigned j=(*it)->ncomps(); j < writecomps; ++j)
00923                 p->write(0.0);
00924             }
00925         }
00926         writer.endCellData();
00927       }
00928 
00930     virtual void writeVertexData(VTK::VTUWriter& writer)
00931       {
00932         if(vertexdata.size() == 0)
00933           return;
00934 
00935         std::string scalars = "";
00936         for (FunctionIterator it=vertexdata.begin(); it!=vertexdata.end(); ++it)
00937           if ((*it)->ncomps()==1)
00938           {
00939             scalars = (*it)->name();
00940             break;
00941           }
00942         std::string vectors = "";
00943         for (FunctionIterator it=vertexdata.begin(); it!=vertexdata.end(); ++it)
00944           if ((*it)->ncomps()>1)
00945           {
00946             vectors = (*it)->name();
00947             break;
00948           }
00949 
00950         writer.beginPointData(scalars, vectors);
00951         for (FunctionIterator it=vertexdata.begin(); it!=vertexdata.end(); ++it)
00952         {
00953           // vtk file format: a vector data always should have 3 comps (with
00954           // 3rd comp = 0 in 2D case)
00955           unsigned writecomps = (*it)->ncomps();
00956           if(writecomps == 2) writecomps = 3;
00957           shared_ptr<VTK::DataArrayWriter<float> > p
00958             (writer.makeArrayWriter<float>((*it)->name(), writecomps,
00959                                            nvertices));
00960           if(!p->writeIsNoop())
00961             for (VertexIterator vit=vertexBegin(); vit!=vertexEnd(); ++vit)
00962             {
00963               for (int j=0; j<(*it)->ncomps(); j++)
00964                 p->write((*it)->evaluate(j,*vit,vit.position()));
00965               // vtk file format: a vector data always should have 3 comps
00966               // (with 3rd comp = 0 in 2D case)
00967               for (unsigned j=(*it)->ncomps(); j < writecomps; ++j)
00968                 p->write(0.0);
00969             }
00970         }
00971         writer.endPointData();
00972       }
00973 
00975     virtual void writeGridPoints(VTK::VTUWriter& writer)
00976       {
00977         writer.beginPoints();
00978 
00979         shared_ptr<VTK::DataArrayWriter<float> > p
00980           (writer.makeArrayWriter<float>("Coordinates", 3, nvertices));
00981         if(!p->writeIsNoop()) {
00982           VertexIterator vEnd = vertexEnd();
00983           for (VertexIterator vit=vertexBegin(); vit!=vEnd; ++vit)
00984           {
00985             int dimw=w;
00986             for (int j=0; j<std::min(dimw,3); j++)
00987               p->write(vit->geometry().corner(vit.localindex())[j]);
00988             for (int j=std::min(dimw,3); j<3; j++)
00989               p->write(0.0);
00990           }
00991         }
00992         // free the VTK::DataArrayWriter before touching the stream
00993         p.reset();
00994 
00995         writer.endPoints();
00996       }
00997 
00999     virtual void writeGridCells(VTK::VTUWriter& writer)
01000       {
01001         writer.beginCells();
01002 
01003         // connectivity
01004         {
01005           shared_ptr<VTK::DataArrayWriter<int> > p1
01006             (writer.makeArrayWriter<int>("connectivity", 1, ncorners));
01007           if(!p1->writeIsNoop())
01008             for (CornerIterator it=cornerBegin(); it!=cornerEnd(); ++it)
01009               p1->write(it.id());
01010         }
01011 
01012         // offsets
01013         {
01014           shared_ptr<VTK::DataArrayWriter<int> > p2
01015             (writer.makeArrayWriter<int>("offsets", 1, ncells));
01016           if(!p2->writeIsNoop()) {
01017             int offset = 0;
01018             for (CellIterator it=cellBegin(); it!=cellEnd(); ++it)
01019             {
01020               offset += it->template count<n>();
01021               p2->write(offset);
01022             }
01023           }
01024         }
01025 
01026         // types
01027         if (n>1)
01028         {
01029           shared_ptr<VTK::DataArrayWriter<unsigned char> > p3
01030             (writer.makeArrayWriter<unsigned char>("types", 1, ncells));
01031           if(!p3->writeIsNoop())
01032             for (CellIterator it=cellBegin(); it!=cellEnd(); ++it)
01033             {
01034               int vtktype = VTK::geometryType(it->type());
01035               p3->write(vtktype);
01036             }
01037         }
01038 
01039         writer.endCells();
01040       }
01041 
01042   protected:
01043     // the list of registered functions
01044     std::list<VTKFunctionPtr> celldata;
01045     std::list<VTKFunctionPtr> vertexdata;
01046 
01047   private: 
01048     // the grid
01049     GridView gridView_;
01050 
01051     // temporary grid information
01052   protected:
01053     int ncells;
01054     int nvertices;
01055     int ncorners;
01056   private:
01057     VertexMapper* vertexmapper;
01058     // in conforming mode, for each vertex id (as obtained by vertexmapper)
01059     // hold its number in the iteration order (VertexIterator)
01060     std::vector<int> number;
01061     VTK::DataMode datamode;
01062   protected:
01063     VTK::OutputType outputtype;
01064   };
01065 
01069   template< class Grid >
01070   class LeafVTKWriter
01071   : public VTKWriter< typename Grid::LeafGridView >
01072   {
01073     typedef VTKWriter< typename Grid::LeafGridView > Base;
01074 
01075   public:
01077     explicit LeafVTKWriter ( const Grid &grid,
01078                              VTK::DataMode dm = VTK::conforming ) DUNE_DEPRECATED
01079     : Base( grid.leafView(), dm )
01080     {}
01081   };
01082 
01086   template< class Grid >
01087   class LevelVTKWriter
01088   : public VTKWriter< typename Grid::LevelGridView >
01089   {
01090     typedef VTKWriter< typename Grid::LevelGridView > Base;
01091 
01092   public:
01094     LevelVTKWriter ( const Grid &grid, int level,
01095                      VTK::DataMode dm = VTK::conforming ) DUNE_DEPRECATED
01096     : Base( grid.levelView( level ), dm )
01097     {}
01098   };
01099   
01100 }
01101 
01102 #endif

Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].