dune-grid  2.7.0
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 
14 #include <dune/common/exceptions.hh>
15 #include <dune/common/indent.hh>
16 
19 
28 namespace 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 data) final {}
300  void writeFloat32 (float data) final {}
301  void writeInt32 (std::int32_t data) final {}
302  void writeUInt32 (std::uint32_t data) final {}
303  void writeUInt8 (std::uint8_t data) 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 data) final {}
345  void writeFloat32 (float data) final {}
346  void writeInt32 (std::int32_t data) final {}
347  void writeUInt32 (std::uint32_t data) final {}
348  void writeUInt8 (std::uint8_t data) 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
Dune::VTK::AppendedBase64DataArrayWriter::writeIsNoop
bool writeIsNoop() const
whether calls to write may be skipped
Definition: dataarraywriter.hh:340
Dune::VTK::appendedraw
@ appendedraw
Output is to the file is appended raw binary.
Definition: common.hh:48
Dune::Base64Stream::write
void write(X &data)
encode a data item
Definition: streams.hh:40
uint8_t
unsigned char uint8_t
Definition: yaspgrid.hh:16
Dune::VTK::BinaryDataArrayWriter::~BinaryDataArrayWriter
~BinaryDataArrayWriter()
finish output; writes end tag
Definition: dataarraywriter.hh:226
Dune::RawStream::write
void write(T data)
write data to stream
Definition: streams.hh:91
Dune::VTK::DataArrayWriterFactory::appendedEncoding
const std::string & appendedEncoding() const
query encoding string for appended data
Definition: dataarraywriter.hh:508
Dune::VTK::NakedBase64DataArrayWriter
a streaming writer for appended data array tags, uses base64 format
Definition: dataarraywriter.hh:357
Dune::VTK::DataArrayWriterFactory::make
DataArrayWriter * make(const std::string &name, unsigned ncomps, unsigned nitems, const Indent &indent, Precision prec)
create a DataArrayWriter
Definition: dataarraywriter.hh:539
Dune::VTK::AppendedRawDataArrayWriter
a streaming writer for data array tags, uses appended raw format
Definition: dataarraywriter.hh:265
Dune::VTK::DataArrayWriter::writeIsNoop
virtual bool writeIsNoop() const
whether calls to write may be skipped
Definition: dataarraywriter.hh:87
Dune::VTK::DataArrayWriter
base class for data array writers
Definition: dataarraywriter.hh:53
Dune::VTK::DataArrayWriter::write
void write(T data)
write one element of data
Definition: dataarraywriter.hh:67
Dune::VTK::PrintType::Type
T Type
type to convert T to before putting it into a stream with <<
Definition: common.hh:96
Dune::VTK::Precision::uint32
@ uint32
Dune::Base64Stream::flush
void flush()
flush the current unwritten data to the stream.
Definition: streams.hh:62
Dune::VTK::ascii
@ ascii
Output to the file is in ascii.
Definition: common.hh:44
Dune::VTK::DataArrayWriterFactory
a factory for DataArrayWriters
Definition: dataarraywriter.hh:460
Dune::VTK::OutputType
OutputType
How the bulk data should be stored in the file.
Definition: common.hh:42
Dune::VTK::NakedBase64DataArrayWriter::NakedBase64DataArrayWriter
NakedBase64DataArrayWriter(std::ostream &theStream, int ncomps, int nitems, Precision prec)
make a new data array writer
Definition: dataarraywriter.hh:367
common.hh
Common stuff for the VTKWriter.
Dune::VTK::Precision::uint8
@ uint8
Dune::VTK::BinaryDataArrayWriter
a streaming writer for data array tags, uses binary inline format
Definition: dataarraywriter.hh:194
Dune::VTK::DataArrayWriter::~DataArrayWriter
virtual ~DataArrayWriter()
virtual destructor
Definition: dataarraywriter.hh:89
Dune::VTK::NakedRawDataArrayWriter
a streaming writer for appended data arrays, uses raw format
Definition: dataarraywriter.hh:405
Dune::VTK::typeSize
std::size_t typeSize(Precision p)
map precision to byte size
Definition: common.hh:348
Dune::VTK::AppendedBase64DataArrayWriter::AppendedBase64DataArrayWriter
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
Dune::VTK::AppendedRawDataArrayWriter::AppendedRawDataArrayWriter
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
Dune::VTK::AppendedBase64DataArrayWriter
a streaming writer for data array tags, uses appended base64 format
Definition: dataarraywriter.hh:307
Dune::VTK::DataArrayWriter::DataArrayWriter
DataArrayWriter(Precision _prec)
construct a data array writer
Definition: dataarraywriter.hh:61
Dune::VTK::appendedbase64
@ appendedbase64
Output is to the file is appended base64 binary.
Definition: common.hh:50
Dune::VTK::AsciiDataArrayWriter::~AsciiDataArrayWriter
~AsciiDataArrayWriter()
finish output; writes end tag
Definition: dataarraywriter.hh:131
Dune::VTK::AsciiDataArrayWriter
a streaming writer for data array tags, uses ASCII inline format
Definition: dataarraywriter.hh:107
Dune::VTK::AsciiDataArrayWriter::AsciiDataArrayWriter
AsciiDataArrayWriter(std::ostream &theStream, std::string name, int ncomps, const Indent &indent_, Precision prec)
make a new data array writer
Definition: dataarraywriter.hh:119
Dune::VTK::AppendedRawDataArrayWriter::writeIsNoop
bool writeIsNoop() const
whether calls to write may be skipped
Definition: dataarraywriter.hh:295
Dune::RawStream
write out data in binary
Definition: streams.hh:81
Dune::VTK::NakedRawDataArrayWriter::NakedRawDataArrayWriter
NakedRawDataArrayWriter(std::ostream &theStream, int ncomps, int nitems, Precision prec)
make a new data array writer
Definition: dataarraywriter.hh:417
Dune::VTK::toString
std::string toString(Precision p)
map precision to VTK type name
Definition: common.hh:328
streams.hh
Dune::VTK::Precision
Precision
which precision to use when writing out data to vtk files
Definition: common.hh:319
Dune::VTK::Precision::float32
@ float32
Dune::VTK::BinaryDataArrayWriter::BinaryDataArrayWriter
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
Dune::VTK::Precision::int32
@ int32
Dune
Include standard header files.
Definition: agrid.hh:58
Dune::VTK::base64
@ base64
Output to the file is inline base64 binary.
Definition: common.hh:46
Dune::VTK::Precision::float64
@ float64
Dune::VTK::DataArrayWriterFactory::DataArrayWriterFactory
DataArrayWriterFactory(OutputType type_, std::ostream &stream_)
create a DataArrayWriterFactory
Definition: dataarraywriter.hh:480
Dune::VTK::DataArrayWriterFactory::beginAppended
bool beginAppended()
signal start of the appended section
Definition: dataarraywriter.hh:495