00001
00002
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) { }
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
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
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
00256 typename Base::template VTKDataArrayWriter<int>
00257 *p1 = Base::template makeVTKDataArrayWriter<int>(s, "connectivity", 1, ncorners);
00258 {
00259
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
00278 typename Base::template VTKDataArrayWriter<int>
00279 *p2 = Base::template makeVTKDataArrayWriter<int>(s, "offsets", 1, ncells);
00280 {
00281
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
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 << "_";
00327
00328 SimpleStream stream(s);
00329
00330
00331 unsigned int blocklength;
00332
00333
00334 for (FunctionIterator it=vertexdata.begin(); it!=vertexdata.end(); ++it)
00335 {
00336 blocklength = nvertices * (*it)->ncomps() * sizeof(float);
00337
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
00350 if((*it)->ncomps()==2)
00351 stream.write(float(0.0));
00352 }
00353 }
00354 }
00355
00356
00357 for (FunctionIterator it=celldata.begin(); it!=celldata.end(); ++it)
00358 {
00359 blocklength = ncells * (*it)->ncomps() * sizeof(float);
00360
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
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
00396 blocklength = ncorners * sizeof(unsigned int);
00397 stream.write(blocklength);
00398 {
00399
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
00417 blocklength = ncells * sizeof(unsigned int);
00418 stream.write(blocklength);
00419 {
00420
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
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