dune-grid 2.8.0
Loading...
Searching...
No Matches
basicwriter.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3
4#ifndef DUNE_GRID_IO_FILE_VTK_BASICWRITER_HH
5#define DUNE_GRID_IO_FILE_VTK_BASICWRITER_HH
6
7#include <fstream>
8#include <iomanip>
9#include <iterator>
10#include <list>
11#include <memory>
12#include <sstream>
13#include <string>
14
15#include <dune/common/parallel/mpiguard.hh>
16#include <dune/common/path.hh>
17
18#include <dune/geometry/referenceelements.hh>
19
24
25namespace Dune
26{
29
30 namespace VTK {
31
32 template<typename IteratorFactory>
34 typedef typename IteratorFactory::CellIterator CellIterator;
35 typedef typename IteratorFactory::CornerIterator CornerIterator;
36 typedef typename IteratorFactory::PointIterator PointIterator;
37
38 typedef typename IteratorFactory::Cell Cell;
39
40 public:
42
43 private:
44 typedef std::list<std::shared_ptr<FunctionWriter> > WriterList;
45 typedef typename WriterList::const_iterator WIterator;
46
47 typedef typename Cell::Geometry::ctype ctype;
48 static const unsigned celldim = Cell::mydimension;
49 typedef ReferenceElements<ctype, celldim> Refelems;
50
51 static const FileType fileType = celldim == 1
53
54 const IteratorFactory& factory;
55
56 WriterList cellData;
57 WriterList pointData;
58
60 typename IteratorFactory::ConnectivityWriter connectivity;
61 OffsetsWriter<Cell> offsets;
63
64 public:
65 BasicWriter(const IteratorFactory& factory_)
66 : factory(factory_), connectivity(factory.makeConnectivity())
67 { }
68
70 //
71 // Methods for adding data
72 //
73
74 void addCellData(const std::shared_ptr<FunctionWriter>& writer) {
75 cellData.push_back(writer);
76 }
77
78 void addPointData(const std::shared_ptr<FunctionWriter>& writer) {
79 pointData.push_back(writer);
80 }
81
82 void clear() {
83 cellData.clear();
84 pointData.clear();
85 }
86
87 protected:
89 //
90 // Methods for writing single functions
91 //
92
94 FunctionWriter& functionWriter,
95 unsigned ncells) const
96 {
97 if(functionWriter.beginWrite(vtuWriter, ncells)) {
98 const CellIterator& cellend = factory.endCells();
99 for(CellIterator cellit = factory.beginCells(); cellit != cellend;
100 ++cellit)
101 functionWriter.write(*cellit, Refelems::general(cellit->type()).
102 position(0,0));
103 }
104 functionWriter.endWrite();
105 }
106
108 FunctionWriter& functionWriter,
109 unsigned npoints) const
110 {
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());
115 }
116 functionWriter.endWrite();
117 }
118
120 FunctionWriter& functionWriter,
121 unsigned ncorners) const
122 {
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());
127 }
128 functionWriter.endWrite();
129 }
130
132 //
133 // Methods for writing whole sections
134 //
135
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();
141 return "";
142 }
143
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();
149 return "";
150 }
151
152 void writeCellData(VTUWriter& vtuWriter, unsigned ncells) const {
153 if(cellData.empty()) return;
154
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();
161 }
162
163 void writePointData(VTUWriter& vtuWriter, unsigned npoints) const {
164 if(pointData.empty()) return;
165
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();
172 }
173
174 void writeGrid(VTUWriter& vtuWriter, unsigned ncells, unsigned npoints,
175 unsigned ncorners) {
176 vtuWriter.beginPoints();
177 writePointFunction(vtuWriter, coords, npoints);
178 vtuWriter.endPoints();
179
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();
186 }
187
188 void writeAll(VTUWriter& vtuWriter, unsigned ncells, unsigned npoints,
189 unsigned ncorners) {
190 writeCellData(vtuWriter, ncells);
191 writePointData(vtuWriter, npoints);
192 writeGrid(vtuWriter, ncells, npoints, ncorners);
193 }
194
195 public:
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);
201
202 VTUWriter vtuWriter(stream, outputType, fileType);
203
204 unsigned ncells = std::distance(factory.beginCells(),
205 factory.endCells());
206 unsigned npoints = std::distance(factory.beginPoints(),
207 factory.endPoints());
208 unsigned ncorners = std::distance(factory.beginCorners(),
209 factory.endCorners());
210
211 vtuWriter.beginMain(ncells, npoints);
212 writeAll(vtuWriter, ncells, npoints, ncorners);
213 vtuWriter.endMain();
214
215 if(vtuWriter.beginAppended())
216 writeAll(vtuWriter, ncells, npoints, ncorners);
217 vtuWriter.endAppended();
218
219 }
220
222
238 void writeCollection(const std::string name,
239 const std::string& piecename,
240 const std::string& piecepath)
241 {
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);
246
247 PVTUWriter writer(stream, fileType);
248
249 writer.beginMain();
250
251 // PPointData
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();
257
258 // PCellData
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();
264
265 // PPoints
266 writer.beginPoints();
267 coords.addArray(writer);
268 writer.endPoints();
269
270 // Pieces
271 for( int i = 0; i < factory.comm().size(); ++i )
272 writer.addPiece(getParallelPieceName(piecename, piecepath, i));
273
274 writer.endMain();
275 }
276
278 //
279 // Filename generators
280 //
281
283
293 std::string getParallelPieceName(const std::string& name,
294 const std::string& path, int rank) const
295 {
296 std::ostringstream s;
297 if(path.size() > 0) {
298 s << path;
299 if(path[path.size()-1] != '/')
300 s << '/';
301 }
302 s << 's' << std::setw(4) << std::setfill('0') << factory.comm().size()
303 << ':';
304 s << 'p' << std::setw(4) << std::setfill('0') << rank << ':';
305 s << name;
306 switch(fileType) {
307 case polyData : s << ".vtp"; break;
308 case unstructuredGrid : s << ".vtu"; break;
309 }
310 return s.str();
311 }
312
314
323 std::string getParallelHeaderName(const std::string& name,
324 const std::string& path) const
325 {
326 std::ostringstream s;
327 if(path.size() > 0) {
328 s << path;
329 if(path[path.size()-1] != '/')
330 s << '/';
331 }
332 s << 's' << std::setw(4) << std::setfill('0') << factory.comm().size()
333 << ':';
334 s << name;
335 switch(fileType) {
336 case polyData : s << ".pvtp"; break;
337 case unstructuredGrid : s << ".pvtu"; break;
338 }
339 return s.str();
340 }
341
343
355 std::string getSerialPieceName(const std::string& name,
356 const std::string& path) const
357 {
358 switch(fileType) {
359 case polyData : return concatPaths(path, name+".vtp");
360 case unstructuredGrid : return concatPaths(path, name+".vtu");
361 }
362 return concatPaths(path, name); // unknown fileType
363 }
364
366 //
367 // User interface functions for writing
368 //
369
371
393 std::string pwrite(const std::string& name, const std::string& path,
394 const std::string& extendpath, OutputType outputType)
395 {
396 MPIGuard guard(factory.comm());
397
398 // do some magic because paraview can only cope with relative paths to
399 // piece files
400 std::ofstream file;
401 file.exceptions(std::ios_base::badbit | std::ios_base::failbit |
402 std::ios_base::eofbit);
403 std::string piecepath = concatPaths(path, extendpath);
404 std::string relpiecepath = relativePath(path, piecepath);
405
406 // write this processes .vtu/.vtp piece file
407 std::string fullname = getParallelPieceName(name, piecepath,
408 factory.comm().rank());
409 writePiece(fullname, outputType);
410
411 // if we are rank 0, write .pvtu/.pvtp parallel header
412 fullname = getParallelHeaderName(name, path);
413 if(factory.comm().rank() == 0)
414 writeCollection(fullname, name, relpiecepath);
415
416 guard.finalize();
417
418 return fullname;
419 }
420
434 std::string write(const std::string &name, OutputType outputType)
435 {
436 // in the parallel case, just use pwrite, it has all the necessary
437 // stuff, so we don't need to reimplement it here.
438 if(factory.comm().size() > 1)
439 return pwrite(name, "", "", outputType);
440
441 // generate filename for process data
442 std::string pieceName = getSerialPieceName(name, "");
443
444 writePiece(pieceName, outputType);
445
446 return pieceName;
447 }
448
449 };
450
451 } // namespace VTK
452
454
455} // namespace Dune
456
457#endif // DUNE_GRID_IO_FILE_VTK_BASICWRITER_HH
Common stuff for the VTKWriter.
Include standard header files.
Definition: agrid.hh:58
OutputType
How the bulk data should be stored in the file.
Definition: common.hh:41
FileType
which type of VTK file to write
Definition: common.hh:250
@ polyData
for .vtp files (PolyData)
Definition: common.hh:252
@ unstructuredGrid
for .vtu files (UnstructuredGrid)
Definition: common.hh:254
Definition: basicwriter.hh:33
void writeCellData(VTUWriter &vtuWriter, unsigned ncells) const
Definition: basicwriter.hh:152
BasicWriter(const IteratorFactory &factory_)
Definition: basicwriter.hh:65
std::string getSerialPieceName(const std::string &name, const std::string &path) const
return name of a serial piece file
Definition: basicwriter.hh:355
void writeCollection(const std::string name, const std::string &piecename, const std::string &piecepath)
write header file in parallel case to stream
Definition: basicwriter.hh:238
void writeGrid(VTUWriter &vtuWriter, unsigned ncells, unsigned npoints, unsigned ncorners)
Definition: basicwriter.hh:174
void writeAll(VTUWriter &vtuWriter, unsigned ncells, unsigned npoints, unsigned ncorners)
Definition: basicwriter.hh:188
std::string pwrite(const std::string &name, const std::string &path, const std::string &extendpath, OutputType outputType)
write output; interface might change later
Definition: basicwriter.hh:393
void clear()
Definition: basicwriter.hh:82
void writeCellFunction(VTUWriter &vtuWriter, FunctionWriter &functionWriter, unsigned ncells) const
Definition: basicwriter.hh:93
void writeCornerFunction(VTUWriter &vtuWriter, FunctionWriter &functionWriter, unsigned ncorners) const
Definition: basicwriter.hh:119
std::string getParallelHeaderName(const std::string &name, const std::string &path) const
return name of a parallel header file
Definition: basicwriter.hh:323
void writePointData(VTUWriter &vtuWriter, unsigned npoints) const
Definition: basicwriter.hh:163
static std::string getFirstVector(const WriterList &data)
Definition: basicwriter.hh:144
FunctionWriterBase< Cell > FunctionWriter
Definition: basicwriter.hh:41
void writePointFunction(VTUWriter &vtuWriter, FunctionWriter &functionWriter, unsigned npoints) const
Definition: basicwriter.hh:107
void writePiece(const std::string &filename, OutputType outputType)
Definition: basicwriter.hh:196
void addCellData(const std::shared_ptr< FunctionWriter > &writer)
Definition: basicwriter.hh:74
static std::string getFirstScalar(const WriterList &data)
Definition: basicwriter.hh:136
std::string getParallelPieceName(const std::string &name, const std::string &path, int rank) const
return name of a parallel piece file
Definition: basicwriter.hh:293
std::string write(const std::string &name, OutputType outputType)
write output (interface might change later)
Definition: basicwriter.hh:434
void addPointData(const std::shared_ptr< FunctionWriter > &writer)
Definition: basicwriter.hh:78
Base class for function writers.
Definition: functionwriter.hh:32
virtual void write(const Cell &, const Domain &)
write at the given position
Definition: functionwriter.hh:57
virtual void endWrite()=0
signal end of writing
virtual bool beginWrite(VTUWriter &writer, std::size_t nitems)=0
start writing with the given writer
writer for the Coordinates array
Definition: functionwriter.hh:145
virtual void addArray(PVTUWriter &writer)
add this field to the given parallel writer
Definition: functionwriter.hh:163
writer for the offsets array
Definition: functionwriter.hh:298
writer for the types array
Definition: functionwriter.hh:338
Dump a .vtu/.vtp files contents to a stream.
Definition: pvtuwriter.hh:60
void endMain()
finish the main PolyData/UnstructuredGrid section
Definition: pvtuwriter.hh:193
void endCellData()
finish CellData section
Definition: pvtuwriter.hh:153
void beginMain(unsigned ghostLevel=0)
start the main PPolyData/PUnstructuredGrid section
Definition: pvtuwriter.hh:187
void beginCellData(const std::string &scalars="", const std::string &vectors="")
start CellData section
Definition: pvtuwriter.hh:144
void beginPointData(const std::string &scalars="", const std::string &vectors="")
start PointData section
Definition: pvtuwriter.hh:118
void addPiece(const std::string &filename)
Add a serial piece to the output file.
Definition: pvtuwriter.hh:213
void endPointData()
finish PointData section
Definition: pvtuwriter.hh:127
void endPoints()
finish section for the point coordinates
Definition: pvtuwriter.hh:169
void beginPoints()
start section for the point coordinates
Definition: pvtuwriter.hh:164
Dump a .vtu/.vtp files contents to a stream.
Definition: vtuwriter.hh:96
bool beginAppended()
start the appended data section
Definition: vtuwriter.hh:343
void endAppended()
finish the appended data section
Definition: vtuwriter.hh:357
void endCellData()
finish CellData section
Definition: vtuwriter.hh:218
void beginMain(unsigned ncells, unsigned npoints)
start the main PolyData/UnstructuredGrid section
Definition: vtuwriter.hh:308
void beginCells()
start section for the grid cells/PolyData lines
Definition: vtuwriter.hh:272
void endPointData()
finish PointData section
Definition: vtuwriter.hh:180
void beginCellData(const std::string &scalars="", const std::string &vectors="")
start CellData section
Definition: vtuwriter.hh:203
void beginPointData(const std::string &scalars="", const std::string &vectors="")
start PointData section
Definition: vtuwriter.hh:165
void endPoints()
finish section for the point coordinates
Definition: vtuwriter.hh:247
void endCells()
start section for the grid cells/PolyData lines
Definition: vtuwriter.hh:283
void beginPoints()
start section for the point coordinates
Definition: vtuwriter.hh:236
void endMain()
finish the main PolyData/UnstructuredGrid section
Definition: vtuwriter.hh:318