- Home
- About DUNE
- Download
- Documentation
- Community
- Development
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].