Dune Core Modules (unstable)

dataarraywriter.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright © 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
17#include <dune/common/indent.hh>
18
19#include <dune/grid/io/file/vtk/streams.hh>
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 {
73 case Precision::float32:
74 writeFloat32(data); break;
75 case Precision::float64:
76 writeFloat64(data); break;
77 case Precision::uint32:
78 writeUInt32(data); break;
79 case Precision::uint8:
80 writeUInt8(data); break;
81 case Precision::int32:
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
122 AsciiDataArrayWriter(std::ostream& theStream, std::string name,
123 int ncomps, const Indent& indent_, Precision prec_)
124 : DataArrayWriter(prec_), s(theStream), counter(0), numPerLine(12), indent(indent_)
125 {
126 s << indent << "<DataArray type=\"" << toString(prec_) << "\" "
127 << "Name=\"" << name << "\" ";
128 s << "NumberOfComponents=\"" << ncomps << "\" ";
129 s << "format=\"ascii\">\n";
130 ++indent;
131 }
132
135 {
136 if (counter%numPerLine!=0) s << "\n";
137 --indent;
138 s << indent << "</DataArray>\n";
139 }
140
141 private:
143 void writeFloat64 (double data) final
144 { write_float(data); }
146 void writeFloat32 (float data) final
147 { write_float(data); }
149 void writeInt32 (std::int32_t data) final
150 { write_(data); }
152 void writeUInt32 (std::uint32_t data) final
153 { write_(data); }
155 void writeUInt8 (std::uint8_t data) final
156 { write_(data); }
157
158 template<class T>
159 void write_(T data)
160 {
161 typedef typename PrintType<T>::Type PT;
162 if(counter%numPerLine==0) s << indent;
163 else s << " ";
164 const auto original_precision = std::cout.precision();
165 s << std::setprecision(std::numeric_limits<PT>::digits10) << (PT) data;
166 std::cout.precision(original_precision);
167 counter++;
168 if (counter%numPerLine==0) s << "\n";
169 }
170
171 template<class T>
172 void write_float(T data)
173 {
174 typedef typename PrintType<T>::Type PT;
175 if(counter%numPerLine==0) s << indent;
176 else s << " ";
177 PT out_data = (PT) data;
178 if (std::fpclassify(out_data) == FP_SUBNORMAL)
179 {
180 // truncate denormalized data to 0 to avoid Paraview segfaults on macOS
181 out_data = 0;
182 }
183 const auto original_precision = std::cout.precision();
184 s << std::setprecision(std::numeric_limits<PT>::digits10) << out_data;
185 std::cout.precision(original_precision);
186 counter++;
187 if (counter%numPerLine==0) s << "\n";
188 }
189
190 std::ostream& s;
191 int counter;
192 int numPerLine;
193 Indent indent;
194 };
195
198 {
199 public:
201
212 BinaryDataArrayWriter(std::ostream& theStream, std::string name,
213 int ncomps, int nitems, const Indent& indent_, Precision prec_)
214 : DataArrayWriter(prec_), s(theStream), b64(theStream), indent(indent_)
215 {
216 s << indent << "<DataArray type=\"" << toString(prec_) << "\" "
217 << "Name=\"" << name << "\" ";
218 s << "NumberOfComponents=\"" << ncomps << "\" ";
219 s << "format=\"binary\">\n";
220
221 // write indentation for the data chunk
222 s << indent+1;
223 // store size, needs to be exactly 32 bit
224 std::uint32_t size = ncomps*nitems*typeSize(prec_);
225 b64.write(size);
226 b64.flush();
227 }
228
231 {
232 b64.flush();
233 // append newline to written data
234 s << "\n";
235 s << indent << "</DataArray>\n";
236 s.flush();
237 }
238
239 private:
241 void writeFloat64 (double data) final
242 { write_(data); }
244 void writeFloat32 (float data) final
245 { write_(data); }
247 void writeInt32 (std::int32_t data) final
248 { write_(data); }
250 void writeUInt32 (std::uint32_t data) final
251 { write_(data); }
253 void writeUInt8 (std::uint8_t data) final
254 { write_(data); }
255
257 template<class T>
258 void write_(T data)
259 {
260 b64.write(data);
261 }
262
263 std::ostream& s;
264 Base64Stream b64;
265 const Indent& indent;
266 };
267
270 {
271 public:
273
286 AppendedRawDataArrayWriter(std::ostream& s, std::string name,
287 int ncomps, unsigned nitems, unsigned& offset,
288 const Indent& indent, Precision prec_)
289 : DataArrayWriter(prec_)
290 {
291 s << indent << "<DataArray type=\"" << toString(prec_) << "\" "
292 << "Name=\"" << name << "\" ";
293 s << "NumberOfComponents=\"" << ncomps << "\" ";
294 s << "format=\"appended\" offset=\""<< offset << "\" />\n";
295 offset += 4; // header
296 offset += ncomps*nitems*typeSize(prec_);
297 }
298
300 bool writeIsNoop() const { return true; }
301
302 private:
304 void writeFloat64 (double) final {}
305 void writeFloat32 (float) final {}
306 void writeInt32 (std::int32_t) final {}
307 void writeUInt32 (std::uint32_t) final {}
308 void writeUInt8 (std::uint8_t) final {}
309 };
310
313 {
314 public:
316
329 AppendedBase64DataArrayWriter(std::ostream& s, std::string name,
330 int ncomps, unsigned nitems,
331 unsigned& offset, const Indent& indent, Precision prec_)
332 : DataArrayWriter(prec_)
333 {
334 s << indent << "<DataArray type=\"" << toString(prec_) << "\" "
335 << "Name=\"" << name << "\" ";
336 s << "NumberOfComponents=\"" << ncomps << "\" ";
337 s << "format=\"appended\" offset=\""<< offset << "\" />\n";
338 offset += 8; // header
339 std::size_t bytes = ncomps*nitems*typeSize(prec_);
340 offset += bytes/3*4;
341 if(bytes%3 != 0)
342 offset += 4;
343 }
344
346 bool writeIsNoop() const { return true; }
347
348 private:
350 void writeFloat64 (double) final {}
351 void writeFloat32 (float) final {}
352 void writeInt32 (std::int32_t) final {}
353 void writeUInt32 (std::uint32_t) final {}
354 void writeUInt8 (std::uint8_t) final {}
355 };
356
358 //
359 // Naked ArrayWriters for the appended section
360 //
361
364 {
365 public:
367
374 NakedBase64DataArrayWriter(std::ostream& theStream, int ncomps,
375 int nitems, Precision prec_)
376 : DataArrayWriter(prec_), b64(theStream)
377 {
378 // store size
379 std::uint32_t size = ncomps*nitems*typeSize(prec_);
380 b64.write(size);
381 b64.flush();
382 }
383
384 private:
386 void writeFloat64 (double data) final
387 { write_(data); }
389 void writeFloat32 (float data) final
390 { write_(data); }
392 void writeInt32 (std::int32_t data) final
393 { write_(data); }
395 void writeUInt32 (std::uint32_t data) final
396 { write_(data); }
398 void writeUInt8 (std::uint8_t data) final
399 { write_(data); }
400
402 template<class T>
403 void write_(T data)
404 {
405 b64.write(data);
406 }
407
408 Base64Stream b64;
409 };
410
413 {
414 RawStream s;
415
416 public:
418
425 NakedRawDataArrayWriter(std::ostream& theStream, int ncomps,
426 int nitems, Precision prec_)
427 : DataArrayWriter(prec_), s(theStream)
428 {
429 s.write((unsigned int)(ncomps*nitems*typeSize(prec_)));
430 }
431
432 private:
434 void writeFloat64 (double data) final
435 { write_(data); }
437 void writeFloat32 (float data) final
438 { write_(data); }
440 void writeInt32 (std::int32_t data) final
441 { write_(data); }
443 void writeUInt32 (std::uint32_t data) final
444 { write_(data); }
446 void writeUInt8 (std::uint8_t data) final
447 { write_(data); }
448
450 template<class T>
451 void write_(T data)
452 {
453 s.write(data);
454 }
455 };
456
458 //
459 // Factory
460 //
461
463
469 enum Phase { main, appended };
470
471 OutputType type;
472 std::ostream& stream;
473 unsigned offset;
475 Phase phase;
476
477 public:
479
488 inline DataArrayWriterFactory(OutputType type_, std::ostream& stream_)
489 : type(type_), stream(stream_), offset(0), phase(main)
490 { }
491
493
503 inline bool beginAppended() {
504 phase = appended;
505 switch(type) {
506 case ascii : return false;
507 case base64 : return false;
508 case appendedraw : return true;
509 case appendedbase64 : return true;
510 }
511 DUNE_THROW(IOError, "Dune::VTK::DataArrayWriter: unsupported "
512 "OutputType " << type);
513 }
514
516 const std::string& appendedEncoding() const {
517 static const std::string rawString = "raw";
518 static const std::string base64String = "base64";
519
520 switch(type) {
521 case ascii :
522 case base64 :
523 DUNE_THROW(IOError, "DataArrayWriterFactory::appendedEncoding(): No "
524 "appended encoding for OutputType " << type);
525 case appendedraw : return rawString;
526 case appendedbase64 : return base64String;
527 }
528 DUNE_THROW(IOError, "DataArrayWriterFactory::appendedEncoding(): "
529 "unsupported OutputType " << type);
530 }
531
533
547 DataArrayWriter* make(const std::string& name, unsigned ncomps,
548 unsigned nitems, const Indent& indent,
549 Precision prec)
550 {
551 switch(phase) {
552 case main :
553 switch(type) {
554 case ascii :
555 return new AsciiDataArrayWriter(stream, name, ncomps, indent, prec);
556 case base64 :
557 return new BinaryDataArrayWriter(stream, name, ncomps, nitems,
558 indent, prec);
559 case appendedraw :
560 return new AppendedRawDataArrayWriter(stream, name, ncomps,
561 nitems, offset, indent, prec);
562 case appendedbase64 :
563 return new AppendedBase64DataArrayWriter(stream, name, ncomps,
564 nitems, offset,
565 indent, prec);
566 }
567 break;
568 case appended :
569 switch(type) {
570 case ascii :
571 case base64 :
572 break; // invalid in appended mode
573 case appendedraw :
574 return new NakedRawDataArrayWriter(stream, ncomps, nitems, prec);
575 case appendedbase64 :
576 return new NakedBase64DataArrayWriter(stream, ncomps, nitems, prec);
577 }
578 break;
579 }
580 DUNE_THROW(IOError, "Dune::VTK::DataArrayWriter: unsupported "
581 "OutputType " << type << " in phase " << phase);
582 }
583 };
584
585 } // namespace VTK
586
588
589} // namespace Dune
590
591#endif // DUNE_GRID_IO_FILE_VTK_DATAARRAYWRITER_HH
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
Default exception class for I/O errors.
Definition: exceptions.hh:325
Utility class for handling nested indentation in output.
Definition: indent.hh:53
Default exception for dummy implementations.
Definition: exceptions.hh:357
write out data in binary
Definition: streams.hh:84
void write(T data)
write data to stream
Definition: streams.hh:93
a streaming writer for data array tags, uses appended base64 format
Definition: dataarraywriter.hh:313
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:329
bool writeIsNoop() const
whether calls to write may be skipped
Definition: dataarraywriter.hh:346
a streaming writer for data array tags, uses appended raw format
Definition: dataarraywriter.hh:270
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:286
bool writeIsNoop() const
whether calls to write may be skipped
Definition: dataarraywriter.hh:300
a streaming writer for data array tags, uses ASCII inline format
Definition: dataarraywriter.hh:110
~AsciiDataArrayWriter()
finish output; writes end tag
Definition: dataarraywriter.hh:134
AsciiDataArrayWriter(std::ostream &theStream, std::string name, int ncomps, const Indent &indent_, Precision prec_)
make a new data array writer
Definition: dataarraywriter.hh:122
a streaming writer for data array tags, uses binary inline format
Definition: dataarraywriter.hh:198
~BinaryDataArrayWriter()
finish output; writes end tag
Definition: dataarraywriter.hh:230
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:212
a factory for DataArrayWriters
Definition: dataarraywriter.hh:468
bool beginAppended()
signal start of the appended section
Definition: dataarraywriter.hh:503
DataArrayWriter * make(const std::string &name, unsigned ncomps, unsigned nitems, const Indent &indent, Precision prec)
create a DataArrayWriter
Definition: dataarraywriter.hh:547
DataArrayWriterFactory(OutputType type_, std::ostream &stream_)
create a DataArrayWriterFactory
Definition: dataarraywriter.hh:488
const std::string & appendedEncoding() const
query encoding string for appended data
Definition: dataarraywriter.hh:516
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 appended data array tags, uses base64 format
Definition: dataarraywriter.hh:364
NakedBase64DataArrayWriter(std::ostream &theStream, int ncomps, int nitems, Precision prec_)
make a new data array writer
Definition: dataarraywriter.hh:374
a streaming writer for appended data arrays, uses raw format
Definition: dataarraywriter.hh:413
NakedRawDataArrayWriter(std::ostream &theStream, int ncomps, int nitems, Precision prec_)
make a new data array writer
Definition: dataarraywriter.hh:425
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: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
#define DUNE_THROW(E,...)
Definition: exceptions.hh:314
Utility class for handling nested indentation in output.
Dune namespace
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
T Type
type to convert T to before putting it into a stream with <<
Definition: common.hh:97
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Jan 9, 23:34, 2026)