vtkstructuredgridwriter.impl.hh 5.42 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#pragma once

#include <iomanip>
#include <iostream>
#include <iterator>
#include <fstream>
#include <sstream>
#include <string>

#include <dune/geometry/referenceelements.hh>
#include <dune/geometry/type.hh>

#include "utility/enum.hh"
#include "utility/filesystem.hh"
#include "utility/string.hh"

namespace Dune { namespace experimental {

template <class GV, class DC>
void VtkStructuredGridWriter<GV,DC>
  ::writeSerialFile (std::string const& filename) const
{
  std::ofstream out(filename, std::ios_base::ate | std::ios::binary);
  if (format_ == Vtk::ASCII) {
    if (datatype_ == Vtk::FLOAT32)
      out << std::setprecision(std::numeric_limits<float>::digits10+2);
    else
      out << std::setprecision(std::numeric_limits<double>::digits10+2);
  }

  std::vector<pos_type> offsets; // pos => offset
Praetorius, Simon's avatar
Praetorius, Simon committed
32
33
34
35
36
37
38
39
  out << "<VTKFile"
      << " type=\"StructuredGrid\""
      << " version=\"1.0\""
      << " byte_order=\"" << this->getEndian() << "\""
      << " header_type=\"UInt64\""
      << (format_ == Vtk::COMPRESSED ? " compressor=\"vtkZLibDataCompressor\"" : "")
      << ">\n";

40
  auto const& wholeExtent = dataCollector_.wholeExtent();
Praetorius, Simon's avatar
Praetorius, Simon committed
41
  out << "<StructuredGrid WholeExtent=\"" << join(wholeExtent.begin(), wholeExtent.end()) << "\">\n";
42

Praetorius, Simon's avatar
Praetorius, Simon committed
43
44
  dataCollector_.writeLocalPiece([&out](auto const& extent) {
    out << "<Piece Extent=\"" << join(extent.begin(), extent.end()) << "\">\n";
45
46
  });

Praetorius, Simon's avatar
Praetorius, Simon committed
47
48
49
50
51
  // Write data associated with grid points
  out << "<PointData" << this->getNames(pointData_) << ">\n";
  for (auto const& v : pointData_)
    this->writeData(out, offsets, v, Super::POINT_DATA);
  out << "</PointData>\n";
52

Praetorius, Simon's avatar
Praetorius, Simon committed
53
54
55
56
57
  // Write data associated with grid cells
  out << "<CellData" << this->getNames(cellData_) << ">\n";
  for (auto const& v : cellData_)
    this->writeData(out, offsets, v, Super::CELL_DATA);
  out << "</CellData>\n";
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

  // Write point coordinates
  out << "<Points>\n";
  this->writePoints(out, offsets);
  out << "</Points>\n";

  out << "</Piece>\n";
  out << "</StructuredGrid>\n";

  std::vector<std::uint64_t> blocks; // size of i'th appended block
  pos_type appended_pos = 0;
  if (is_a(format_, Vtk::APPENDED)) {
    out << "<AppendedData encoding=\"raw\">\n_";
    appended_pos = out.tellp();
    for (auto const& v : pointData_) {
Praetorius, Simon's avatar
Praetorius, Simon committed
73
      if (v.type() == Vtk::FLOAT32)
74
75
76
77
78
        blocks.push_back( this->template writeDataAppended<float>(out, v, Super::POINT_DATA) );
      else
        blocks.push_back( this->template writeDataAppended<double>(out, v, Super::POINT_DATA) );
    }
    for (auto const& v : cellData_) {
Praetorius, Simon's avatar
Praetorius, Simon committed
79
      if (v.type() == Vtk::FLOAT32)
80
81
82
83
        blocks.push_back( this->template writeDataAppended<float>(out, v, Super::CELL_DATA) );
      else
        blocks.push_back( this->template writeDataAppended<double>(out, v, Super::CELL_DATA) );
    }
Praetorius, Simon's avatar
Praetorius, Simon committed
84

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
    if (datatype_ == Vtk::FLOAT32)
      blocks.push_back( this->template writePointsAppended<float>(out) );
    else
      blocks.push_back( this->template writePointsAppended<double>(out) );
    out << "</AppendedData>\n";
  }

  out << "</VTKFile>";

  // fillin offset values and block sizes
  if (is_a(format_, Vtk::APPENDED)) {
    pos_type offset = 0;
    for (std::size_t i = 0; i < offsets.size(); ++i) {
      out.seekp(offsets[i]);
      out << '"' << offset << '"';
      offset += pos_type(blocks[i]);
    }
  }
}


template <class GV, class DC>
void VtkStructuredGridWriter<GV,DC>
  ::writeParallelFile (std::string const& pfilename, int size) const
{
  std::string filename = pfilename + ".p" + this->fileExtension();
  std::ofstream out(filename, std::ios_base::ate | std::ios::binary);

Praetorius, Simon's avatar
Praetorius, Simon committed
113
114
115
116
117
118
119
120
  out << "<VTKFile"
      << " type=\"PStructuredGrid\""
      << " version=\"1.0\""
      << " byte_order=\"" << this->getEndian() << "\""
      << " header_type=\"UInt64\""
      << (format_ == Vtk::COMPRESSED ? " compressor=\"vtkZLibDataCompressor\"" : "")
      << ">\n";

121
  auto const& wholeExtent = dataCollector_.wholeExtent();
Praetorius, Simon's avatar
Praetorius, Simon committed
122
123
124
125
126
127
128
129
130
131
132
133
134
  out << "<PStructuredGrid"
      << " GhostLevel=\"0\""
      << " WholeExtent=\"" << join(wholeExtent.begin(), wholeExtent.end()) << "\""
      << ">\n";

  // Write data associated with grid points
  out << "<PPointData" << this->getNames(pointData_) << ">\n";
  for (auto const& v : pointData_) {
    out << "<PDataArray"
        << " Name=\"" << v.name() << "\""
        << " type=\"" << to_string(v.type()) << "\""
        << " NumberOfComponents=\"" << v.ncomps() << "\""
        << " />\n";
135
  }
Praetorius, Simon's avatar
Praetorius, Simon committed
136
137
138
139
140
141
142
143
144
145
  out << "</PPointData>\n";

  // Write data associated with grid cells
  out << "<PCellData" << this->getNames(cellData_) << ">\n";
  for (auto const& v : cellData_) {
    out << "<PDataArray"
        << " Name=\"" << v.name() << "\""
        << " type=\"" << to_string(v.type()) << "\""
        << " NumberOfComponents=\"" << v.ncomps() << "\""
        << " />\n";
146
  }
Praetorius, Simon's avatar
Praetorius, Simon committed
147
  out << "</PCellData>\n";
148
149
150

  // Write points
  out << "<PPoints>\n";
Praetorius, Simon's avatar
Praetorius, Simon committed
151
152
153
154
  out << "<PDataArray"
      << " type=\"" << to_string(datatype_) << "\""
      << " NumberOfComponents=\"3\""
      << " />\n";
155
156
157
  out << "</PPoints>\n";

  // Write piece file references
Praetorius, Simon's avatar
Praetorius, Simon committed
158
  dataCollector_.writePieces([&out,pfilename,ext=this->fileExtension()](int p, auto const& extent, bool write_extent)
159
  {
Praetorius, Simon's avatar
Praetorius, Simon committed
160
161
162
163
    std::string piece_source = pfilename + "_p" + std::to_string(p) + "." + ext;
    out << "<Piece Source=\"" << piece_source << "\"";
    if (write_extent)
      out << " Extent=\"" << join(extent.begin(), extent.end()) << "\"";
164
165
    out << " />\n";
  });
166

167
  out << "</PStructuredGrid>\n";
168
169
170
171
  out << "</VTKFile>";
}

}} // end namespace Dune::experimental