GridFormat 0.4.0
I/O-Library for grid-like data structures
Loading...
Searching...
No Matches
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_READER_HPP_
9#define GRIDFORMAT_READER_HPP_
10
11#include <array>
12#include <vector>
13#include <memory>
14#include <utility>
15#include <concepts>
16#include <functional>
17#include <optional>
18#include <algorithm>
19#include <iterator>
20#include <string>
21
22#include <gridformat/common/type_traits.hpp>
23#include <gridformat/parallel/concepts.hpp>
24#include <gridformat/parallel/communication.hpp>
26
27namespace GridFormat {
28
29namespace FileFormat { struct Any; }
30
31template<typename FileFormat>
32struct ReaderFactory;
33
34// Forward declaration, implementation in main API header.
35template<Concepts::Communicator C = NullCommunicator>
37 public:
38 AnyReaderFactory() requires(std::same_as<C, NullCommunicator>) = default;
39 explicit AnyReaderFactory(const C& comm) : _comm{comm} {}
40 std::unique_ptr<GridReader> make_for(const std::string& filename) const;
41 private:
42 C _comm;
43};
44
45#ifndef DOXYGEN
46namespace ReaderDetail {
47
48 template<typename FileFormat>
49 concept SequentiallyConstructible
50 = is_complete<ReaderFactory<FileFormat>>
51 and requires(const FileFormat& f) {
52 { ReaderFactory<FileFormat>::make(f) } -> std::derived_from<GridReader>;
53 };
54
55 template<typename FileFormat, typename Communicator>
56 concept ParallelConstructible
57 = is_complete<ReaderFactory<FileFormat>>
58 and Concepts::Communicator<Communicator>
59 and requires(const FileFormat& f, const Communicator& comm) {
60 { ReaderFactory<FileFormat>::make(f, comm) } -> std::derived_from<GridReader>;
61 };
62
63 template<typename FieldNameStorage>
64 void copy_field_names(const GridReader& reader, FieldNameStorage& names) {
65 std::ranges::copy(cell_field_names(reader), std::back_inserter(names.cell_fields));
66 std::ranges::copy(point_field_names(reader), std::back_inserter(names.point_fields));
67 std::ranges::copy(meta_data_field_names(reader), std::back_inserter(names.meta_data_fields));
68 }
69
70 using ReaderFactoryFunctor = std::function<std::unique_ptr<GridReader>(const std::string&)>;
71
72 template<Concepts::Communicator C = NullCommunicator>
73 ReaderFactoryFunctor default_reader_factory(const C& c = {}) {
74 if (!std::same_as<C, NullCommunicator>)
75 return [fac = AnyReaderFactory<C>{c}] (const std::string& f) { return fac.make_for(f); };
76 return [fac = AnyReaderFactory<>{}] (const std::string& f) { return fac.make_for(f); };
77 }
78
79} // namespace ReaderDetail
80#endif // DOXYGEN
81
94class Reader : public GridReader {
95 public:
96 using ReaderFactoryFunctor = ReaderDetail::ReaderFactoryFunctor;
97
98 Reader(ReaderFactoryFunctor f = ReaderDetail::default_reader_factory())
99 : _reader_factory{f}
100 {}
101
102 explicit Reader(const FileFormat::Any&, ReaderFactoryFunctor f = ReaderDetail::default_reader_factory())
103 : Reader(f)
104 {}
105
106 template<Concepts::Communicator C>
107 explicit Reader(const FileFormat::Any&, const C& c)
108 : Reader(ReaderDetail::default_reader_factory(c))
109 {}
110
111 template<ReaderDetail::SequentiallyConstructible FileFormat>
112 explicit Reader(const FileFormat& f)
113 : _reader{_make_unique(ReaderFactory<FileFormat>::make(f))}
114 {}
115
116 template<typename FileFormat,
117 Concepts::Communicator Communicator>
118 requires(ReaderDetail::ParallelConstructible<FileFormat, Communicator>)
119 explicit Reader(const FileFormat& f, const Communicator& c)
120 : _reader{_make_unique(ReaderFactory<FileFormat>::make(f, c))}
121 {}
122
124 template<typename... ConstructorArgs>
125 static Reader from(const std::string& filename, ConstructorArgs&&... args) {
126 return Reader{std::forward<ConstructorArgs>(args)...}.with_opened(filename);
127 }
128
130 Reader& with_opened(const std::string& filename) & {
131 this->open(filename);
132 return *this;
133 }
134
136 Reader&& with_opened(const std::string& filename) && {
137 this->open(filename);
138 return std::move(*this);
139 }
140
141 private:
142 template<typename ReaderImpl>
143 auto _make_unique(ReaderImpl&& reader) const {
144 return std::make_unique<std::remove_cvref_t<ReaderImpl>>(std::move(reader));
145 }
146
147 std::string _name() const override {
148 if (_reader_is_set())
149 return _access_reader().name();
150 return "undefined";
151 }
152
153 void _open(const std::string& filename, typename GridReader::FieldNames& names) override {
154 if (_reader_factory)
155 _reader = (*_reader_factory)(filename);
156 _access_reader().close();
157 _access_reader().open(filename);
158 ReaderDetail::copy_field_names(_access_reader(), names);
159 };
160
161 void _close() override {
162 _access_reader().close();
163 }
164
165 std::size_t _number_of_cells() const override {
166 return _access_reader().number_of_cells();
167 }
168
169 std::size_t _number_of_points() const override {
170 return _access_reader().number_of_points();
171 }
172
173 std::size_t _number_of_pieces() const override {
174 return _access_reader().number_of_pieces();
175 }
176
177 FieldPtr _cell_field(std::string_view name) const override {
178 return _access_reader().cell_field(name);
179 }
180
181 FieldPtr _point_field(std::string_view name) const override {
182 return _access_reader().point_field(name);
183 }
184
185 FieldPtr _meta_data_field(std::string_view name) const override {
186 return _access_reader().meta_data_field(name);
187 }
188
189 void _visit_cells(const CellVisitor& v) const override {
190 _access_reader().visit_cells(v);
191 }
192
193 FieldPtr _points() const override {
194 return _access_reader().points();
195 }
196
197 typename GridReader::PieceLocation _location() const override {
198 return _access_reader().location();
199 }
200
201 std::vector<double> _ordinates(unsigned int dir) const override {
202 return _access_reader().ordinates(dir);
203 }
204
205 std::array<double, 3> _spacing() const override {
206 return _access_reader().spacing();
207 }
208
209 std::array<double, 3> _origin() const override {
210 return _access_reader().origin();
211 }
212
213 std::array<double, 3> _basis_vector(unsigned int dir) const override {
214 return _access_reader().basis_vector(dir);
215 }
216
217 bool _is_sequence() const override {
218 return _access_reader().is_sequence();
219 }
220
221 std::size_t _number_of_steps() const override {
222 return _access_reader().number_of_steps();
223 }
224
225 double _time_at_step(std::size_t step) const override {
226 return _access_reader().time_at_step(step);
227 }
228
229 void _set_step(std::size_t step, typename GridReader::FieldNames& field_names) override {
230 _access_reader().set_step(step);
231 field_names.clear();
232 ReaderDetail::copy_field_names(_access_reader(), field_names);
233 }
234
235 const GridReader& _access_reader() const {
236 _check_reader_access();
237 return *_reader;
238 }
239
240 GridReader& _access_reader() {
241 _check_reader_access();
242 return *_reader;
243 }
244
245 void _check_reader_access() const {
246 if (!_reader_is_set())
247 throw InvalidState("No file has been read");
248 }
249
250 bool _reader_is_set() const {
251 return static_cast<bool>(_reader);
252 }
253
254 std::unique_ptr<GridReader> _reader;
255 std::optional<ReaderFactoryFunctor> _reader_factory;
256};
257
258} // namespace GridFormat
259
260#endif // GRIDFORMAT_WRITER_HPP_
Definition: reader.hpp:36
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
bool is_sequence() const
Return true if the read file is a sequence.
Definition: reader.hpp:152
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
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
void open(const std::string &filename)
Open the given grid file.
Definition: reader.hpp:78
void set_step(std::size_t step_idx)
Set the step from which to read data (only available for sequence formats)
Definition: reader.hpp:167
FieldPtr point_field(std::string_view name) const
Return the point field with the given name.
Definition: reader.hpp:216
double time_at_step(std::size_t step_idx) const
Return the time at the current step (only available for sequence formats)
Definition: reader.hpp:162
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
void close()
Close the grid file.
Definition: reader.hpp:85
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
std::size_t number_of_steps() const
Return the number of available steps (only available for sequence formats)
Definition: reader.hpp:157
Interface to the readers for all supported file formats.
Definition: reader.hpp:94
Reader && with_opened(const std::string &filename) &&
Read the data from the given file and return this reader (lvalue references overload)
Definition: reader.hpp:136
static Reader from(const std::string &filename, ConstructorArgs &&... args)
Construct a reader instance from the given arguments, while directly opening the given file.
Definition: reader.hpp:125
Reader & with_opened(const std::string &filename) &
Read the data from the given file and return this reader.
Definition: reader.hpp:130
Base class for grid data readers.
std::shared_ptr< const Field > FieldPtr
Pointer type used by writers/readers for fields.
Definition: field.hpp:186
Selector for an unspecified file format. When using this format, GridFormat will automatically select...
Definition: gridformat.hpp:204
Factory class to create a reader for the given file format.
Definition: gridformat.hpp:149