dune-vtk  0.2
vtkreader.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <iosfwd>
4 #include <map>
5 #include <memory>
6 #include <vector>
7 
8 #include <dune/common/shared_ptr.hh>
9 #include <dune/common/typelist.hh>
10 #include <dune/common/typeutilities.hh>
11 
12 #include <dune/vtk/filereader.hh>
13 #include <dune/vtk/types.hh>
15 
16 // default GridCreator
19 
20 namespace Dune
21 {
23 
34  template <class Grid, class GC = Vtk::ContinuousGridCreator<Grid>, class FieldType = double>
35  class VtkReader
36  : public Vtk::FileReader<Grid, VtkReader<Grid, GC>>
37  {
38  // Sections visited during the xml parsing
39  enum Sections {
40  NO_SECTION = 0, VTK_FILE, UNSTRUCTURED_GRID, PIECE, POINT_DATA, PD_DATA_ARRAY, CELL_DATA, CD_DATA_ARRAY,
41  POINTS, POINTS_DATA_ARRAY, CELLS, CELLS_DATA_ARRAY, APPENDED_DATA, XML_NAME, XML_NAME_ASSIGN, XML_VALUE
42  };
43 
44  // Type storing information about read data
45  struct DataArrayAttributes
46  {
47  std::string name;
48  Vtk::DataTypes type;
49  unsigned int components = 1;
50  std::uint64_t offset = 0;
51  Sections section = NO_SECTION;
52  };
53 
54  // Type of global world coordinates
55  using GlobalCoordinate = typename GC::GlobalCoordinate;
56 
57  // Template representing a grid-function that is created in getPointData() and getCellData()
58  // with Context either Vtk::PointContext or Vek::CellContext, respectively.
59  // To each GridCreator a GridFunction is associated, see, e.g. Vtk::ContinuousGridFunction
60  // or Vtk::LagrangeGridFunction.
61  template <class Context>
63 
64  public:
65  using GridCreator = GC;
66 
68  using PointGridFunction = GridFunction<Vtk::PointContext>;
69 
71  using CellGridFunction = GridFunction<Vtk::CellContext>;
72 
73  public:
75 
81  template <class... Args,
82  std::enable_if_t<std::is_constructible<GridCreator, Args...>::value,int> = 0>
83  explicit VtkReader (Args&&... args)
84  : VtkReader(std::make_shared<GridCreator>(std::forward<Args>(args)...))
85  {}
86 
88  explicit VtkReader (GridCreator& creator)
89  : VtkReader(stackobject_to_shared_ptr(creator))
90  {}
91 
93  explicit VtkReader (std::shared_ptr<GridCreator> creator)
94  : creator_(std::move(creator))
95  {}
96 
98 
106  void read (std::string const& filename, bool fillCreator = true);
107 
110  {
111  return *creator_;
112  }
113 
116  std::unique_ptr<Grid> createGrid () const
117  {
118  return creator_->createGrid();
119  }
120 
123  GridFunction<Vtk::PointContext> getPointData (std::string const& name) const
124  {
125  auto data_it = dataArray_.find("PointData." + name);
126  auto point_it = pointData_.find("PointData." + name);
127  VTK_ASSERT_MSG(data_it != dataArray_.end() && point_it != pointData_.end(),
128  "The data to extract is not found in point-data. Try `getCellData()` instead!");
129  VTK_ASSERT(data_it->second.section == POINT_DATA);
130 
131  return {*creator_, point_it->second, data_it->second.name, data_it->second.components,
132  data_it->second.type, vec_types, vec_offsets, vec_connectivity};
133  }
134 
137  std::vector<DataArrayAttributes> getPointDataAttributes () const
138  {
139  std::vector<DataArrayAttributes> attributes;
140  attributes.reserve(pointData_.size());
141  for (auto const& da : dataArray_) {
142  if (da.second.section == POINT_DATA)
143  attributes.push_back(da.second);
144  }
145  return attributes;
146  }
147 
150  GridFunction<Vtk::CellContext> getCellData (std::string const& name) const
151  {
152  auto data_it = dataArray_.find("CellData." + name);
153  auto cell_it = cellData_.find("CellData." + name);
154  VTK_ASSERT_MSG(data_it != dataArray_.end() && cell_it != cellData_.end(),
155  "The data to extract is not found in cell-data. Try `getPointData()` instead!");
156  VTK_ASSERT(data_it->second.section == CELL_DATA);
157 
158  return {*creator_, cell_it->second, data_it->second.name, data_it->second.components,
159  data_it->second.type, vec_types, vec_offsets, vec_connectivity};
160  }
161 
164  std::vector<DataArrayAttributes> getCellDataAttributes () const
165  {
166  std::vector<DataArrayAttributes> attributes;
167  attributes.reserve(cellData_.size());
168  for (auto const& da : dataArray_) {
169  if (da.second.section == CELL_DATA)
170  attributes.push_back(da.second);
171  }
172  return attributes;
173  }
174 
177 
179 
183  void readSerialFileFromStream (std::ifstream& input, bool create = true);
184 
186 
190  void readParallelFileFromStream (std::ifstream& input, int rank, int size, bool create = true);
191 
194  void fillGridCreator (bool insertPieces = true);
195 
197 
199  std::vector<std::string> const& pieces () const
200  {
201  return pieces_;
202  }
203 
204 #ifndef DOXYGEN
205  // Implementation of the FileReader interface
206  static void fillFactoryImpl (GridFactory<Grid>& factory, std::string const& filename)
207  {
208  VtkReader reader{factory};
209  reader.read(filename);
210  }
211 #endif
212 
213  private:
214  // Read values stored on the cells with ID `id`
215  Sections readCellData (std::ifstream& input, std::string id);
216 
217  template <class F, class H>
218  void readCellDataAppended (MetaType<F>, MetaType<H>, std::ifstream& input, std::string id);
219 
220  // Read values stored on the points with ID `id`
221  Sections readPointData (std::ifstream& input, std::string id);
222 
223  template <class F, class H>
224  void readPointDataAppended (MetaType<F>, MetaType<H>, std::ifstream& input, std::string id);
225 
226 
227  // Read vertex coordinates from `input` stream and store in into `factory`
228  Sections readPoints (std::ifstream& input, std::string id);
229 
230  template <class F, class H>
231  void readPointsAppended (MetaType<F>, MetaType<H>, std::ifstream& input);
232 
233 
234  // Read cell type, cell offsets and connectivity from `input` stream
235  Sections readCells (std::ifstream& input, std::string id);
236 
237  template <class H>
238  void readCellsAppended (MetaType<H>, std::ifstream& input);
239 
240  // Read data from appended section in vtk file, starting from `offset`
241  template <class FloatType, class HeaderType>
242  void readAppended (std::ifstream& input, std::vector<FloatType>& values, HeaderType offset);
243 
244  // Test whether line belongs to section
245  bool isSection (std::string line,
246  std::string key,
247  Sections current,
248  Sections parent = NO_SECTION) const
249  {
250  bool result = line.substr(1, key.length()) == key;
251  if (result && current != parent)
252  DUNE_THROW(Exception , "<" << key << "> in wrong section." );
253  return result;
254  }
255 
256  // Convert a section into a string
257  std::string toString (Sections s) const;
258 
259  // Find beginning of appended binary data
260  std::uint64_t findAppendedDataPosition (std::ifstream& input) const;
261 
262  // Read attributes from current xml tag
263  std::map<std::string, std::string> parseXml (std::string const& line, bool& closed);
264 
265  // clear all vectors
266  void clear ();
267 
268  auto comm () const
269  {
270  return MPIHelper::getCollectiveCommunication();
271  }
272 
273  private:
274  std::shared_ptr<GridCreator> creator_;
275 
277  Vtk::FormatTypes format_;
278 
280  Vtk::CompressorTypes compressor_;
281 
282  // Temporary data to construct the grid elements
283  std::vector<GlobalCoordinate> vec_points;
284  std::vector<std::uint64_t> vec_point_ids; //< Global unique vertex ID
285  std::vector<std::uint8_t> vec_types; //< VTK cell type ID
286  std::vector<std::int64_t> vec_offsets; //< offset of vertices of cell
287  std::vector<std::int64_t> vec_connectivity; //< vertex indices of cell
288 
289  std::size_t numberOfCells_ = 0; //< Number of cells in the grid
290  std::size_t numberOfPoints_ = 0; //< Number of vertices in the grid
291 
292  // offset information for appended data
293  // map: id -> {Name,DataType,NumberOfComponents,Offset}
294  std::map<std::string, DataArrayAttributes> dataArray_;
295 
296  // storage for internal point and cell data
297  // map: id -> vector of data entries per point/cell
298  std::map<std::string, std::vector<FieldType>> pointData_;
299  std::map<std::string, std::vector<FieldType>> cellData_;
300 
301  // vector of filenames of parallel pieces
302  std::vector<std::string> pieces_;
303 
305  std::uint64_t offset0_ = 0;
306 
307  bool read_ = false;
308  };
309 
310  // deduction guides
311  template <class Grid>
312  VtkReader (GridFactory<Grid>&)
314 
315  template <class GridCreator,
316  class = std::void_t<typename GridCreator::Grid>>
317  VtkReader (GridCreator&)
319 
320  template <class GridCreator,
321  class = std::void_t<typename GridCreator::Grid>>
322  VtkReader (std::shared_ptr<GridCreator>)
324 
325 } // end namespace Dune
326 
327 #include "vtkreader.impl.hh"
Macro for wrapping error checks and throwing exceptions.
#define VTK_ASSERT_MSG(cond, text)
check if condition cond holds; otherwise, throw a VtkError with a message.
Definition: errors.hh:19
#define VTK_ASSERT(cond)
check if condition cond holds; otherwise, throw a VtkError.
Definition: errors.hh:29
Definition: writer.hh:13
VtkReader(GridFactory< Grid > &) -> VtkReader< Grid, Vtk::ContinuousGridCreator< Grid >>
FormatTypes
Type used for representing the output format.
Definition: types.hh:21
CompressorTypes
Definition: types.hh:149
DataTypes
Definition: types.hh:52
Definition: filereader.hh:16
static void fillFactoryImpl(GridFactory< Grid > &, const std::string &, Args &&...)
Definition: filereader.hh:71
void type
Definition: gridfunctions/common.hh:27
File-Reader for Vtk unstructured .vtu files.
Definition: vtkreader.hh:37
VtkReader(Args &&... args)
Constructor. Creates a new GridCreator with the passed factory.
Definition: vtkreader.hh:83
void read(std::string const &filename, bool fillCreator=true)
Read the grid from file with filename into the GridCreator.
Definition: vtkreader.impl.hh:20
VtkReader(std::shared_ptr< GridCreator > creator)
Constructor. Stores the shared_ptr.
Definition: vtkreader.hh:93
void readParallelFileFromStream(std::ifstream &input, int rank, int size, bool create=true)
Read the grid from and input stream, referring to a .pvtu file, into the GridFactory factory_.
Definition: vtkreader.impl.hh:249
std::unique_ptr< Grid > createGrid() const
Definition: vtkreader.hh:116
VtkReader(GridCreator &creator)
Constructor. Stores the references in a non-destroying shared_ptr.
Definition: vtkreader.hh:88
GC GridCreator
Definition: vtkreader.hh:65
std::vector< DataArrayAttributes > getPointDataAttributes() const
Definition: vtkreader.hh:137
GridFunction< Vtk::CellContext > getCellData(std::string const &name) const
Definition: vtkreader.hh:150
void fillGridCreator(bool insertPieces=true)
Definition: vtkreader.impl.hh:681
GridFunction< Vtk::PointContext > PointGridFunction
GridFunction representing the data stored on the points in the file.
Definition: vtkreader.hh:68
GridFunction< Vtk::PointContext > getPointData(std::string const &name) const
Definition: vtkreader.hh:123
void readSerialFileFromStream(std::ifstream &input, bool create=true)
Read the grid from an input stream, referring to a .vtu file, into the GridFactory factory_.
Definition: vtkreader.impl.hh:43
std::vector< DataArrayAttributes > getCellDataAttributes() const
Definition: vtkreader.hh:164
GridFunction< Vtk::CellContext > CellGridFunction
GridFunction representing the data stored on the cells in the file.
Definition: vtkreader.hh:71
std::vector< std::string > const & pieces() const
Return the filenames of parallel pieces.
Definition: vtkreader.hh:199
GridCreator & gridCreator()
Obtains the creator of the reader.
Definition: vtkreader.hh:109