DUNE PDELab (2.8)

dataarraywriter.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_DATAARRAYWRITER_HH
5#define DUNE_GRID_IO_FILE_VTK_DATAARRAYWRITER_HH
6
7#include <cstdint>
8#include <iostream>
9#include <string>
10#include <iomanip>
11#include <cstdint>
12#include <cmath>
13
15#include <dune/common/indent.hh>
16
17#include <dune/grid/io/file/vtk/streams.hh>
19
28namespace Dune
29{
32
33 namespace VTK {
34
36
54 {
55 public:
57
62 : prec(_prec)
63 {}
64
66 template<class T>
67 void write(T data)
68 {
69 switch(prec)
70 {
71 case Precision::float32:
72 writeFloat32(data); break;
73 case Precision::float64:
74 writeFloat64(data); break;
75 case Precision::uint32:
76 writeUInt32(data); break;
77 case Precision::uint8:
78 writeUInt8(data); break;
79 case Precision::int32:
80 writeInt32(data); break;
81 default:
82 DUNE_THROW(Dune::NotImplemented, "Unknown precision type");
83 }
84 }
85
87 virtual bool writeIsNoop() const { return false; }
89 virtual ~DataArrayWriter () {}
90
91 private:
93 virtual void writeFloat32 (float data) = 0;
95 virtual void writeFloat64 (double data) = 0;
97 virtual void writeInt32 (std::int32_t data) = 0;
99 virtual void writeUInt8 (std::uint8_t data) = 0;
101 virtual void writeUInt32 (std::uint32_t data) = 0;
102
103 Precision prec;
104 };
105
108 {
109 public:
111
119 AsciiDataArrayWriter(std::ostream& theStream, std::string name,
120 int ncomps, const Indent& indent_, Precision prec_)
121 : DataArrayWriter(prec_), s(theStream), counter(0), numPerLine(12), indent(indent_)
122 {
123 s << indent << "<DataArray type=\"" << toString(prec_) << "\" "
124 << "Name=\"" << name << "\" ";
125 s << "NumberOfComponents=\"" << ncomps << "\" ";
126 s << "format=\"ascii\">\n";
127 ++indent;
128 }
129
132 {
133 if (counter%numPerLine!=0) s << "\n";
134 --indent;
135 s << indent << "</DataArray>\n";
136 }
137
138 private:
140 void writeFloat64 (double data) final
141 { write_float(data); }
143 void writeFloat32 (float data) final
144 { write_float(data); }
146 void writeInt32 (std::int32_t data) final
147 { write_(data); }
149 void writeUInt32 (std::uint32_t data) final
150 { write_(data); }
152 void writeUInt8 (std::uint8_t data) final
153 { write_(data); }
154
155 template<class T>
156 void write_(T data)
157 {
158 typedef typename PrintType<T>::Type PT;
159 if(counter%numPerLine==0) s << indent;
160 else s << " ";
161 const auto original_precision = std::cout.precision();
162 s << std::setprecision(std::numeric_limits<PT>::digits10) << (PT) data;
163 std::cout.precision(original_precision);
164 counter++;
165 if (counter%numPerLine==0) s << "\n";
166 }
167
168 template<class T>
169 void write_float(T data)
170 {
171 typedef typename PrintType<T>::Type PT;
172 if(counter%numPerLine==0) s << indent;
173 else s << " ";
174 PT out_data = (PT) data;
175 if (std::fpclassify(out_data) == FP_SUBNORMAL)
176 {
177 // truncate denormalized data to 0 to avoid Paraview segfaults on macOS
178 out_data = 0;
179 }
180 const auto original_precision = std::cout.precision();
181 s << std::setprecision(std::numeric_limits<PT>::digits10) << out_data;
182 std::cout.precision(original_precision);
183 counter++;
184 if (counter%numPerLine==0) s << "\n";
185 }
186
187 std::ostream& s;
188 int counter;
189 int numPerLine;
190 Indent indent;
191 };
192
195 {
196 public:
198
208 BinaryDataArrayWriter(std::ostream& theStream, std::string name,
209 int ncomps, int nitems, const Indent& indent_, Precision prec_)
210 : DataArrayWriter(prec_), s(theStream), b64(theStream), indent(indent_)
211 {
212 s << indent << "<DataArray type=\"" << toString(prec_) << "\" "
213 << "Name=\"" << name << "\" ";
214 s << "NumberOfComponents=\"" << ncomps << "\" ";
215 s << "format=\"binary\">\n";
216
217 // write indentation for the data chunk
218 s << indent+1;
219 // store size, needs to be exactly 32 bit
220 std::uint32_t size = ncomps*nitems*typeSize(prec_);
221 b64.write(size);
222 b64.flush();
223 }
224
227 {
228 b64.flush();
229 // append newline to written data
230 s << "\n";
231 s << indent << "</DataArray>\n";
232 s.flush();
233 }
234
235 private:
237 void writeFloat64 (double data) final
238 { write_(data); }
240 void writeFloat32 (float data) final
241 { write_(data); }
243 void writeInt32 (std::int32_t data) final
244 { write_(data); }
246 void writeUInt32 (std::uint32_t data) final
247 { write_(data); }
249 void writeUInt8 (std::uint8_t data) final
250 { write_(data); }
251
253 template<class T>
254 void write_(T data)
255 {
256 b64.write(data);
257 }
258
259 std::ostream& s;
260 Base64Stream b64;
261 const Indent& indent;
262 };
263
266 {
267 public:
269
281 AppendedRawDataArrayWriter(std::ostream& s, std::string name,
282 int ncomps, unsigned nitems, unsigned& offset,
283 const Indent& indent, Precision prec_)
284 : DataArrayWriter(prec_)
285 {
286 s << indent << "<DataArray type=\"" << toString(prec_) << "\" "
287 << "Name=\"" << name << "\" ";
288 s << "NumberOfComponents=\"" << ncomps << "\" ";
289 s << "format=\"appended\" offset=\""<< offset << "\" />\n";
290 offset += 4; // header
291 offset += ncomps*nitems*typeSize(prec_);
292 }
293
295 bool writeIsNoop() const { return true; }
296
297 private:
299 void writeFloat64 (double) final {}
300 void writeFloat32 (float) final {}
301 void writeInt32 (std::int32_t) final {}
302 void writeUInt32 (std::uint32_t) final {}
303 void writeUInt8 (std::uint8_t) final {}
304 };
305
308 {
309 public:
311
323 AppendedBase64DataArrayWriter(std::ostream& s, std::string name,
324 int ncomps, unsigned nitems,
325 unsigned& offset, const Indent& indent, Precision prec_)
326 : DataArrayWriter(prec_)
327 {
328 s << indent << "<DataArray type=\"" << toString(prec_) << "\" "
329 << "Name=\"" << name << "\" ";
330 s << "NumberOfComponents=\"" << ncomps << "\" ";
331 s << "format=\"appended\" offset=\""<< offset << "\" />\n";
332 offset += 8; // header
333 std::size_t bytes = ncomps*nitems*typeSize(prec_);
334 offset += bytes/3*4;
335 if(bytes%3 != 0)
336 offset += 4;
337 }
338
340 bool writeIsNoop() const { return true; }
341
342 private:
344 void writeFloat64 (double) final {}
345 void writeFloat32 (float) final {}
346 void writeInt32 (std::int32_t) final {}
347 void writeUInt32 (std::uint32_t) final {}
348 void writeUInt8 (std::uint8_t) final {}
349 };
350
352 //
353 // Naked ArrayWriters for the appended section
354 //
355
358 {
359 public:
361
367 NakedBase64DataArrayWriter(std::ostream& theStream, int ncomps,
368 int nitems, Precision prec_)
369 : DataArrayWriter(prec_), b64(theStream)
370 {
371 // store size
372 std::uint32_t size = ncomps*nitems*typeSize(prec_);
373 b64.write(size);
374 b64.flush();
375 }
376
377 private:
379 void writeFloat64 (double data) final
380 { write_(data); }
382 void writeFloat32 (float data) final
383 { write_(data); }
385 void writeInt32 (std::int32_t data) final
386 { write_(data); }
388 void writeUInt32 (std::uint32_t data) final
389 { write_(data); }
391 void writeUInt8 (std::uint8_t data) final
392 { write_(data); }
393
395 template<class T>
396 void write_(T data)
397 {
398 b64.write(data);
399 }
400
401 Base64Stream b64;
402 };
403
406 {
407 RawStream s;
408
409 public:
411
417 NakedRawDataArrayWriter(std::ostream& theStream, int ncomps,
418 int nitems, Precision prec_)
419 : DataArrayWriter(prec_), s(theStream)
420 {
421 s.write((unsigned int)(ncomps*nitems*typeSize(prec_)));
422 }
423
424 private:
426 void writeFloat64 (double data) final
427 { write_(data); }
429 void writeFloat32 (float data) final
430 { write_(data); }
432 void writeInt32 (std::int32_t data) final
433 { write_(data); }
435 void writeUInt32 (std::uint32_t data) final
436 { write_(data); }
438 void writeUInt8 (std::uint8_t data) final
439 { write_(data); }
440
442 template<class T>
443 void write_(T data)
444 {
445 s.write(data);
446 }
447 };
448
450 //
451 // Factory
452 //
453
455
461 enum Phase { main, appended };
462
463 OutputType type;
464 std::ostream& stream;
465 unsigned offset;
467 Phase phase;
468
469 public:
471
480 inline DataArrayWriterFactory(OutputType type_, std::ostream& stream_)
481 : type(type_), stream(stream_), offset(0), phase(main)
482 { }
483
485
495 inline bool beginAppended() {
496 phase = appended;
497 switch(type) {
498 case ascii : return false;
499 case base64 : return false;
500 case appendedraw : return true;
501 case appendedbase64 : return true;
502 }
503 DUNE_THROW(IOError, "Dune::VTK::DataArrayWriter: unsupported "
504 "OutputType " << type);
505 }
506
508 const std::string& appendedEncoding() const {
509 static const std::string rawString = "raw";
510 static const std::string base64String = "base64";
511
512 switch(type) {
513 case ascii :
514 case base64 :
515 DUNE_THROW(IOError, "DataArrayWriterFactory::appendedEncoding(): No "
516 "appended encoding for OutputType " << type);
517 case appendedraw : return rawString;
518 case appendedbase64 : return base64String;
519 }
520 DUNE_THROW(IOError, "DataArrayWriterFactory::appendedEncoding(): "
521 "unsupported OutputType " << type);
522 }
523
525
539 DataArrayWriter* make(const std::string& name, unsigned ncomps,
540 unsigned nitems, const Indent& indent,
541 Precision prec)
542 {
543 switch(phase) {
544 case main :
545 switch(type) {
546 case ascii :
547 return new AsciiDataArrayWriter(stream, name, ncomps, indent, prec);
548 case base64 :
549 return new BinaryDataArrayWriter(stream, name, ncomps, nitems,
550 indent, prec);
551 case appendedraw :
552 return new AppendedRawDataArrayWriter(stream, name, ncomps,
553 nitems, offset, indent, prec);
554 case appendedbase64 :
555 return new AppendedBase64DataArrayWriter(stream, name, ncomps,
556 nitems, offset,
557 indent, prec);
558 }
559 break;
560 case appended :
561 switch(type) {
562 case ascii :
563 case base64 :
564 break; // invlid in appended mode
565 case appendedraw :
566 return new NakedRawDataArrayWriter(stream, ncomps, nitems, prec);
567 case appendedbase64 :
568 return new NakedBase64DataArrayWriter(stream, ncomps, nitems, prec);
569 }
570 break;
571 }
572 DUNE_THROW(IOError, "Dune::VTK::DataArrayWriter: unsupported "
573 "OutputType " << type << " in phase " << phase);
574 }
575 };
576
577 } // namespace VTK
578
580
581} // namespace Dune
582
583#endif // DUNE_GRID_IO_FILE_VTK_DATAARRAYWRITER_HH
void write(X &data)
encode a data item
Definition: streams.hh:40
void flush()
flush the current unwritten data to the stream.
Definition: streams.hh:62
Default exception class for I/O errors.
Definition: exceptions.hh:229
Utility class for handling nested indentation in output.
Definition: indent.hh:51
Default exception for dummy implementations.
Definition: exceptions.hh:261
write out data in binary
Definition: streams.hh:82
a streaming writer for data array tags, uses appended base64 format
Definition: dataarraywriter.hh:308
AppendedBase64DataArrayWriter(std::ostream &s, std::string name, int ncomps, unsigned nitems, unsigned &offset, const Indent &indent, Precision prec_)
make a new data array writer
Definition: dataarraywriter.hh:323
bool writeIsNoop() const
whether calls to write may be skipped
Definition: dataarraywriter.hh:340
a streaming writer for data array tags, uses appended raw format
Definition: dataarraywriter.hh:266
AppendedRawDataArrayWriter(std::ostream &s, std::string name, int ncomps, unsigned nitems, unsigned &offset, const Indent &indent, Precision prec_)
make a new data array writer
Definition: dataarraywriter.hh:281
bool writeIsNoop() const
whether calls to write may be skipped
Definition: dataarraywriter.hh:295
a streaming writer for data array tags, uses ASCII inline format
Definition: dataarraywriter.hh:108
~AsciiDataArrayWriter()
finish output; writes end tag
Definition: dataarraywriter.hh:131
AsciiDataArrayWriter(std::ostream &theStream, std::string name, int ncomps, const Indent &indent_, Precision prec_)
make a new data array writer
Definition: dataarraywriter.hh:119
a streaming writer for data array tags, uses binary inline format
Definition: dataarraywriter.hh:195
~BinaryDataArrayWriter()
finish output; writes end tag
Definition: dataarraywriter.hh:226
BinaryDataArrayWriter(std::ostream &theStream, std::string name, int ncomps, int nitems, const Indent &indent_, Precision prec_)
make a new data array writer
Definition: dataarraywriter.hh:208
a factory for DataArrayWriters
Definition: dataarraywriter.hh:460
bool beginAppended()
signal start of the appended section
Definition: dataarraywriter.hh:495
DataArrayWriter * make(const std::string &name, unsigned ncomps, unsigned nitems, const Indent &indent, Precision prec)
create a DataArrayWriter
Definition: dataarraywriter.hh:539
DataArrayWriterFactory(OutputType type_, std::ostream &stream_)
create a DataArrayWriterFactory
Definition: dataarraywriter.hh:480
const std::string & appendedEncoding() const
query encoding string for appended data
Definition: dataarraywriter.hh:508
base class for data array writers
Definition: dataarraywriter.hh:54
void write(T data)
write one element of data
Definition: dataarraywriter.hh:67
DataArrayWriter(Precision _prec)
construct a data array writer
Definition: dataarraywriter.hh:61
virtual bool writeIsNoop() const
whether calls to write may be skipped
Definition: dataarraywriter.hh:87
virtual ~DataArrayWriter()
virtual destructor
Definition: dataarraywriter.hh:89
a streaming writer for appended data array tags, uses base64 format
Definition: dataarraywriter.hh:358
NakedBase64DataArrayWriter(std::ostream &theStream, int ncomps, int nitems, Precision prec_)
make a new data array writer
Definition: dataarraywriter.hh:367
a streaming writer for appended data arrays, uses raw format
Definition: dataarraywriter.hh:406
NakedRawDataArrayWriter(std::ostream &theStream, int ncomps, int nitems, Precision prec_)
make a new data array writer
Definition: dataarraywriter.hh:417
A few common exception classes.
Common stuff for the VTKWriter.
Precision
which precision to use when writing out data to vtk files
Definition: common.hh:269
OutputType
How the bulk data should be stored in the file.
Definition: common.hh:41
@ ascii
Output to the file is in ascii.
Definition: common.hh:43
@ appendedraw
Output is to the file is appended raw binary.
Definition: common.hh:47
@ appendedbase64
Output is to the file is appended base64 binary.
Definition: common.hh:49
@ base64
Output to the file is inline base64 binary.
Definition: common.hh:45
std::string toString(Precision p)
map precision to VTK type name
Definition: common.hh:278
std::size_t typeSize(Precision p)
map precision to byte size
Definition: common.hh:298
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
Utility class for handling nested indentation in output.
Dune namespace.
Definition: alignedallocator.hh:11
T Type
type to convert T to before putting it into a stream with <<
Definition: common.hh:95
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 22, 23:30, 2024)