4#ifndef DUNE_GRID_IO_FILE_VTK_BASICWRITER_HH
5#define DUNE_GRID_IO_FILE_VTK_BASICWRITER_HH
18#include <dune/geometry/referenceelements.hh>
21#include <dune/grid/io/file/vtk/functionwriter.hh>
22#include <dune/grid/io/file/vtk/pvtuwriter.hh>
23#include <dune/grid/io/file/vtk/vtuwriter.hh>
32 template<
typename IteratorFactory>
34 typedef typename IteratorFactory::CellIterator CellIterator;
35 typedef typename IteratorFactory::CornerIterator CornerIterator;
36 typedef typename IteratorFactory::PointIterator PointIterator;
38 typedef typename IteratorFactory::Cell Cell;
41 typedef FunctionWriterBase<Cell> FunctionWriter;
44 typedef std::list<std::shared_ptr<FunctionWriter> > WriterList;
45 typedef typename WriterList::const_iterator WIterator;
47 typedef typename Cell::Geometry::ctype ctype;
48 static const unsigned celldim = Cell::mydimension;
49 typedef ReferenceElements<ctype, celldim> Refelems;
51 static const FileType fileType = celldim == 1
54 const IteratorFactory& factory;
59 CoordinatesWriter<Cell> coords;
60 typename IteratorFactory::ConnectivityWriter connectivity;
61 OffsetsWriter<Cell> offsets;
62 TypesWriter<Cell> types;
65 BasicWriter(
const IteratorFactory& factory_)
66 : factory(factory_), connectivity(factory.makeConnectivity())
74 void addCellData(
const std::shared_ptr<FunctionWriter>& writer) {
75 cellData.push_back(writer);
78 void addPointData(
const std::shared_ptr<FunctionWriter>& writer) {
79 pointData.push_back(writer);
93 void writeCellFunction(VTUWriter& vtuWriter,
94 FunctionWriter& functionWriter,
95 unsigned ncells)
const
97 if(functionWriter.beginWrite(vtuWriter, ncells)) {
98 const CellIterator& cellend = factory.endCells();
99 for(CellIterator cellit = factory.beginCells(); cellit != cellend;
104 functionWriter.endWrite();
107 void writePointFunction(VTUWriter& vtuWriter,
108 FunctionWriter& functionWriter,
109 unsigned npoints)
const
111 if(functionWriter.beginWrite(vtuWriter, npoints)) {
112 const PointIterator& pend = factory.endPoints();
113 for(PointIterator pit = factory.beginPoints(); pit != pend; ++pit)
114 functionWriter.write(pit->cell(), pit->duneIndex());
116 functionWriter.endWrite();
119 void writeCornerFunction(VTUWriter& vtuWriter,
120 FunctionWriter& functionWriter,
121 unsigned ncorners)
const
123 if(functionWriter.beginWrite(vtuWriter, ncorners)) {
124 const CornerIterator& cend = factory.endCorners();
125 for(CornerIterator cit = factory.beginCorners(); cit != cend; ++cit)
126 functionWriter.write(cit->cell(), cit->duneIndex());
128 functionWriter.endWrite();
136 static std::string getFirstScalar(
const WriterList& data) {
137 const WIterator& wend = data.end();
138 for(WIterator wit = data.begin(); wit != wend; ++wit)
139 if((*wit)->ncomps() == 1)
140 return (*wit)->name();
144 static std::string getFirstVector(
const WriterList& data) {
145 const WIterator& wend = data.end();
146 for(WIterator wit = data.begin(); wit != wend; ++wit)
147 if((*wit)->ncomps() == 3)
148 return (*wit)->name();
152 void writeCellData(VTUWriter& vtuWriter,
unsigned ncells)
const {
153 if(cellData.empty())
return;
155 vtuWriter.beginCellData(getFirstScalar(cellData),
156 getFirstVector(cellData));
157 const WIterator& wend = cellData.end();
158 for(WIterator wit = cellData.begin(); wit != wend; ++wit)
159 writeCellFunction(vtuWriter, **wit, ncells);
160 vtuWriter.endCellData();
163 void writePointData(VTUWriter& vtuWriter,
unsigned npoints)
const {
164 if(pointData.empty())
return;
166 vtuWriter.beginPointData(getFirstScalar(pointData),
167 getFirstVector(pointData));
168 const WIterator& wend = pointData.end();
169 for(WIterator wit = pointData.begin(); wit != wend; ++wit)
170 writePointFunction(vtuWriter, **wit, npoints);
171 vtuWriter.endPointData();
174 void writeGrid(VTUWriter& vtuWriter,
unsigned ncells,
unsigned npoints,
176 vtuWriter.beginPoints();
177 writePointFunction(vtuWriter, coords, npoints);
178 vtuWriter.endPoints();
180 vtuWriter.beginCells();
181 writeCornerFunction(vtuWriter, connectivity, ncorners);
182 writeCellFunction(vtuWriter, offsets, ncells);
183 if(fileType != polyData)
184 writeCellFunction(vtuWriter, types, ncells);
185 vtuWriter.endCells();
188 void writeAll(VTUWriter& vtuWriter,
unsigned ncells,
unsigned npoints,
190 writeCellData(vtuWriter, ncells);
191 writePointData(vtuWriter, npoints);
192 writeGrid(vtuWriter, ncells, npoints, ncorners);
196 void writePiece(
const std::string& filename, OutputType outputType) {
197 std::ofstream stream;
198 stream.exceptions(std::ios_base::badbit | std::ios_base::failbit |
199 std::ios_base::eofbit);
200 stream.open(filename.c_str(), std::ios::binary);
202 VTUWriter vtuWriter(stream, outputType, fileType);
204 unsigned ncells = std::distance(factory.beginCells(),
206 unsigned npoints = std::distance(factory.beginPoints(),
207 factory.endPoints());
208 unsigned ncorners = std::distance(factory.beginCorners(),
209 factory.endCorners());
211 vtuWriter.beginMain(ncells, npoints);
212 writeAll(vtuWriter, ncells, npoints, ncorners);
215 if(vtuWriter.beginAppended())
216 writeAll(vtuWriter, ncells, npoints, ncorners);
217 vtuWriter.endAppended();
238 void writeCollection(
const std::string name,
239 const std::string& piecename,
240 const std::string& piecepath)
242 std::ofstream stream;
243 stream.exceptions(std::ios_base::badbit | std::ios_base::failbit |
244 std::ios_base::eofbit);
245 stream.open(name.c_str(), std::ios::binary);
247 PVTUWriter writer(stream, fileType);
252 writer.beginPointData(getFirstScalar(pointData),
253 getFirstVector(pointData));
254 for(WIterator it=pointData.begin(); it!=pointData.end(); ++it)
255 (*it)->addArray(writer);
256 writer.endPointData();
259 writer.beginCellData(getFirstScalar(cellData),
260 getFirstVector(cellData));
261 for(WIterator it=cellData.begin(); it!=cellData.end(); ++it)
262 (*it)->addArray(writer);
263 writer.endCellData();
266 writer.beginPoints();
267 coords.addArray(writer);
271 for(
int i = 0; i < factory.comm().size(); ++i )
272 writer.addPiece(getParallelPieceName(piecename, piecepath, i));
293 std::string getParallelPieceName(
const std::string& name,
294 const std::string& path,
int rank)
const
296 std::ostringstream s;
297 if(path.size() > 0) {
299 if(path[path.size()-1] !=
'/')
302 s <<
's' << std::setw(4) << std::setfill(
'0') << factory.comm().size()
304 s <<
'p' << std::setw(4) << std::setfill(
'0') << rank <<
':';
323 std::string getParallelHeaderName(
const std::string& name,
324 const std::string& path)
const
326 std::ostringstream s;
327 if(path.size() > 0) {
329 if(path[path.size()-1] !=
'/')
332 s <<
's' << std::setw(4) << std::setfill(
'0') << factory.comm().size()
336 case polyData : s <<
".pvtp";
break;
355 std::string getSerialPieceName(
const std::string& name,
356 const std::string& path)
const
392 std::string pwrite(
const std::string& name,
const std::string& path,
393 const std::string& extendpath, OutputType outputType)
395 MPIGuard guard(factory.comm());
400 file.exceptions(std::ios_base::badbit | std::ios_base::failbit |
401 std::ios_base::eofbit);
402 std::string piecepath =
concatPaths(path, extendpath);
403 std::string relpiecepath =
relativePath(path, piecepath);
406 std::string fullname = getParallelPieceName(name, piecepath,
407 factory.comm().rank());
408 writePiece(fullname, outputType);
411 fullname = getParallelHeaderName(name, path);
412 if(factory.comm().rank() == 0)
413 writeCollection(fullname, name, relpiecepath);
433 std::string write(
const std::string &name, OutputType outputType)
437 if(factory.comm().size() > 1)
438 return pwrite(name,
"",
"", outputType);
441 std::string pieceName = getSerialPieceName(name,
"");
443 writePiece(pieceName, outputType);
Common stuff for the VTKWriter.
FileType
which type of VTK file to write
Definition: common.hh:298
@ polyData
for .vtp files (PolyData)
Definition: common.hh:300
@ unstructuredGrid
for .vtu files (UnstructuredGrid)
Definition: common.hh:302
std::string relativePath(const std::string &newbase, const std::string &p)
compute a relative path between two paths
Definition: path.cc:151
std::string concatPaths(const std::string &base, const std::string &p)
concatenate two paths
Definition: path.cc:30
Implements a MPIGuard which detects an error on a remote process.
Dune namespace.
Definition: alignedallocator.hh:10
Utilities for handling filesystem paths.
static const ReferenceElement & general(const GeometryType &type)
get general reference elements
Definition: referenceelements.hh:196