vtkreader.hh 4.4 KB
Newer Older
Praetorius, Simon's avatar
Praetorius, Simon committed
1
2
3
4
5
6
#pragma once

#include <iosfwd>
#include <map>

#include "filereader.hh"
7
#include "gridcreator.hh"
Praetorius, Simon's avatar
Praetorius, Simon committed
8
9
#include "vtktypes.hh"

10
namespace Dune { namespace experimental
Praetorius, Simon's avatar
Praetorius, Simon committed
11
12
{
  /// File-Reader for Vtk .vtu files
13
14
15
16
17
18
  /**
   * Reads .vtu files and constructs a grid from the cells stored in the file
   * Additionally, stored data can be read.
   *
   * Assumption on the file structure: Each XML tag must be on a separate line.
   **/
19
  template <class Grid, class GridCreator = DefaultGridCreator>
Praetorius, Simon's avatar
Praetorius, Simon committed
20
  class VtkReader
21
      : public FileReader<Grid, VtkReader<Grid, GridCreator>>
Praetorius, Simon's avatar
Praetorius, Simon committed
22
  {
23
    // Sections visited during the xml parsing
Praetorius, Simon's avatar
Praetorius, Simon committed
24
25
26
27
28
    enum Sections {
      NO_SECTION = 0, VTK_FILE, UNSTRUCTURED_GRID, PIECE, POINT_DATA, PD_DATA_ARRAY, CELL_DATA, CD_DATA_ARRAY,
      POINTS, POINTS_DATA_ARRAY, CELLS, CELLS_DATA_ARRAY, APPENDED_DATA, XML_NAME, XML_NAME_ASSIGN, XML_VALUE
    };

29
30
31
32
33
34
35
    struct DataArrayAttributes
    {
      Vtk::DataTypes type;
      std::size_t components = 1;
      std::uint64_t offset = 0;
    };

Praetorius, Simon's avatar
Praetorius, Simon committed
36
37
38
39
    using Entity = typename Grid::template Codim<0>::Entity;
    using GlobalCoordinate = typename Entity::Geometry::GlobalCoordinate;

  public:
40
41
42
    /// Constructor. Stores a pointer to the GridFactory.
    VtkReader (GridFactory<Grid>& factory)
      : factory_(&factory)
Praetorius, Simon's avatar
Praetorius, Simon committed
43
44
    {}

45
46
47
48
49
50
51
52
53
    /// Read the grid from file with `filename` into the GridFactory `factory`
    void readFromFile (std::string const& filename);

    /// Implementation of \ref FileReader interface
    static void readFactoryImpl (GridFactory<Grid>& factory, std::string const& filename)
    {
      VtkReader reader{factory};
      reader.readFromFile(filename);
    }
Praetorius, Simon's avatar
Praetorius, Simon committed
54
55

  private:
56
57
    // Read values stored on the cells with name `name`
    template <class T>
58
    Sections readCellData (std::ifstream& /*input*/, std::vector<T>& /*values*/, std::string /*name*/)
Praetorius, Simon's avatar
Praetorius, Simon committed
59
60
61
62
63
    {
      /* does not read anything */
      return CD_DATA_ARRAY;
    }

64
    template <class T>
65
    Sections readPointData (std::ifstream& /*input*/, std::vector<T>& /*values*/, std::string /*name*/)
Praetorius, Simon's avatar
Praetorius, Simon committed
66
67
68
69
70
    {
      /* does not read anything */
      return PD_DATA_ARRAY;
    }

71
    // Read vertex coordinates from `input` stream and store in into `factory`
72
    Sections readPoints (std::ifstream& input);
Praetorius, Simon's avatar
Praetorius, Simon committed
73
74

    template <class T>
75
    void readPointsAppended (std::ifstream& input);
Praetorius, Simon's avatar
Praetorius, Simon committed
76

77
    // Read cell type, cell offsets and connectivity from `input` stream
78
    Sections readCells (std::ifstream& input, std::string name);
Praetorius, Simon's avatar
Praetorius, Simon committed
79
80
81

    void readCellsAppended (std::ifstream& input);

82
    // Read data from appended section in vtk file, starting from `offset`
Praetorius, Simon's avatar
Praetorius, Simon committed
83
84
85
    template <class T>
    void readAppended (std::ifstream& input, std::vector<T>& values, std::uint64_t offset);

86
87
88
89
    // Test whether line belongs to section
    bool isSection (std::string line,
                    std::string key,
                    Sections current,
90
                    Sections parent = NO_SECTION) const
Praetorius, Simon's avatar
Praetorius, Simon committed
91
92
93
94
95
96
97
    {
      bool result = line.substr(1, key.length()) == key;
      if (result && current != parent)
        DUNE_THROW(Exception , "<" << key << "> in wrong section." );
      return result;
    }

98
99
100
    // Find beginning of appended binary data
    std::uint64_t findAppendedDataPosition (std::ifstream& input) const;

101
102
    // Read attributes from current xml tag
    std::map<std::string, std::string> parseXml(std::string const& line, bool& closed);
Praetorius, Simon's avatar
Praetorius, Simon committed
103

104
    // Construct a grid using the GridFactory `factory` and the read vectors
105
106
    // \ref vec_points, \ref vec_types, \ref vec_offsets, and \ref vec_connectivity,
    // by passing to \ref GridCreator.
107
    void createGrid() const;
Praetorius, Simon's avatar
Praetorius, Simon committed
108
109

  private:
110
111
112
    GridFactory<Grid>* factory_;

    /// Data format, i.e. ASCII, BINARY or COMPRESSED. Read from xml attributes.
Praetorius, Simon's avatar
Praetorius, Simon committed
113
114
    Vtk::FormatTypes format_;

115
    // Temporary data to construct the grid elements
116
    std::vector<GlobalCoordinate> vec_points;
117
118
119
    std::vector<std::uint8_t> vec_types; //< VTK cell type ID
    std::vector<std::int64_t> vec_offsets; //< offset of vertices of cell
    std::vector<std::int64_t> vec_connectivity; //< vertex indices of cell
Praetorius, Simon's avatar
Praetorius, Simon committed
120

121
122
    std::size_t numberOfCells_; //< Number of cells in the grid
    std::size_t numberOfPoints_; // Number of vertices in the grid
Praetorius, Simon's avatar
Praetorius, Simon committed
123

124
    // offset information for appended data
125
126
    // map Name -> {DataType,NumberOfComponents,Offset}
    std::map<std::string, DataArrayAttributes> dataArray_;
Praetorius, Simon's avatar
Praetorius, Simon committed
127

128
129
    /// Offset of beginning of appended data
    std::uint64_t offset0_;
Praetorius, Simon's avatar
Praetorius, Simon committed
130
131
  };

132
}} // end namespace Dune::experimental
Praetorius, Simon's avatar
Praetorius, Simon committed
133
134

#include "vtkreader.impl.hh"