GridFormat 0.4.0
I/O-Library for grid-like data structures
Loading...
Searching...
No Matches
pvd_reader.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2022-2023 Dennis Gläser <dennis.glaeser@iws.uni-stuttgart.de>
2// SPDX-License-Identifier: MIT
8#ifndef GRIDFORMAT_VTK_PVD_READER_HPP_
9#define GRIDFORMAT_VTK_PVD_READER_HPP_
10
11#include <memory>
12#include <optional>
13#include <filesystem>
14#include <functional>
15#include <type_traits>
16#include <iterator>
17
18#include <gridformat/common/string_conversion.hpp>
19#include <gridformat/parallel/communication.hpp>
22
28
34
35namespace GridFormat {
36
41template<Concepts::Communicator C = NullCommunicator>
42class PVDReader : public GridReader {
43 struct Step {
44 std::string filename;
45 double time;
46 };
47
48 static constexpr bool is_parallel = !std::is_same_v<NullCommunicator, C>;
49
50 public:
51 using StepReaderFactory = std::conditional_t<
52 is_parallel,
53 std::function<std::unique_ptr<GridReader>(const C&, const std::string&)>,
54 std::function<std::unique_ptr<GridReader>(const std::string&)>
55 >;
56
57
58 PVDReader() requires(std::same_as<C, NullCommunicator>)
59 : _step_reader_factory{_make_default_step_reader_factory()}
60 {}
61
62 explicit PVDReader(StepReaderFactory&& f) requires(std::same_as<C, NullCommunicator>)
63 : _step_reader_factory{std::move(f)}
64 {}
65
66 explicit PVDReader(const C& comm)
67 : _communicator{comm}
68 , _step_reader_factory{_make_default_step_reader_factory()}
69 {}
70
71 explicit PVDReader(const C& comm, StepReaderFactory&& f)
72 : _communicator{comm}
73 , _step_reader_factory{std::move(f)}
74 {}
75
76 private:
77 StepReaderFactory _make_default_step_reader_factory() const {
78 if constexpr (is_parallel)
79 return [&] (const C& comm, const std::string& filename) {
80 return _make_reader_from_file(comm, filename);
81 };
82 else
83 return [&] (const std::string& filename) {
84 return _make_reader_from_file(NullCommunicator{}, filename);
85 };
86 }
87
88 static std::unique_ptr<GridReader> _make_reader_from_file(const C& comm, const std::string& filename) {
89 std::filesystem::path path{filename};
90 if (path.extension() == ".vtu")
91 return std::make_unique<VTUReader>();
92 else if (path.extension() == ".vtp")
93 return std::make_unique<VTPReader>();
94 else if (path.extension() == ".vts")
95 return std::make_unique<VTSReader>();
96 else if (path.extension() == ".vtr")
97 return std::make_unique<VTRReader>();
98 else if (path.extension() == ".vti")
99 return std::make_unique<VTIReader>();
100 else if (path.extension() == ".pvtu")
101 return std::make_unique<PVTUReader>(comm);
102 else if (path.extension() == ".pvtp")
103 return std::make_unique<PVTPReader>(comm);
104 else if (path.extension() == ".pvts")
105 return std::make_unique<PVTSReader>(comm);
106 else if (path.extension() == ".pvtr")
107 return std::make_unique<PVTRReader>(comm);
108 else if (path.extension() == ".pvti")
109 return std::make_unique<PVTIReader>(comm);
110 throw IOError("Could not find reader for format with extension " + std::string{path.extension()});
111 }
112
113 std::string _name() const override {
114 return "PVDReader";
115 }
116
117 void _open(const std::string& filename, typename GridReader::FieldNames& names) override {
118 _reset();
119 _read_steps(filename);
120 _make_step_reader();
121 _read_current_field_names(names);
122 }
123
124 void _close() override {
125 _reset();
126 }
127
128 std::size_t _number_of_cells() const override {
129 return _access_reader().number_of_cells();
130 }
131
132 std::size_t _number_of_points() const override {
133 return _access_reader().number_of_points();
134 }
135
136 std::size_t _number_of_pieces() const override {
137 return _access_reader().number_of_pieces();
138 }
139
140 virtual FieldPtr _cell_field(std::string_view name) const override {
141 return _access_reader().cell_field(name);
142 }
143
144 virtual FieldPtr _point_field(std::string_view name) const override {
145 return _access_reader().point_field(name);
146 }
147
148 virtual FieldPtr _meta_data_field(std::string_view name) const override {
149 return _access_reader().meta_data_field(name);
150 }
151
152 virtual void _visit_cells(const typename GridReader::CellVisitor& visitor) const override {
153 _access_reader().visit_cells(visitor);
154 }
155
156 virtual FieldPtr _points() const override {
157 return _access_reader().points();
158 }
159
160 virtual typename GridReader::PieceLocation _location() const override {
161 return _access_reader().location();
162 }
163
164 virtual std::vector<double> _ordinates(unsigned int i) const override {
165 return _access_reader().ordinates(i);
166 }
167
168 virtual typename GridReader::Vector _spacing() const override {
169 return _access_reader().spacing();
170 }
171
172 virtual typename GridReader::Vector _origin() const override {
173 return _access_reader().origin();
174 }
175
176 virtual typename GridReader::Vector _basis_vector(unsigned int i) const override {
177 return _access_reader().basis_vector(i);
178 }
179
180 virtual bool _is_sequence() const override {
181 return true;
182 }
183
184 std::size_t _number_of_steps() const override {
185 return _steps.size();
186 }
187
188 double _time_at_step(std::size_t step_idx) const override {
189 return _steps.at(step_idx).time;
190 }
191
192 void _set_step(std::size_t step_idx, typename GridReader::FieldNames& names) override {
193 names.clear();
194 _step_index = step_idx;
195 _make_step_reader();
196 _read_current_field_names(names);
197 }
198
199 void _read_steps(const std::string& filename) {
200 auto helper = VTK::XMLReaderHelper::make_from(filename, "Collection");
201 for (const auto& data_set : children(helper.get("Collection")) | std::views::filter([] (const XMLElement& e) {
202 return e.name() == "DataSet";
203 }))
204 _steps.emplace_back(Step{
205 .filename = _get_piece_path(data_set.get_attribute("file"), filename),
206 .time = from_string<double>(data_set.get_attribute("timestep"))
207 });
208 }
209
210 std::string _get_piece_path(std::filesystem::path vtk_file,
211 std::filesystem::path pvtk_file) const {
212 if (vtk_file.is_absolute())
213 return vtk_file;
214 return pvtk_file.parent_path() / vtk_file;
215 }
216
217 void _make_step_reader() {
218 const std::string& filename = _steps.at(_step_index).filename;
219 _step_reader = _invoke_reader_factory(filename);
220 _step_reader->open(filename);
221 }
222
223 std::unique_ptr<GridReader> _invoke_reader_factory(const std::string& filename) const {
224 if constexpr (is_parallel)
225 return _step_reader_factory(_communicator, filename);
226 else
227 return _step_reader_factory(filename);
228 }
229
230 void _read_current_field_names(typename GridReader::FieldNames& names) const {
231 std::ranges::copy(cell_field_names(_access_reader()), std::back_inserter(names.cell_fields));
232 std::ranges::copy(point_field_names(_access_reader()), std::back_inserter(names.point_fields));
233 std::ranges::copy(meta_data_field_names(_access_reader()), std::back_inserter(names.meta_data_fields));
234 }
235
236 void _reset() {
237 _step_reader.reset();
238 _steps.clear();
239 _step_index = 0;
240 }
241
242 const GridReader& _access_reader() const {
243 if (!_step_reader)
244 throw ValueError("No data available");
245 return *_step_reader;
246 }
247
248 C _communicator;
249 StepReaderFactory _step_reader_factory;
250 std::unique_ptr<GridReader> _step_reader;
251 std::vector<Step> _steps;
252 std::size_t _step_index = 0;
253};
254
255} // namespace GridFormat
256
257#endif // GRIDFORMAT_VTK_PVD_READER_HPP_
Abstract base class for all readers, defines the common interface.
Definition: reader.hpp:51
void visit_cells(const CellVisitor &visitor) const
Visit all cells in the grid read from the file.
Definition: reader.hpp:201
std::size_t number_of_pieces() const
Definition: reader.hpp:108
FieldPtr meta_data_field(std::string_view name) const
Return the meta data field with the given name.
Definition: reader.hpp:221
const std::string & filename() const
Return the name of the opened grid file (empty string until open() is called)
Definition: reader.hpp:92
friend std::ranges::range auto point_field_names(const GridReader &reader)
Return a range over the names of all read point fields.
Definition: reader.hpp:231
std::string name() const
Return the name of this reader.
Definition: reader.hpp:73
Vector origin() const
Return the origin of the grid (only available for image grid formats)
Definition: reader.hpp:140
friend std::ranges::range auto meta_data_field_names(const GridReader &reader)
Return a range over the names of all read metadata fields.
Definition: reader.hpp:236
FieldPtr point_field(std::string_view name) const
Return the point field with the given name.
Definition: reader.hpp:216
PieceLocation location() const
Return the location of this piece in a structured grid (only available for structured grid formats)
Definition: reader.hpp:123
FieldPtr cell_field(std::string_view name) const
Return the cell field with the given name.
Definition: reader.hpp:211
friend std::ranges::range auto cell_field_names(const GridReader &reader)
Return a range over the names of all read cell fields.
Definition: reader.hpp:226
FieldPtr points() const
Return the points of the grid as field.
Definition: reader.hpp:206
std::vector< double > ordinates(unsigned int direction) const
Return the ordinates of the grid (only available for rectilinear grid formats)
Definition: reader.hpp:128
std::size_t number_of_cells() const
Return the number of cells in the grid read from the file.
Definition: reader.hpp:97
std::size_t number_of_points() const
Return the number of points in the grid read from the file.
Definition: reader.hpp:102
Vector spacing() const
Return the spacing of the grid (only available for image grid formats)
Definition: reader.hpp:135
Vector basis_vector(unsigned int direction) const
Return the basis vector of the grid in the given direction (only available for image grid formats)
Definition: reader.hpp:145
Reader for .pvd time series file format.
Definition: pvd_reader.hpp:42
Base class for grid data readers.
std::shared_ptr< const Field > FieldPtr
Pointer type used by writers/readers for fields.
Definition: field.hpp:186
Definition: reader.hpp:266
Describes the location of a piece within a distributed structured grid.
Definition: reader.hpp:57
Helper classes and functions for VTK XML-type file format writers & readers.