8#ifndef GRIDFORMAT_VTK_PVD_READER_HPP_
9#define GRIDFORMAT_VTK_PVD_READER_HPP_
18#include <gridformat/common/string_conversion.hpp>
19#include <gridformat/parallel/communication.hpp>
41template<Concepts::Communicator C = NullCommunicator>
48 static constexpr bool is_parallel = !std::is_same_v<NullCommunicator, C>;
51 using StepReaderFactory = std::conditional_t<
53 std::function<std::unique_ptr<GridReader>(
const C&,
const std::string&)>,
54 std::function<std::unique_ptr<GridReader>(
const std::string&)>
58 PVDReader()
requires(std::same_as<C, NullCommunicator>)
59 : _step_reader_factory{_make_default_step_reader_factory()}
62 explicit PVDReader(StepReaderFactory&& f)
requires(std::same_as<C, NullCommunicator>)
63 : _step_reader_factory{std::move(f)}
68 , _step_reader_factory{_make_default_step_reader_factory()}
71 explicit PVDReader(
const C& comm, StepReaderFactory&& f)
73 , _step_reader_factory{std::move(f)}
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);
83 return [&] (
const std::string&
filename) {
84 return _make_reader_from_file(NullCommunicator{},
filename);
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()});
113 std::string _name()
const override {
121 _read_current_field_names(names);
124 void _close()
override {
128 std::size_t _number_of_cells()
const override {
132 std::size_t _number_of_points()
const override {
136 std::size_t _number_of_pieces()
const override {
140 virtual FieldPtr _cell_field(std::string_view
name)
const override {
144 virtual FieldPtr _point_field(std::string_view
name)
const override {
148 virtual FieldPtr _meta_data_field(std::string_view
name)
const override {
152 virtual void _visit_cells(
const typename GridReader::CellVisitor& visitor)
const override {
156 virtual FieldPtr _points()
const override {
157 return _access_reader().
points();
164 virtual std::vector<double> _ordinates(
unsigned int i)
const override {
168 virtual typename GridReader::Vector _spacing()
const override {
169 return _access_reader().
spacing();
172 virtual typename GridReader::Vector _origin()
const override {
173 return _access_reader().
origin();
176 virtual typename GridReader::Vector _basis_vector(
unsigned int i)
const override {
180 virtual bool _is_sequence()
const override {
184 std::size_t _number_of_steps()
const override {
185 return _steps.size();
188 double _time_at_step(std::size_t step_idx)
const override {
189 return _steps.at(step_idx).time;
194 _step_index = step_idx;
196 _read_current_field_names(names);
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";
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"))
210 std::string _get_piece_path(std::filesystem::path vtk_file,
211 std::filesystem::path pvtk_file)
const {
212 if (vtk_file.is_absolute())
214 return pvtk_file.parent_path() / vtk_file;
217 void _make_step_reader() {
218 const std::string&
filename = _steps.at(_step_index).filename;
219 _step_reader = _invoke_reader_factory(
filename);
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);
227 return _step_reader_factory(
filename);
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));
237 _step_reader.reset();
244 throw ValueError(
"No data available");
245 return *_step_reader;
249 StepReaderFactory _step_reader_factory;
250 std::unique_ptr<GridReader> _step_reader;
251 std::vector<Step> _steps;
252 std::size_t _step_index = 0;
Base class for grid data readers.
std::shared_ptr< const Field > FieldPtr
Pointer type used by writers/readers for fields.
Definition: field.hpp:186
Helper classes and functions for VTK XML-type file format writers & readers.