subsamplingvtkwriter.hh

Go to the documentation of this file.
00001 // -*- tab-width: 4; indent-tabs-mode: nil -*-
00002 // $Id: subsamplingvtkwriter.hh 4915 2009-03-10 10:50:41Z mnolte $
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     }
00129     ncorners = nvertices;
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       stream.write(blocklength);
00361       for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00362       {
00363         Refinement &refinement = buildRefinement<dim, ctype>(i->type(), subsampledGeometryType(i->type()));
00364         for(SubElementIterator sit = refinement.eBegin(level), send = refinement.eEnd(level);
00365             sit != send; ++sit)
00366         {
00367           for (int j=0; j<(*it)->ncomps(); j++)
00368             stream.write(float((*it)->evaluate(j,*i,sit.coords())));
00369           if((*it)->ncomps() == 2)
00370             stream.write(float(0.0));
00371         }
00372       }
00373     }
00374       
00375     // point coordinates
00376     blocklength = nvertices * 3 * sizeof(float);
00377     stream.write(blocklength);
00378     for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00379     {
00380       Refinement &refinement = buildRefinement<dim, ctype>(i->type(), subsampledGeometryType(i->type()));
00381       for(SubVertexIterator sit = refinement.vBegin(level), send = refinement.vEnd(level);
00382           sit != send; ++sit)
00383       {
00384         FieldVector<ctype, dimw> coords = i->geometry().global(sit.coords());
00385         for (int j=0; j<std::min(int(dimw),3); j++)
00386           stream.write(float(coords[j]));
00387         for (int j=std::min(int(dimw),3); j<3; j++)
00388           stream.write(float(0.0));
00389       }
00390     }
00391       
00392     // connectivity
00393     blocklength = ncorners * sizeof(unsigned int);
00394     stream.write(blocklength);
00395     {
00396       //offset into the vertex numbering
00397       unsigned int offset = 0;
00398       for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00399       {
00400         GeometryType coerceTo = subsampledGeometryType(i->type());
00401         Refinement &refinement = buildRefinement<dim, ctype>(i->type(), coerceTo);
00402         for(SubElementIterator sit = refinement.eBegin(level), send = refinement.eEnd(level);
00403             sit != send; ++sit)
00404         {
00405           IndexVector indices = sit.vertexIndices();
00406           for(unsigned int ii = 0; ii < indices.size(); ++ii)
00407             stream.write(offset+indices[renumber(coerceTo, ii)]);
00408         }
00409         offset += refinement.nVertices(level);
00410       }
00411     }
00412 
00413     // offsets
00414     blocklength = ncells * sizeof(unsigned int);
00415     stream.write(blocklength);
00416     {
00417       //offset into the connectivity array
00418       unsigned int offset = 0;
00419       for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00420       {
00421         Refinement &refinement = buildRefinement<dim, ctype>(i->type(), subsampledGeometryType(i->type()));
00422         offset += refinement.nVertices(level);
00423         stream.write(offset);
00424       }
00425     }
00426 
00427     // cell types
00428     if (dim>1)
00429     {
00430       blocklength = ncells * sizeof(unsigned char);
00431       stream.write(blocklength);
00432       for (CellIterator it=cellBegin(); it!=cellEnd(); ++it)
00433       {
00434         GeometryType coerceTo = subsampledGeometryType(it->type());
00435         Refinement &refinement = buildRefinement<dim, ctype>(it->type(), coerceTo);
00436         unsigned char vtktype = vtkType(coerceTo);
00437         for(int i = 0; i < refinement.nElements(level); ++i)
00438           stream.write(vtktype);
00439       }
00440     }
00441 
00442     s << std::endl;
00443     indentDown();
00444     indent(s); s << "</AppendedData>" << std::endl;
00445   }
00446 }
00447 
00448 #endif // DUNE_SUBSAMPLINGVTKWRITER_HH

Generated on Tue Jul 28 22:28:20 2009 for dune-grid by  doxygen 1.5.6