subsamplingvtkwriter.hh

Go to the documentation of this file.
00001 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002 // vi: set et ts=8 sw=2 sts=2:
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/common/indent.hh>
00011 #include <dune/grid/common/virtualrefinement.hh>
00012 #include <dune/grid/io/file/vtk/vtkwriter.hh>
00013 #include <dune/grid/io/file/vtk/vtuwriter.hh>
00014 
00021 namespace Dune
00022 {
00034   template< class GridView >
00035   class SubsamplingVTKWriter 
00036     : public VTKWriter<GridView>
00037   {
00038     typedef VTKWriter<GridView> Base;
00039     enum { dim = GridView::dimension };
00040     enum { dimw = GridView::dimensionworld };
00041     typedef typename GridView::Grid::ctype ctype;
00042     typedef VirtualRefinement<dim, ctype> Refinement;
00043     typedef typename Refinement::IndexVector IndexVector;
00044     typedef typename Refinement::ElementIterator SubElementIterator;
00045     typedef typename Refinement::VertexIterator SubVertexIterator;
00046 
00047     typedef typename Base::CellIterator CellIterator;
00048     typedef typename Base::FunctionIterator FunctionIterator;
00049     using Base::cellBegin;
00050     using Base::cellEnd;
00051     using Base::celldata;
00052     using Base::ncells;
00053     using Base::ncorners;
00054     using Base::nvertices;
00055     using Base::outputtype;
00056     using Base::vertexBegin;
00057     using Base::vertexEnd;
00058     using Base::vertexdata;
00059 
00060   public:
00073     explicit SubsamplingVTKWriter (const GridView &gridView,
00074                                    unsigned int level_, bool coerceToSimplex_ = false)
00075       : Base(gridView, VTK::nonconforming)
00076       , level(level_), coerceToSimplex(coerceToSimplex_)
00077     { }
00078 
00079   private:
00080     GeometryType subsampledGeometryType(GeometryType geometryType) {
00081       if(geometryType.isCube() && !coerceToSimplex) { /* nothing */ }
00082       else geometryType.makeSimplex(dim);
00083       return geometryType;
00084     }
00085 
00086   protected:
00088     virtual void countEntities(int &nvertices, int &ncells, int &ncorners);
00089 
00091     virtual void writeCellData(VTK::VTUWriter& writer);
00092 
00094     virtual void writeVertexData(VTK::VTUWriter& writer);
00095 
00097     virtual void writeGridPoints(VTK::VTUWriter& writer);
00098 
00100     virtual void writeGridCells(VTK::VTUWriter& writer);
00101 
00102   public:
00103     using Base::addVertexData;
00104 
00105   private:
00106     // hide addVertexData -- adding vertex data directly without a VTKFunction
00107     // currently does not work since the P1VectorWrapper used for that uses a
00108     // nearest-neighbour search to find the value for the given point.  See
00109     // FS#676.
00110     template<class V>
00111     void addVertexData (const V& v, const std::string &name, int ncomps=1);
00112 
00113     unsigned int level;
00114     bool coerceToSimplex;
00115   };
00116 
00118   template <class GridView>
00119   void SubsamplingVTKWriter<GridView>::countEntities(int &nvertices, int &ncells, int &ncorners)
00120   {
00121     nvertices = 0;
00122     ncells = 0;
00123     ncorners = 0;
00124     for (CellIterator it=this->cellBegin(); it!=cellEnd(); ++it)
00125     {
00126       Refinement &refinement = buildRefinement<dim, ctype>(it->type(), subsampledGeometryType(it->type()));
00127 
00128       ncells += refinement.nElements(level);
00129       nvertices += refinement.nVertices(level);
00130       ncorners += refinement.nElements(level) * refinement.eBegin(level).vertexIndices().size();
00131     }
00132   }
00133 
00135   template <class GridView>
00136   void SubsamplingVTKWriter<GridView>::writeCellData(VTK::VTUWriter& writer)
00137   {
00138     if(celldata.size() == 0)
00139       return;
00140 
00141     std::string scalars = "";
00142     for (FunctionIterator it=celldata.begin(); it!=celldata.end(); ++it)
00143       if ((*it)->ncomps()==1)
00144       {
00145         scalars = (*it)->name();
00146         break;
00147       }
00148     std::string vectors = "";
00149     for (FunctionIterator it=celldata.begin(); it!=celldata.end(); ++it)
00150       if ((*it)->ncomps()>1)
00151       {
00152         vectors = (*it)->name();
00153         break;
00154       }
00155 
00156     writer.beginCellData(scalars, vectors);
00157     for (FunctionIterator it=celldata.begin(); it!=celldata.end(); ++it)
00158     {
00159       // vtk file format: a vector data always should have 3 comps (with 3rd
00160       // comp = 0 in 2D case)
00161       unsigned writecomps = (*it)->ncomps();
00162       if(writecomps == 2) writecomps = 3;
00163 
00164       shared_ptr<VTK::DataArrayWriter<float> > p
00165         (writer.makeArrayWriter<float>((*it)->name(), writecomps, ncells));
00166       if(!p->writeIsNoop())
00167         for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00168         {
00169           Refinement &refinement =
00170             buildRefinement<dim, ctype>(i->type(),
00171                                         subsampledGeometryType(i->type()));
00172           for(SubElementIterator sit = refinement.eBegin(level),
00173                 send = refinement.eEnd(level);
00174               sit != send; ++sit)
00175           {
00176             for (int j=0; j<(*it)->ncomps(); j++)
00177               p->write((*it)->evaluate(j,*i,sit.coords()));
00178             // expand 2D-Vectors to 3D
00179             for(unsigned j = (*it)->ncomps(); j < writecomps; j++)
00180               p->write(0.0);
00181           }
00182         }
00183     }
00184     writer.endCellData();
00185   }
00186 
00188   template <class GridView>
00189   void SubsamplingVTKWriter<GridView>::writeVertexData(VTK::VTUWriter& writer)
00190   {
00191     if(vertexdata.size() == 0)
00192       return;
00193 
00194     std::string scalars = "";
00195     for (FunctionIterator it=vertexdata.begin(); it!=vertexdata.end(); ++it)
00196       if ((*it)->ncomps()==1)
00197       {
00198         scalars = (*it)->name();
00199         break;
00200       }
00201     std::string vectors = "";
00202     for (FunctionIterator it=vertexdata.begin(); it!=vertexdata.end(); ++it)
00203       if ((*it)->ncomps()>1)
00204       {
00205         vectors = (*it)->name();
00206         break;
00207       }
00208 
00209     writer.beginPointData(scalars, vectors);
00210     for (FunctionIterator it=vertexdata.begin(); it!=vertexdata.end(); ++it)
00211     {
00212       // vtk file format: a vector data always should have 3 comps (with 3rd
00213       // comp = 0 in 2D case)
00214       unsigned writecomps = (*it)->ncomps();
00215       if(writecomps == 2) writecomps = 3;
00216 
00217       shared_ptr<VTK::DataArrayWriter<float> > p
00218         (writer.makeArrayWriter<float>((*it)->name(), writecomps, nvertices));
00219       if(!p->writeIsNoop())
00220         for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00221         {
00222           Refinement &refinement =
00223             buildRefinement<dim, ctype>(i->type(),
00224                                         subsampledGeometryType(i->type()));
00225           for(SubVertexIterator sit = refinement.vBegin(level),
00226                 send = refinement.vEnd(level);
00227               sit != send; ++sit)
00228           {
00229             for (int j=0; j<(*it)->ncomps(); j++)
00230               p->write((*it)->evaluate(j,*i,sit.coords()));
00231             // vtk file format: a vector data always should have 3 comps (with
00232             // 3rd comp = 0 in 2D case)
00233             for(unsigned j = (*it)->ncomps(); j < writecomps; j++)
00234               p->write(0.0);
00235           }
00236         }
00237     }
00238     writer.endPointData();
00239   }
00240 
00242   template <class GridView>
00243   void SubsamplingVTKWriter<GridView>::writeGridPoints(VTK::VTUWriter& writer)
00244   {
00245     writer.beginPoints();
00246 
00247     shared_ptr<VTK::DataArrayWriter<float> > p
00248       (writer.makeArrayWriter<float>("Coordinates", 3, nvertices));
00249     if(!p->writeIsNoop())
00250       for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00251       {
00252         Refinement &refinement =
00253           buildRefinement<dim, ctype>(i->type(),
00254                                       subsampledGeometryType(i->type()));
00255         for(SubVertexIterator sit = refinement.vBegin(level),
00256               send = refinement.vEnd(level);
00257             sit != send; ++sit)
00258         {
00259           FieldVector<ctype, dimw> coords = i->geometry().global(sit.coords());
00260           for (int j=0; j<std::min(int(dimw),3); j++)
00261             p->write(coords[j]);
00262           for (int j=std::min(int(dimw),3); j<3; j++)
00263             p->write(0.0);
00264         }
00265       }
00266     // free the VTK::DataArrayWriter before touching the stream
00267     p.reset();
00268 
00269     writer.endPoints();
00270   }
00271 
00273   template <class GridView>
00274   void SubsamplingVTKWriter<GridView>::writeGridCells(VTK::VTUWriter& writer)
00275   {
00276     writer.beginCells();
00277 
00278     // connectivity
00279     {
00280       shared_ptr<VTK::DataArrayWriter<int> > p1
00281         (writer.makeArrayWriter<int>("connectivity", 1, ncorners));
00282       // The offset within the index numbering
00283       if(!p1->writeIsNoop()) {
00284         int offset = 0;
00285         for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00286         {
00287           GeometryType coercedToType = subsampledGeometryType(i->type());
00288           Refinement &refinement =
00289             buildRefinement<dim, ctype>(i->type(), coercedToType);
00290           for(SubElementIterator sit = refinement.eBegin(level),
00291                 send = refinement.eEnd(level);
00292               sit != send; ++sit)
00293           {
00294             IndexVector indices = sit.vertexIndices();
00295             for(unsigned int ii = 0; ii < indices.size(); ++ii)
00296               p1->write(offset+indices[VTK::renumber(coercedToType, ii)]);
00297           }
00298           offset += refinement.nVertices(level);
00299         }
00300       }
00301     }
00302 
00303     // offsets
00304     {
00305       shared_ptr<VTK::DataArrayWriter<int> > p2
00306         (writer.makeArrayWriter<int>("offsets", 1, ncells));
00307       if(!p2->writeIsNoop()) {
00308         // The offset into the connectivity array
00309         int offset = 0;
00310         for (CellIterator i=cellBegin(); i!=cellEnd(); ++i)
00311         {
00312           Refinement &refinement =
00313             buildRefinement<dim, ctype>(i->type(),
00314                                         subsampledGeometryType(i->type()));
00315           unsigned int verticesPerCell =
00316             refinement.eBegin(level).vertexIndices().size();
00317           for(int element = 0; element < refinement.nElements(level);
00318               ++element)
00319           {
00320             offset += verticesPerCell;
00321             p2->write(offset);
00322           }
00323         }
00324       }
00325     }
00326 
00327     // types
00328     if (dim>1)
00329     {
00330       shared_ptr<VTK::DataArrayWriter<unsigned char> > p3
00331         (writer.makeArrayWriter<unsigned char>("types", 1, ncells));
00332       if(!p3->writeIsNoop())
00333         for (CellIterator it=cellBegin(); it!=cellEnd(); ++it)
00334         {
00335           GeometryType coerceTo = subsampledGeometryType(it->type());
00336           Refinement &refinement =
00337             buildRefinement<dim, ctype>(it->type(), coerceTo);
00338           int vtktype = VTK::geometryType(coerceTo);
00339           for(int i = 0; i < refinement.nElements(level); ++i)
00340             p3->write(vtktype);
00341         }
00342     }
00343 
00344     writer.endCells();
00345   }
00346 }
00347 
00348 #endif // DUNE_SUBSAMPLINGVTKWRITER_HH

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