dune-grid 2.9.0
dataarraywriter.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4// vi: set et ts=4 sw=2 sts=2:
5
6#ifndef DUNE_GRID_IO_FILE_VTK_DATAARRAYWRITER_HH
7#define DUNE_GRID_IO_FILE_VTK_DATAARRAYWRITER_HH
8
9#include <cstdint>
10#include <iostream>
11#include <string>
12#include <iomanip>
13#include <cstdint>
14#include <cmath>
15
16#include <dune/common/exceptions.hh>
17#include <dune/common/indent.hh>
18
21
30namespace Dune
31{
34
35 namespace VTK {
36
38
56 {
57 public:
59
64 : prec(_prec)
65 {}
66
68 template<class T>
69 void write(T data)
70 {
71 switch(prec)
72 {
74 writeFloat32(data); break;
76 writeFloat64(data); break;
78 writeUInt32(data); break;
80 writeUInt8(data); break;
82 writeInt32(data); break;
83 default:
84 DUNE_THROW(Dune::NotImplemented, "Unknown precision type");
85 }
86 }
87
89 virtual bool writeIsNoop() const { return false; }
91 virtual ~DataArrayWriter () {}
92
93 private:
95 virtual void writeFloat32 (float data) = 0;
97 virtual void writeFloat64 (double data) = 0;
99 virtual void writeInt32 (std::int32_t data) = 0;
101 virtual void writeUInt8 (std::uint8_t data) = 0;
103 virtual void writeUInt32 (std::uint32_t data) = 0;
104
105 Precision prec;
106 };
107
110 {
111 public:
113
121 AsciiDataArrayWriter(std::ostream& theStream, std::string name,
122 int ncomps, const Indent& indent_, Precision prec_)
123 : DataArrayWriter(prec_), s(theStream), counter(0), numPerLine(12), indent(indent_)
124 {
125 s << indent << "<DataArray type=\"" << toString(prec_) << "\" "
126 << "Name=\"" << name << "\" ";
127 s << "NumberOfComponents=\"" << ncomps << "\" ";
128 s << "format=\"ascii\">\n";
129 ++indent;
130 }
131
134 {
135 if (counter%numPerLine!=0) s << "\n";
136 --indent;
137 s << indent << "</DataArray>\n";
138 }
139
140 private:
142 void writeFloat64 (double data) final
143 { write_float(data); }
145 void writeFloat32 (float data) final
146 { write_float(data); }
148 void writeInt32 (std::int32_t data) final
149 { write_(data); }
151 void writeUInt32 (std::uint32_t data) final
152 { write_(data); }
154 void writeUInt8 (std::uint8_t data) final
155 { write_(data); }
156
157 template<class T>
158 void write_(T data)
159 {
160 typedef typename PrintType<T>::Type PT;
161 if(counter%numPerLine==0) s << indent;
162 else s << " ";
163 const auto original_precision = std::cout.precision();
164 s << std::setprecision(std::numeric_limits<PT>::digits10) << (PT) data;
165 std::cout.precision(original_precision);
166 counter++;
167 if (counter%numPerLine==0) s << "\n";
168 }
169
170 template<class T>
171 void write_float(T data)
172 {
173 typedef typename PrintType<T>::Type PT;
174 if(counter%numPerLine==0) s << indent;
175 else s << " ";
176 PT out_data = (PT) data;
177 if (std::fpclassify(out_data) == FP_SUBNORMAL)
178 {
179 // truncate denormalized data to 0 to avoid Paraview segfaults on macOS
180 out_data = 0;
181 }
182 const auto original_precision = std::cout.precision();
183 s << std::setprecision(std::numeric_limits<PT>::digits10) << out_data;
184 std::cout.precision(original_precision);
185 counter++;
186 if (counter%numPerLine==0) s << "\n";
187 }
188
189 std::ostream& s;
190 int counter;
191 int numPerLine;
192 Indent indent;
193 };
194
197 {
198 public:
200
210 BinaryDataArrayWriter(std::ostream& theStream, std::string name,
211 int ncomps, int nitems, const Indent& indent_, Precision prec_)
212 : DataArrayWriter(prec_), s(theStream), b64(theStream), indent(indent_)
213 {
214 s << indent << "<DataArray type=\"" << toString(prec_) << "\" "
215 << "Name=\"" << name << "\" ";
216 s << "NumberOfComponents=\"" << ncomps << "\" ";
217 s << "format=\"binary\">\n";
218
219 // write indentation for the data chunk
220 s << indent+1;
221 // store size, needs to be exactly 32 bit
222 std::uint32_t size = ncomps*nitems*typeSize(prec_);
223 b64.write(size);
224 b64.flush();
225 }
226
229 {
230 b64.flush();
231 // append newline to written data
232 s << "\n";
233 s << indent << "</DataArray>\n";
234 s.flush();
235 }
236
237 private:
239 void writeFloat64 (double data) final
240 { write_(data); }
242 void writeFloat32 (float data) final
243 { write_(data); }
245 void writeInt32 (std::int32_t data) final
246 { write_(data); }
248 void writeUInt32 (std::uint32_t data) final
249 { write_(data); }
251 void writeUInt8 (std::uint8_t data) final
252 { write_(data); }
253
255 template<class T>
256 void write_(T data)
257 {
258 b64.write(data);
259 }
260
261 std::ostream& s;
262 Base64Stream b64;
263 const Indent& indent;
264 };
265
268 {
269 public:
271
283 AppendedRawDataArrayWriter(std::ostream& s, std::string name,
284 int ncomps, unsigned nitems, unsigned& offset,
285 const Indent& indent, Precision prec_)
286 : DataArrayWriter(prec_)
287 {
288 s << indent << "<DataArray type=\"" << toString(prec_) << "\" "
289 << "Name=\"" << name << "\" ";
290 s << "NumberOfComponents=\"" << ncomps << "\" ";
291 s << "format=\"appended\" offset=\""<< offset << "\" />\n";
292 offset += 4; // header
293 offset += ncomps*nitems*typeSize(prec_);
294 }
295
297 bool writeIsNoop() const { return true; }
298
299 private:
301 void writeFloat64 (double) final {}
302 void writeFloat32 (float) final {}
303 void writeInt32 (std::int32_t) final {}
304 void writeUInt32 (std::uint32_t) final {}
305 void writeUInt8 (std::uint8_t) final {}
306 };
307
310 {
311 public:
313
325 AppendedBase64DataArrayWriter(std::ostream& s, std::string name,
326 int ncomps, unsigned nitems,
327 unsigned& offset, const Indent& indent, Precision prec_)
328 : DataArrayWriter(prec_)
329 {
330 s << indent << "<DataArray type=\"" << toString(prec_) << "\" "
331 << "Name=\"" << name << "\" ";
332 s << "NumberOfComponents=\"" << ncomps << "\" ";
333 s << "format=\"appended\" offset=\""<< offset << "\" />\n";
334 offset += 8; // header
335 std::size_t bytes = ncomps*nitems*typeSize(prec_);
336 offset += bytes/3*4;
337 if(bytes%3 != 0)
338 offset += 4;
339 }
340
342 bool writeIsNoop() const { return true; }
343
344 private:
346 void writeFloat64 (double) final {}
347 void writeFloat32 (float) final {}
348 void writeInt32 (std::int32_t) final {}
349 void writeUInt32 (std::uint32_t) final {}
350 void writeUInt8 (std::uint8_t) final {}
351 };
352
354 //
355 // Naked ArrayWriters for the appended section
356 //
357
360 {
361 public:
363
369 NakedBase64DataArrayWriter(std::ostream& theStream, int ncomps,
370 int nitems, Precision prec_)
371 : DataArrayWriter(prec_), b64(theStream)
372 {
373 // store size
374 std::uint32_t size = ncomps*nitems*typeSize(prec_);
375 b64.write(size);
376 b64.flush();
377 }
378
379 private:
381 void writeFloat64 (double data) final
382 { write_(data); }
384 void writeFloat32 (float data) final
385 { write_(data); }
387 void writeInt32 (std::int32_t data) final
388 { write_(data); }
390 void writeUInt32 (std::uint32_t data) final
391 { write_(data); }
393 void writeUInt8 (std::uint8_t data) final
394 { write_(data); }
395
397 template<class T>
398 void write_(T data)
399 {
400 b64.write(data);
401 }
402
403 Base64Stream b64;
404 };
405
408 {
409 RawStream s;
410
411 public:
413
419 NakedRawDataArrayWriter(std::ostream& theStream, int ncomps,
420 int nitems, Precision prec_)
421 : DataArrayWriter(prec_), s(theStream)
422 {
423 s.write((unsigned int)(ncomps*nitems*typeSize(prec_)));
424 }
425
426 private:
428 void writeFloat64 (double data) final
429 { write_(data); }
431 void writeFloat32 (float data) final
432 { write_(data); }
434 void writeInt32 (std::int32_t data) final
435 { write_(data); }
437 void writeUInt32 (std::uint32_t data) final
438 { write_(data); }
440 void writeUInt8 (std::uint8_t data) final
441 { write_(data); }
442
444 template<class T>
445 void write_(T data)
446 {
447 s.write(data);
448 }
449 };
450
452 //
453 // Factory
454 //
455
457
463 enum Phase { main, appended };
464
465 OutputType type;
466 std::ostream& stream;
467 unsigned offset;
469 Phase phase;
470
471 public:
473
482 inline DataArrayWriterFactory(OutputType type_, std::ostream& stream_)
483 : type(type_), stream(stream_), offset(0), phase(main)
484 { }
485
487
497 inline bool beginAppended() {
498 phase = appended;
499 switch(type) {
500 case ascii : return false;
501 case base64 : return false;
502 case appendedraw : return true;
503 case appendedbase64 : return true;
504 }
505 DUNE_THROW(IOError, "Dune::VTK::DataArrayWriter: unsupported "
506 "OutputType " << type);
507 }
508
510 const std::string& appendedEncoding() const {
511 static const std::string rawString = "raw";
512 static const std::string base64String = "base64";
513
514 switch(type) {
515 case ascii :
516 case base64 :
517 DUNE_THROW(IOError, "DataArrayWriterFactory::appendedEncoding(): No "
518 "appended encoding for OutputType " << type);
519 case appendedraw : return rawString;
520 case appendedbase64 : return base64String;
521 }
522 DUNE_THROW(IOError, "DataArrayWriterFactory::appendedEncoding(): "
523 "unsupported OutputType " << type);
524 }
525
527
541 DataArrayWriter* make(const std::string& name, unsigned ncomps,
542 unsigned nitems, const Indent& indent,
543 Precision prec)
544 {
545 switch(phase) {
546 case main :
547 switch(type) {
548 case ascii :
549 return new AsciiDataArrayWriter(stream, name, ncomps, indent, prec);
550 case base64 :
551 return new BinaryDataArrayWriter(stream, name, ncomps, nitems,
552 indent, prec);
553 case appendedraw :
554 return new AppendedRawDataArrayWriter(stream, name, ncomps,
555 nitems, offset, indent, prec);
556 case appendedbase64 :
557 return new AppendedBase64DataArrayWriter(stream, name, ncomps,
558 nitems, offset,
559 indent, prec);
560 }
561 break;
562 case appended :
563 switch(type) {
564 case ascii :
565 case base64 :
566 break; // invlid in appended mode
567 case appendedraw :
568 return new NakedRawDataArrayWriter(stream, ncomps, nitems, prec);
569 case appendedbase64 :
570 return new NakedBase64DataArrayWriter(stream, ncomps, nitems, prec);
571 }
572 break;
573 }
574 DUNE_THROW(IOError, "Dune::VTK::DataArrayWriter: unsupported "
575 "OutputType " << type << " in phase " << phase);
576 }
577 };
578
579 } // namespace VTK
580
582
583} // namespace Dune
584
585#endif // DUNE_GRID_IO_FILE_VTK_DATAARRAYWRITER_HH
Common stuff for the VTKWriter.
Include standard header files.
Definition: agrid.hh:60
Precision
which precision to use when writing out data to vtk files
Definition: common.hh:271
OutputType
How the bulk data should be stored in the file.
Definition: common.hh:43
@ ascii
Output to the file is in ascii.
Definition: common.hh:45
@ appendedraw
Output is to the file is appended raw binary.
Definition: common.hh:49
@ appendedbase64
Output is to the file is appended base64 binary.
Definition: common.hh:51
@ base64
Output to the file is inline base64 binary.
Definition: common.hh:47
std::string toString(Precision p)
map precision to VTK type name
Definition: common.hh:280
std::size_t typeSize(Precision p)
map precision to byte size
Definition: common.hh:300
T Type
type to convert T to before putting it into a stream with <<
Definition: common.hh:97
base class for data array writers
Definition: dataarraywriter.hh:56
void write(T data)
write one element of data
Definition: dataarraywriter.hh:69
DataArrayWriter(Precision _prec)
construct a data array writer
Definition: dataarraywriter.hh:63
virtual bool writeIsNoop() const
whether calls to write may be skipped
Definition: dataarraywriter.hh:89
virtual ~DataArrayWriter()
virtual destructor
Definition: dataarraywriter.hh:91
a streaming writer for data array tags, uses ASCII inline format
Definition: dataarraywriter.hh:110
~AsciiDataArrayWriter()
finish output; writes end tag
Definition: dataarraywriter.hh:133
AsciiDataArrayWriter(std::ostream &theStream, std::string name, int ncomps, const Indent &indent_, Precision prec_)
make a new data array writer
Definition: dataarraywriter.hh:121
a streaming writer for data array tags, uses binary inline format
Definition: dataarraywriter.hh:197
~BinaryDataArrayWriter()
finish output; writes end tag
Definition: dataarraywriter.hh:228
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:210
a streaming writer for data array tags, uses appended raw format
Definition: dataarraywriter.hh:268
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:283
bool writeIsNoop() const
whether calls to write may be skipped
Definition: dataarraywriter.hh:297
a streaming writer for data array tags, uses appended base64 format
Definition: dataarraywriter.hh:310
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:325
bool writeIsNoop() const
whether calls to write may be skipped
Definition: dataarraywriter.hh:342
a streaming writer for appended data array tags, uses base64 format
Definition: dataarraywriter.hh:360
NakedBase64DataArrayWriter(std::ostream &theStream, int ncomps, int nitems, Precision prec_)
make a new data array writer
Definition: dataarraywriter.hh:369
a streaming writer for appended data arrays, uses raw format
Definition: dataarraywriter.hh:408
NakedRawDataArrayWriter(std::ostream &theStream, int ncomps, int nitems, Precision prec_)
make a new data array writer
Definition: dataarraywriter.hh:419
a factory for DataArrayWriters
Definition: dataarraywriter.hh:462
bool beginAppended()
signal start of the appended section
Definition: dataarraywriter.hh:497
DataArrayWriter * make(const std::string &name, unsigned ncomps, unsigned nitems, const Indent &indent, Precision prec)
create a DataArrayWriter
Definition: dataarraywriter.hh:541
DataArrayWriterFactory(OutputType type_, std::ostream &stream_)
create a DataArrayWriterFactory
Definition: dataarraywriter.hh:482
const std::string & appendedEncoding() const
query encoding string for appended data
Definition: dataarraywriter.hh:510
void write(X &data)
encode a data item
Definition: streams.hh:42
void flush()
flush the current unwritten data to the stream.
Definition: streams.hh:64
write out data in binary
Definition: streams.hh:84
void write(T data)
write data to stream
Definition: streams.hh:93