subsamplingvtkwriter.hh

Go to the documentation of this file.
00001 // -*- tab-width: 4; indent-tabs-mode: nil -*-
00002 // $Id: subsamplingvtkwriter.hh 5917 2009-11-11 17:00:06Z robertk $
00003 
00004 #ifndef DUNE_SUBSAMPLINGVTKWRITER_HH
00005 #define DUNE_SUBSAMPLINGVTKWRITER_HH
00006 
00007 #include <ostream>
00008 
00009 #include <dune/common/geometrytype.hh>
00010 #include <dune/grid/common/virtualrefinement.hh>
00011 #include <dune/grid/io/file/vtk/vtkwriter.hh>
00012 
00019 namespace Dune
00020 {
00032   template< class GridView >
00033   class SubsamplingVTKWriter 
00034     : public VTKWriter<GridView>
00035   {
00036     typedef VTKWriter<GridView> Base;
00037     enum { dim = GridView::dimension };
00038     enum { dimw = GridView::dimensionworld };
00039     typedef typename GridView::Grid::ctype ctype;
00040     typedef VirtualRefinement<dim, ctype> Refinement;
00041     typedef typename Refinement::IndexVector IndexVector;
00042     typedef typename Refinement::ElementIterator SubElementIterator;
00043     typedef typename Refinement::VertexIterator SubVertexIterator;
00044 
00045     typedef typename Base::CellIterator CellIterator;
00046     typedef typename Base::FunctionIterator FunctionIterator;
00047     typedef typename Base::SimpleStream SimpleStream;
00048     using Base::cellBegin;
00049     using Base::cellEnd;
00050     using Base::celldata;
00051     using Base::indent;
00052     using Base::indentDown;
00053     using Base::indentUp;
00054     using Base::makeVTKDataArrayWriter;
00055     using Base::ncells;
00056     using Base::ncorners;
00057     using Base::nvertices;
00058     using Base::outputtype;
00059     using Base::renumber;
00060     using Base::vertexBegin;
00061     using Base::vertexEnd;
00062     using Base::vertexdata;
00063     using Base::vtkType;
00064 
00065   public:
00078     explicit SubsamplingVTKWriter (const GridView &gridView,
00079                                    unsigned int level_, bool coerceToSimplex_ = false)
00080       : Base(gridView, VTKOptions::nonconforming)
00081       , level(level_), coerceToSimplex(coerceToSimplex_)
00082     { }
00083 
00084   private:
00085     GeometryType subsampledGeometryType(GeometryType geometryType) {
00086       if(geometryType.isCube() && !coerceToSimplex) { /* nothing */ }
00087       else geometryType.makeSimplex(dim);
00088       return geometryType;
00089     }
00090 
00091   protected:
00093     virtual void countEntities(int &nvertices, int &ncells, int &ncorners);
00094 
00096     virtual void writeCellData (std::ostream& s);
00097 
00099     virtual void writeVertexData (std::ostream& s);
00100 
00102     virtual void writeGridPoints (std::ostream& s);
00103 
00105     virtual void writeGridCells (std::ostream& s);
00106 
00108     virtual void writeAppendedData (std::ostream& s);
00109 
00110   private:
00111     unsigned int level;
00112     bool coerceToSimplex;
00113   };
00114 
00116   template <class GridView>
00117   void SubsamplingVTKWriter<GridView>::countEntities(int &nvertices, int &ncells, int &ncorners)
00118   {
00119     nvertices = 0;
00120     ncells = 0;
00121     ncorners = 0;
00122     for (CellIterator it=this->cellBegin(); it!=cellEnd(); ++it)
00123     {
00124       Refinement &refinement = buildRefinement<dim, ctype>(it->type(), subsampledGeometryType(it->type()));
00125 
00126       ncells += refinement.nElements(level);
00127       nvertices += refinement.nVertices(level);
00128       ncorners += refinement.nElements(level) * refinement.eBegin(level).vertexIndices().size();
00129     }
00130   }
00131 
00133   template <class GridView>
00134   void SubsamplingVTKWriter<GridView>::writeCellData (std::ostream& s)
00135   {
00136     indent(s); s << "<CellData";
00137     for (FunctionIterator it=celldata.begin(); it!=celldata.end(); ++it)
00138       if ((*it)->ncomps()==1)
00139       {
00140         s << " Scalars=\"" << (*it)->name() << "\"" ;
00141         break;
00142       }
00143     for (FunctionIterator it=celldata.begin(); it!=celldata.end(); ++it)
00144       if ((*it)->ncomps()>1)
00145       {
00146         s << " Vectors=\"" << (*it)->name() << "\"" ;
00147         break;
00148       }
00149     s << ">" << std::endl;
00150     indentUp();
00151     for (FunctionIterator it=celldata.begin(); it!=celldata.end(); ++it)
00152     {
00153       typename Base::template VTKDataArrayWriter<float>
00154         *p = Base::template makeVTKDataArrayWriter<float>(s, (*it)->name().c_str(), (*it)->ncomps(), (*it)->ncomps()*ncells);
00155       for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00156       {
00157         Refinement &refinement = buildRefinement<dim, ctype>(i->type(), subsampledGeometryType(i->type()));
00158         for(SubElementIterator sit = refinement.eBegin(level), send = refinement.eEnd(level);
00159             sit != send; ++sit)
00160         {
00161           for (int j=0; j<(*it)->ncomps(); j++)
00162             p->write((*it)->evaluate(j,*i,sit.coords()));
00163           // expand 2D-Vectors to 3D
00164           if((*it)->ncomps()==2)
00165             p->write(0.0);
00166         }
00167       }
00168       delete p;
00169     }
00170     indentDown();
00171     indent(s); s << "</CellData>" << std::endl;
00172   }
00173 
00175   template <class GridView>
00176   void SubsamplingVTKWriter<GridView>::writeVertexData (std::ostream& s)
00177   {
00178     indent(s); s << "<PointData";
00179     for (FunctionIterator it=vertexdata.begin(); it!=vertexdata.end(); ++it)
00180       if ((*it)->ncomps()==1)
00181       {
00182         s << " Scalars=\"" << (*it)->name() << "\"" ;
00183         break;
00184       }
00185     for (FunctionIterator it=vertexdata.begin(); it!=vertexdata.end(); ++it)
00186       if ((*it)->ncomps()>1)
00187       {
00188         s << " Vectors=\"" << (*it)->name() << "\"" ;
00189         break;
00190       }
00191     s << ">" << std::endl;
00192     indentUp();
00193     for (FunctionIterator it=vertexdata.begin(); it!=vertexdata.end(); ++it)
00194     {
00195       typename Base::template VTKDataArrayWriter<float>
00196         *p = Base::template makeVTKDataArrayWriter<float>(s, (*it)->name().c_str(), (*it)->ncomps(), (*it)->ncomps()*nvertices);
00197       for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00198       {
00199         Refinement &refinement = buildRefinement<dim, ctype>(i->type(), subsampledGeometryType(i->type()));
00200         for(SubVertexIterator sit = refinement.vBegin(level), send = refinement.vEnd(level);
00201             sit != send; ++sit)
00202         {
00203           for (int j=0; j<(*it)->ncomps(); j++)
00204             p->write((*it)->evaluate(j,*i,sit.coords()));
00205           //vtk file format: a vector data always should have 3 comps(with 3rd comp = 0 in 2D case)
00206           if((*it)->ncomps()==2)
00207             p->write(0.0);
00208         }
00209       }
00210       delete p;
00211     }
00212     indentDown();
00213     indent(s); s << "</PointData>" << std::endl;
00214   }
00215 
00217   template <class GridView>
00218   void SubsamplingVTKWriter<GridView>::writeGridPoints (std::ostream& s)
00219   {
00220     indent(s); s << "<Points>" << std::endl;
00221     indentUp();
00222 
00223     typename Base::template VTKDataArrayWriter<float>
00224       *p = Base::template makeVTKDataArrayWriter<float>(s, "Coordinates", 3, 3*nvertices);
00225     for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00226     {
00227       Refinement &refinement = buildRefinement<dim, ctype>(i->type(), subsampledGeometryType(i->type()));
00228       for(SubVertexIterator sit = refinement.vBegin(level), send = refinement.vEnd(level);
00229           sit != send; ++sit)
00230       {
00231         FieldVector<ctype, dimw> coords = i->geometry().global(sit.coords());
00232         for (int j=0; j<std::min(int(dimw),3); j++)
00233           p->write(coords[j]);
00234         for (int j=std::min(int(dimw),3); j<3; j++)
00235           p->write(0.0);
00236       }
00237     }
00238     delete p;
00239 
00240     indentDown();
00241     indent(s); s << "</Points>" << std::endl;
00242   }
00243 
00245   template <class GridView>
00246   void SubsamplingVTKWriter<GridView>::writeGridCells (std::ostream& s)
00247   {
00248     indent(s); 
00249     if (dim>1)
00250       s << "<Cells>" << std::endl;
00251     else
00252       s << "<Lines>" << std::endl;
00253     indentUp();
00254 
00255     // connectivity
00256     typename Base::template VTKDataArrayWriter<int>
00257       *p1 = Base::template makeVTKDataArrayWriter<int>(s, "connectivity", 1, ncorners);
00258     {
00259       // The offset within the index numbering
00260       int offset = 0;
00261       for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00262       {
00263         GeometryType coercedToType = subsampledGeometryType(i->type());
00264         Refinement &refinement = buildRefinement<dim, ctype>(i->type(), coercedToType);
00265         for(SubElementIterator sit = refinement.eBegin(level), send = refinement.eEnd(level);
00266             sit != send; ++sit)
00267           {
00268             IndexVector indices = sit.vertexIndices();
00269             for(unsigned int ii = 0; ii < indices.size(); ++ii)
00270               p1->write(offset+indices[renumber(coercedToType, ii)]);
00271           }
00272         offset += refinement.nVertices(level);
00273       }
00274     }
00275     delete p1;
00276 
00277     // offsets
00278     typename Base::template VTKDataArrayWriter<int>
00279       *p2 = Base::template makeVTKDataArrayWriter<int>(s, "offsets", 1, ncells);
00280     {
00281       // The offset into the connectivity array
00282       int offset = 0;
00283       for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00284       {
00285         Refinement &refinement = buildRefinement<dim, ctype>(i->type(), subsampledGeometryType(i->type()));
00286         unsigned int verticesPerCell = refinement.eBegin(level).vertexIndices().size();
00287         for(int element = 0; element < refinement.nElements(level); ++element)
00288         {
00289           offset += verticesPerCell;
00290           p2->write(offset);
00291         }
00292       }
00293     }
00294     delete p2;
00295 
00296     // types
00297     if (dim>1)
00298     {
00299       typename Base::template VTKDataArrayWriter<unsigned char>
00300         *p3 = Base::template makeVTKDataArrayWriter<unsigned char>(s, "types", 1, ncells);
00301       for (CellIterator it=cellBegin(); it!=cellEnd(); ++it)
00302       {
00303         GeometryType coerceTo = subsampledGeometryType(it->type());
00304         Refinement &refinement = buildRefinement<dim, ctype>(it->type(), coerceTo);
00305         int vtktype = vtkType(coerceTo);
00306         for(int i = 0; i < refinement.nElements(level); ++i)
00307           p3->write(vtktype);
00308       }
00309       delete p3;
00310     }
00311 
00312     indentDown();
00313     indent(s); 
00314     if (dim>1)
00315       s << "</Cells>" << std::endl;
00316     else
00317       s << "</Lines>" << std::endl;
00318   }
00319 
00321   template <class GridView>
00322   void SubsamplingVTKWriter<GridView>::writeAppendedData (std::ostream& s)
00323   {
00324     indent(s); s << "<AppendedData encoding=\"raw\">" << std::endl;
00325     indentUp();
00326     indent(s); s << "_"; // indicates start of binary data
00327 
00328     SimpleStream stream(s);
00329 
00330     // write length before each data block
00331     unsigned int blocklength;
00332 
00333     // point data     
00334     for (FunctionIterator it=vertexdata.begin(); it!=vertexdata.end(); ++it)
00335     {
00336       blocklength = nvertices * (*it)->ncomps() * sizeof(float);
00337       //vtk file format: a vector data always should have 3 comps(with 3rd comp = 0 in 2D case)
00338       if((*it)->ncomps()==2)
00339         blocklength = nvertices * (3) * sizeof(float);
00340       stream.write(blocklength);
00341       for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00342       {
00343         Refinement &refinement = buildRefinement<dim, ctype>(i->type(), subsampledGeometryType(i->type()));
00344         for(SubVertexIterator sit = refinement.vBegin(level), send = refinement.vEnd(level);
00345             sit != send; ++sit)
00346         {
00347           for (int j=0; j<(*it)->ncomps(); j++)
00348             stream.write(float((*it)->evaluate(j,*i,sit.coords())));
00349           //vtk file format: a vector data always should have 3 comps(with 3rd comp = 0 in 2D case)
00350           if((*it)->ncomps()==2)
00351             stream.write(float(0.0));
00352         }
00353       }
00354     }
00355 
00356     // cell data
00357     for (FunctionIterator it=celldata.begin(); it!=celldata.end(); ++it)
00358     {
00359       blocklength = ncells * (*it)->ncomps() * sizeof(float);
00360       //vtk file format: a vector data always should have 3 comps(with 3rd comp = 0 in 2D case)
00361       if((*it)->ncomps()==2)
00362         blocklength = ncells * (3) * sizeof(float);
00363       stream.write(blocklength);
00364       for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00365       {
00366         Refinement &refinement = buildRefinement<dim, ctype>(i->type(), subsampledGeometryType(i->type()));
00367         for(SubElementIterator sit = refinement.eBegin(level), send = refinement.eEnd(level);
00368             sit != send; ++sit)
00369         {
00370           for (int j=0; j<(*it)->ncomps(); j++)
00371             stream.write(float((*it)->evaluate(j,*i,sit.coords())));
00372           if((*it)->ncomps() == 2)
00373             stream.write(float(0.0));
00374         }
00375       }
00376     }
00377       
00378     // point coordinates
00379     blocklength = nvertices * 3 * sizeof(float);
00380     stream.write(blocklength);
00381     for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00382     {
00383       Refinement &refinement = buildRefinement<dim, ctype>(i->type(), subsampledGeometryType(i->type()));
00384       for(SubVertexIterator sit = refinement.vBegin(level), send = refinement.vEnd(level);
00385           sit != send; ++sit)
00386       {
00387         FieldVector<ctype, dimw> coords = i->geometry().global(sit.coords());
00388         for (int j=0; j<std::min(int(dimw),3); j++)
00389           stream.write(float(coords[j]));
00390         for (int j=std::min(int(dimw),3); j<3; j++)
00391           stream.write(float(0.0));
00392       }
00393     }
00394       
00395     // connectivity
00396     blocklength = ncorners * sizeof(unsigned int);
00397     stream.write(blocklength);
00398     {
00399       //offset into the vertex numbering
00400       unsigned int offset = 0;
00401       for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00402       {
00403         GeometryType coerceTo = subsampledGeometryType(i->type());
00404         Refinement &refinement = buildRefinement<dim, ctype>(i->type(), coerceTo);
00405         for(SubElementIterator sit = refinement.eBegin(level), send = refinement.eEnd(level);
00406             sit != send; ++sit)
00407         {
00408           IndexVector indices = sit.vertexIndices();
00409           for(unsigned int ii = 0; ii < indices.size(); ++ii)
00410             stream.write(offset+indices[renumber(coerceTo, ii)]);
00411         }
00412         offset += refinement.nVertices(level);
00413       }
00414     }
00415 
00416     // offsets
00417     blocklength = ncells * sizeof(unsigned int);
00418     stream.write(blocklength);
00419     {
00420       //offset into the connectivity array
00421       unsigned int offset = 0;
00422       for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00423       {
00424         Refinement &refinement = buildRefinement<dim, ctype>(i->type(), subsampledGeometryType(i->type()));
00425         unsigned int verticesPerCell = refinement.eBegin(level).vertexIndices().size();
00426         for(int element = 0; element < refinement.nElements(level); ++element)
00427         {
00428           offset += verticesPerCell;
00429           stream.write(offset);
00430         }
00431       }
00432     }
00433 
00434     // cell types
00435     if (dim>1)
00436     {
00437       blocklength = ncells * sizeof(unsigned char);
00438       stream.write(blocklength);
00439       for (CellIterator it=cellBegin(); it!=cellEnd(); ++it)
00440       {
00441         GeometryType coerceTo = subsampledGeometryType(it->type());
00442         Refinement &refinement = buildRefinement<dim, ctype>(it->type(), coerceTo);
00443         unsigned char vtktype = vtkType(coerceTo);
00444         for(int i = 0; i < refinement.nElements(level); ++i)
00445           stream.write(vtktype);
00446       }
00447     }
00448 
00449     s << std::endl;
00450     indentDown();
00451     indent(s); s << "</AppendedData>" << std::endl;
00452   }
00453 }
00454 
00455 #endif // DUNE_SUBSAMPLINGVTKWRITER_HH

Generated on Sun Nov 15 22:28:44 2009 for dune-grid by  doxygen 1.5.6