GridFormat 0.6.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_
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
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
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
Base class for grid data readers.
std::shared_ptr< const Field > FieldPtr
Pointer type used by writers/readers for fields.
Definition field.hpp:205
Reader for .pvtp file format.
Reader for .pvtp file format.
Reader for .pvtr file format.
Reader for .pvts file format.
Reader for .pvtu file format.
Definition reader.hpp:266
Describes the location of a piece within a distributed structured grid.
Definition reader.hpp:57
Reader for .vti file format.
Reader for .vtp file format.
Reader for .vtr file format.
Reader for .vts file format.
Reader for .vtu file format.
Helper classes and functions for VTK XML-type file format writers & readers.