dune-vtk  0.2
vtktimeserieswriter.impl.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <cstdio>
5 #include <iomanip>
6 #include <iostream>
7 #include <iterator>
8 #include <fstream>
9 #include <sstream>
10 #include <string>
11 
12 #if HAVE_VTK_ZLIB
13 #include <zlib.h>
14 #endif
15 
16 #include <dune/geometry/referenceelements.hh>
17 #include <dune/geometry/type.hh>
18 
19 #include <dune/vtk/utility/enum.hh>
22 
23 namespace Dune {
24 
25 template <class W>
27 {
28  if (initialized_) {
29  int ec = std::remove(filenameMesh_.c_str());
30  assert(ec == 0);
31  for (auto const& timestep : timesteps_) {
32  ec = std::remove(timestep.second.c_str());
33  assert(ec == 0);
34  }
35  }
36  std::remove(tmpDir_.string().c_str());
37 }
38 
39 
40 template <class W>
42  ::writeTimestep (double time, std::string const& fn, std::optional<std::string> tmpDir, bool writeCollection) const
43 {
44  auto name = Vtk::Path(fn).stem();
45  auto tmpBase = tmpDir ? Vtk::Path(*tmpDir) : tmpDir_;
46  auto tmp = tmpBase;
47  tmp /= name.string();
48 
49  vtkWriter_.dataCollector_->update();
50 
51  std::string filenameBase = tmp.string();
52 
53  if (vtkWriter_.comm().size() > 1)
54  filenameBase = tmp.string() + "_p" + std::to_string(vtkWriter_.comm().rank());
55 
56  if (!initialized_) {
57  Vtk::createDirectories(tmpBase);
58 
59  // write points and cells only once
60  filenameMesh_ = filenameBase + ".mesh.vtkdata";
61  std::ofstream out(filenameMesh_, std::ios_base::ate | std::ios::binary);
62  vtkWriter_.writeGridAppended(out, blocks_);
63  initialized_ = true;
64  }
65 
66  std::string filenameData = filenameBase + "_t" + std::to_string(timesteps_.size()) + ".vtkdata";
67  std::ofstream out(filenameData, std::ios_base::ate | std::ios::binary);
68  vtkWriter_.writeDataAppended(out, blocks_);
69  timesteps_.emplace_back(time, filenameData);
70 
71  if (writeCollection)
72  write(fn);
73 }
74 
75 
76 template <class W>
77 std::string VtkTimeseriesWriter<W>
78  ::write (std::string const& fn, std::optional<std::string> dir) const
79 {
80  assert( initialized_ );
81 
82  auto p = Vtk::Path(fn);
83  auto name = p.stem();
84  p.removeFilename();
85 
86  Vtk::Path fn_dir = p;
87  Vtk::Path data_dir = dir ? Vtk::Path(*dir) : fn_dir;
88  Vtk::Path rel_dir = Vtk::relative(data_dir, fn_dir);
89 
90  std::string serial_fn = fn_dir.string() + '/' + name.string() + "_ts";
91  std::string parallel_fn = data_dir.string() + '/' + name.string() + "_ts";
92  std::string rel_fn = rel_dir.string() + '/' + name.string() + "_ts";
93 
94  int commRank = vtkWriter_.comm().rank();
95  int commSize = vtkWriter_.comm().size();
96  if (commSize > 1)
97  serial_fn += "_p" + std::to_string(commRank);
98 
99  std::string outputFilename;
100 
101  { // write serial file
102  outputFilename = serial_fn + "." + vtkWriter_.getFileExtension();
103  std::ofstream serial_out(outputFilename, std::ios_base::ate | std::ios::binary);
104  assert(serial_out.is_open());
105 
106  serial_out.imbue(std::locale::classic());
107  serial_out << std::setprecision(vtkWriter_.getDatatype() == Vtk::DataTypes::FLOAT32
108  ? std::numeric_limits<float>::digits10+2
109  : std::numeric_limits<double>::digits10+2);
110 
111  vtkWriter_.writeTimeseriesSerialFile(serial_out, filenameMesh_, timesteps_, blocks_);
112  }
113 
114  if (commSize > 1 && commRank == 0) {
115  // write parallel file
116  outputFilename = parallel_fn + ".p" + vtkWriter_.getFileExtension();
117  std::ofstream parallel_out(outputFilename, std::ios_base::ate | std::ios::binary);
118  assert(parallel_out.is_open());
119 
120  parallel_out.imbue(std::locale::classic());
121  parallel_out << std::setprecision(vtkWriter_.getDatatype() == Vtk::DataTypes::FLOAT32
122  ? std::numeric_limits<float>::digits10+2
123  : std::numeric_limits<double>::digits10+2);
124 
125  vtkWriter_.writeTimeseriesParallelFile(parallel_out, rel_fn, commSize, timesteps_);
126  }
127 
128  return outputFilename;
129 }
130 
131 } // end namespace Dune
Definition: datacollectorinterface.hh:9
std::string to_string(Vtk::FormatTypes type)
Definition: types.cc:12
Path relative(Path const &a, Path const &b)
Find the path of a relative to directory of b
Definition: filesystem.cc:173
@ FLOAT32
Definition: types.hh:56
bool createDirectories(Path const &p)
Create directory and non existing parent directories.
Definition: filesystem.cc:140
Definition: filesystem.hh:15
Path stem() const
Returns the stem path component.
Definition: filesystem.cc:66
std::string string() const
Return the path as string.
Definition: filesystem.cc:27
void writeTimestep(double time, std::string const &fn, std::optional< std::string > tmpDir={}, bool writeCollection=true) const
Write the attached data to the file.
Definition: vtktimeserieswriter.impl.hh:42
virtual std::string write(std::string const &fn, std::optional< std::string > dir={}) const override
Writes all timesteps to single timeseries file.
Definition: vtktimeserieswriter.impl.hh:78
~VtkTimeseriesWriter()
Remove all written intermediate files and remove temporary directory.
Definition: vtktimeserieswriter.impl.hh:26