GCC Code Coverage Report


Directory: gridformat/
File: gridformat/vtk/hdf_image_grid_reader.hpp
Date: 2024-11-10 16:24:00
Exec Total Coverage
Lines: 170 190 89.5%
Functions: 34 63 54.0%
Branches: 190 454 41.9%

Line Branch Exec Source
1 // SPDX-FileCopyrightText: 2022-2023 Dennis Gläser <dennis.glaeser@iws.uni-stuttgart.de>
2 // SPDX-License-Identifier: MIT
3 /*!
4 * \file
5 * \ingroup VTK
6 * \brief Reader for the VTK HDF file format for image grids.
7 */
8 #ifndef GRIDFORMAT_VTK_HDF_IMAGE_GRID_READER_HPP_
9 #define GRIDFORMAT_VTK_HDF_IMAGE_GRID_READER_HPP_
10 #if GRIDFORMAT_HAVE_HIGH_FIVE
11
12 #include <iterator>
13 #include <optional>
14 #include <algorithm>
15 #include <functional>
16 #include <concepts>
17 #include <numeric>
18 #include <utility>
19 #include <ranges>
20
21 #include <gridformat/common/field.hpp>
22 #include <gridformat/common/field_transformations.hpp>
23 #include <gridformat/common/exceptions.hpp>
24 #include <gridformat/common/lazy_field.hpp>
25 #include <gridformat/common/ranges.hpp>
26
27 #include <gridformat/grid/reader.hpp>
28 #include <gridformat/parallel/concepts.hpp>
29 #include <gridformat/vtk/hdf_common.hpp>
30
31 namespace GridFormat {
32
33 /*!
34 * \ingroup VTK
35 * \brief Reader for the VTK-HDF file format for image grids.
36 */
37 class VTKHDFImageGridReader : public GridReader {
38 using Communicator = NullCommunicator;
39 using HDF5File = HDF5::File<Communicator>;
40 static constexpr std::size_t vtk_space_dim = 3;
41
42 public:
43 67 explicit VTKHDFImageGridReader() = default;
44
45 template<Concepts::Communicator C>
46 explicit VTKHDFImageGridReader(C&&) {
47 static_assert(
48 std::is_same_v<std::remove_cvref_t<C>, NullCommunicator>,
49 "Cannot read vtk-hdf image grid files in parallel"
50 );
51 }
52
53 private:
54 2 std::string _name() const override {
55
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (_is_transient())
56 return "VTKHDFImageGridReader (transient)";
57
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 return "VTKHDFImageGridReader";
58 }
59
60 68 void _open(const std::string& filename, typename GridReader::FieldNames& field_names) override {
61
2/4
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 68 times.
✗ Branch 5 not taken.
68 _file = HDF5File{filename, _comm, HDF5File::read_only};
62
63
2/4
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 68 times.
✗ Branch 5 not taken.
68 const auto type = VTKHDF::get_file_type(_file.value());
64
3/4
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 38 times.
✓ Branch 4 taken 30 times.
68 if (type != "ImageData")
65
3/6
✓ Branch 2 taken 38 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 38 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 38 times.
✗ Branch 10 not taken.
38 throw ValueError("Incompatible VTK-HDF type: '" + type + "', expected 'ImageData'.");
66
67
2/4
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
30 VTKHDF::check_version_compatibility(_file.value(), {2, 0});
68
69
4/6
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 30 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 15 times.
✓ Branch 9 taken 15 times.
90 if (_file->exists("/VTKHDF/Steps"))
70
2/4
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 15 times.
✗ Branch 6 not taken.
75 _file->visit_attribute("/VTKHDF/Steps/NSteps", [&] (auto&& field) {
71 30 _num_steps.emplace();
72 30 field.export_to(_num_steps.value());
73 30 _step_index.emplace(0);
74 30 });
75
76 90 const auto copy_names_in = [&] (const std::string& group, auto& storage) {
77
2/2
✓ Branch 2 taken 82 times.
✓ Branch 3 taken 8 times.
90 if (_file->exists(group))
78
2/4
✓ Branch 3 taken 82 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 82 times.
✗ Branch 7 not taken.
82 std::ranges::copy(_file->dataset_names_in(group), std::back_inserter(storage));
79 90 };
80
2/4
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
60 copy_names_in("VTKHDF/CellData", field_names.cell_fields);
81
2/4
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
60 copy_names_in("VTKHDF/PointData", field_names.point_fields);
82
2/4
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
60 copy_names_in("VTKHDF/FieldData", field_names.meta_data_fields);
83
84
3/6
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 30 times.
✗ Branch 8 not taken.
60 auto spacing = _file.value().template read_attribute_to<std::vector<double>>("/VTKHDF/Spacing");
85
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
30 if (spacing.size() != vtk_space_dim)
86 throw SizeError("Unexpected spacing vector read (size = " + as_string(spacing.size()) + ")");
87
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 _cell_spacing = Ranges::to_array<vtk_space_dim>(spacing);
88
89
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
60 auto direction = std::vector<double>{1., 0., 0., 0., 1., 0., 0., 0., 1.};
90
3/6
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 30 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 30 times.
✗ Branch 9 not taken.
90 if (_file->has_attribute_at("/VTKHDF/Direction"))
91
2/4
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 30 times.
✗ Branch 6 not taken.
90 direction = _file->template read_attribute_to<std::vector<double>>("/VTKHDF/Direction");
92
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
30 if (direction.size() != 9)
93 throw SizeError("Unexpected direction vector read (size = " + as_string(direction.size()) + ")");
94
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 _direction = Ranges::to_array<9>(direction);
95
96
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
60 auto origin = std::vector<double>{0., 0., 0.};
97
3/6
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 30 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 30 times.
✗ Branch 9 not taken.
90 if (_file->has_attribute_at("/VTKHDF/Origin"))
98
2/4
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 30 times.
✗ Branch 6 not taken.
90 origin = _file->template read_attribute_to<std::vector<double>>("/VTKHDF/Origin");
99
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
30 if (origin.size() != vtk_space_dim)
100 throw SizeError("Unexpected origin read (size = " + as_string(origin.size()) + ")");
101
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 _point_origin = Ranges::to_array<vtk_space_dim>(origin);
102
103
3/6
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 30 times.
✗ Branch 8 not taken.
60 auto extents = _file.value().template read_attribute_to<std::vector<std::size_t>>("/VTKHDF/WholeExtent");
104
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
30 if (extents.size() != 6)
105 throw SizeError("Unexpected 'WholeExtents' attribute (size = " + as_string(extents.size()) + ").");
106 30 _piece_location.lower_left = {extents[0], extents[2], extents[4]};
107 30 _piece_location.upper_right = {extents[1], extents[3], extents[5]};
108 68 }
109
110 void _close() override {
111 _file = {};
112 _piece_location = {};
113 _cell_spacing = {};
114 _point_origin = {};
115 _direction = {};
116 }
117
118 5 typename GridReader::PieceLocation _location() const override {
119 5 return _piece_location;
120 }
121
122 4 typename GridReader::Vector _spacing() const override {
123 4 return _cell_spacing;
124 }
125
126 2 typename GridReader::Vector _origin() const override {
127 2 return _point_origin;
128 }
129
130 1212 std::size_t _number_of_cells() const override {
131 1212 const auto counts = _get_extents();
132
2/4
✓ Branch 1 taken 1212 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1212 times.
✗ Branch 5 not taken.
4848 auto actives = counts | std::views::filter([] (auto e) { return e != 0; });
133
3/6
✓ Branch 1 taken 1212 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1212 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1212 times.
✗ Branch 8 not taken.
1212 return std::accumulate(
134 std::ranges::begin(actives),
135 std::ranges::end(actives),
136 std::size_t{1},
137 std::multiplies{}
138 2424 );
139 }
140
141 1403 std::size_t _number_of_points() const override {
142
1/2
✓ Branch 2 taken 1403 times.
✗ Branch 3 not taken.
1403 auto counts = Ranges::incremented(_get_extents(), 1);
143 1403 return std::accumulate(
144 std::ranges::begin(counts),
145 std::ranges::end(counts),
146 std::size_t{1},
147 std::multiplies{}
148 2806 );
149 }
150
151 2 std::size_t _number_of_pieces() const override {
152 2 return 1;
153 }
154
155 185 void _visit_cells(const typename GridReader::CellVisitor& visitor) const override {
156
1/2
✓ Branch 2 taken 185 times.
✗ Branch 3 not taken.
185 VTK::CommonDetail::visit_structured_cells(visitor, _make_vtk_extents_array());
157 185 }
158
159 65 FieldPtr _points() const override {
160 65 std::array<std::size_t, 6> extents = _make_vtk_extents_array();
161 65 extents[1] += 1;
162 65 extents[3] += 1;
163 65 extents[5] += 1;
164 65 return make_field_ptr(LazyField{
165 int{}, // dummy source
166
1/2
✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
65 MDLayout{{VTK::CommonDetail::number_of_entities(extents), std::size_t{vtk_space_dim}}},
167 Precision<double>{},
168 [ex=extents, o=_point_origin, s=_cell_spacing, d=_direction] (const int&) {
169 65 return VTK::CommonDetail::serialize_structured_points(ex, o, s, d);
170 }
171
3/6
✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 65 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 65 times.
✗ Branch 9 not taken.
195 });
172 }
173
174 25 bool _is_sequence() const override {
175 25 return _is_transient();
176 }
177
178 206 std::size_t _number_of_steps() const override {
179
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 206 times.
206 if (!_num_steps.has_value())
180 throw ValueError("Read file is not a sequence");
181 206 return _num_steps.value();
182 }
183
184 75 double _time_at_step(std::size_t step_idx) const override {
185
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 75 times.
75 if (step_idx >= _number_of_steps())
186 throw ValueError("Only " + as_string(_number_of_steps()) + " available");
187
4/12
✓ Branch 2 taken 75 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 75 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 75 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 75 times.
✗ Branch 14 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
450 return _file.value().template read_dataset_to<double>("/VTKHDF/Steps/Values", HDF5::Slice{
188 .offset = {step_idx},
189 .count = {1}
190 150 });
191 }
192
193 95 void _set_step(std::size_t step_idx, typename GridReader::FieldNames&) override {
194
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 95 times.
95 if (step_idx >= _number_of_steps())
195 throw ValueError("Only " + as_string(_number_of_steps()) + " available");
196 95 _step_index = step_idx;
197 95 }
198
199 1052 auto _serialization_callback(std::string path, std::size_t target_size) const {
200 1052 return [&, size=target_size, _step=_step_index, _p=std::move(path)] (const HDF5File& file) {
201
2/4
✓ Branch 1 taken 608 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 608 times.
✗ Branch 5 not taken.
608 auto count = file.get_dimensions(_p).value();
202
1/2
✓ Branch 1 taken 608 times.
✗ Branch 2 not taken.
608 auto offset = count;
203
1/2
✓ Branch 1 taken 608 times.
✗ Branch 2 not taken.
608 std::ranges::fill(offset, 0);
204
2/2
✓ Branch 1 taken 510 times.
✓ Branch 2 taken 98 times.
608 if (_step) {
205
1/2
✓ Branch 1 taken 510 times.
✗ Branch 2 not taken.
510 count.at(0) = 1;
206
2/4
✓ Branch 1 taken 510 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 510 times.
✗ Branch 5 not taken.
510 offset.at(0) = _step.value();
207 }
208 1824 return file.visit_dataset(_p, [&] <typename F> (F&& field) {
209
2/2
✓ Branch 1 taken 510 times.
✓ Branch 2 taken 98 times.
1216 const std::size_t step_offset = _step.has_value() ? 1 : 0;
210
1/2
✓ Branch 1 taken 608 times.
✗ Branch 2 not taken.
1216 const auto layout = field.layout();
211
4/6
✓ Branch 1 taken 608 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 608 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 396 times.
✓ Branch 7 taken 212 times.
1216 if (layout.dimension() == _grid_dimension() + step_offset)
212
3/6
✓ Branch 1 taken 396 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 396 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 396 times.
✗ Branch 9 not taken.
1584 return transform(make_field_ptr(std::move(field)), FieldTransformation::reshape_to(
213
1/2
✓ Branch 1 taken 396 times.
✗ Branch 2 not taken.
1584 MDLayout{{size}}
214
1/2
✓ Branch 2 taken 396 times.
✗ Branch 3 not taken.
792 ))->serialized();
215
3/6
✓ Branch 1 taken 212 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 212 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 212 times.
✗ Branch 7 not taken.
424 else if (layout.dimension() == _grid_dimension() + step_offset + 1)
216
3/6
✓ Branch 1 taken 212 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 212 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 212 times.
✗ Branch 9 not taken.
848 return transform(make_field_ptr(std::move(field)), FieldTransformation::reshape_to(
217
3/6
✓ Branch 1 taken 212 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 212 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 212 times.
✗ Branch 8 not taken.
424 MDLayout{{size, layout.extent(_grid_dimension() + step_offset)}}
218
1/2
✓ Branch 2 taken 212 times.
✗ Branch 3 not taken.
424 ))->serialized();
219 throw InvalidState("Unexpected field layout: " + as_string(layout));
220
3/10
✓ Branch 1 taken 608 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 608 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 608 times.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
3040 }, HDF5::Slice{.offset = offset, .count = count});
221 1660 };
222 }
223
224 492 FieldPtr _cell_field(std::string_view name) const override {
225
2/4
✓ Branch 1 taken 492 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 492 times.
✗ Branch 5 not taken.
492 const std::string path = "VTKHDF/CellData/" + std::string{name};
226
1/2
✓ Branch 2 taken 492 times.
✗ Branch 3 not taken.
492 const auto num_components = _get_number_of_components(path);
227
3/4
✓ Branch 1 taken 328 times.
✓ Branch 2 taken 164 times.
✓ Branch 4 taken 328 times.
✗ Branch 5 not taken.
492 const auto layout = num_components ? MDLayout{{_number_of_cells(), num_components.value()}}
228
4/8
✓ Branch 1 taken 328 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 328 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 164 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 164 times.
✗ Branch 11 not taken.
492 : MDLayout{{_number_of_cells()}};
229 492 return make_field_ptr(VTKHDF::DataSetField{
230 _file.value(),
231 492 std::move(layout),
232
3/6
✓ Branch 1 taken 492 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 492 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 492 times.
✗ Branch 8 not taken.
492 _file.value().get_precision(path).value(),
233
1/2
✓ Branch 1 taken 492 times.
✗ Branch 2 not taken.
984 _serialization_callback(path, _number_of_cells())
234
5/10
✓ Branch 1 taken 492 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 492 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 492 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 492 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 492 times.
✗ Branch 15 not taken.
2460 });
235 492 }
236
237 560 FieldPtr _point_field(std::string_view name) const override {
238
2/4
✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
560 const std::string path = "VTKHDF/PointData/" + std::string{name};
239
1/2
✓ Branch 2 taken 560 times.
✗ Branch 3 not taken.
560 const auto num_components = _get_number_of_components(path);
240
3/4
✓ Branch 1 taken 372 times.
✓ Branch 2 taken 188 times.
✓ Branch 4 taken 372 times.
✗ Branch 5 not taken.
560 const auto layout = num_components ? MDLayout{{_number_of_points(), num_components.value()}}
241
4/8
✓ Branch 1 taken 372 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 372 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 188 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 188 times.
✗ Branch 11 not taken.
560 : MDLayout{{_number_of_points()}};
242 560 return make_field_ptr(VTKHDF::DataSetField{
243 _file.value(),
244 560 std::move(layout),
245
3/6
✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 560 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 560 times.
✗ Branch 8 not taken.
560 _file.value().get_precision(path).value(),
246
1/2
✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
1120 _serialization_callback(path, _number_of_points())
247
5/10
✓ Branch 1 taken 560 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 560 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 560 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 560 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 560 times.
✗ Branch 15 not taken.
2800 });
248 560 }
249
250 30 FieldPtr _meta_data_field(std::string_view name) const override {
251
2/4
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
30 const auto path = "VTKHDF/FieldData/" + std::string{name};
252
3/6
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 30 times.
✗ Branch 8 not taken.
30 const auto dims = _file.value().get_dimensions(path).value();
253
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
30 if (dims.size() == 1)
254 return make_field_ptr(VTKHDF::DataSetField{_file.value(), path});
255
3/8
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 30 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 30 times.
30 if (dims.size() > 3 || (!_is_transient() && dims.size() != 2))
256 throw SizeError("Unexpected field data array size");
257
2/4
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 30 times.
30 if (dims.at(dims.size() - 2) != 1)
258 throw SizeError("Cannot only read one-dimensional field data");
259
260
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 auto offset = dims;
261
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 auto count = offset;
262
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 std::ranges::fill(offset, 0);
263
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 count.at(0) = 1;
264
3/6
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 30 times.
✗ Branch 8 not taken.
30 offset.at(0) = _is_transient() ? _step_index.value() : 0;
265 30 return make_field_ptr(VTKHDF::DataSetField{
266 _file.value(),
267
2/4
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
30 MDLayout{count | std::views::drop(1)},
268
3/6
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 30 times.
✗ Branch 8 not taken.
30 _file.value().get_precision(path).value(),
269
2/8
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
60 [p=path, o=offset, c=count] (const HDF5File& f) {
270 18 return f.visit_dataset(p, [&] <typename F> (F&& field) {
271
2/4
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
12 return FlattenedField{make_field_ptr(std::move(field))}.serialized();
272
3/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
12 }, HDF5::Slice{.offset = o, .count = c});
273 }
274
5/10
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 30 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 30 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 30 times.
✗ Branch 14 not taken.
90 });
275 30 }
276
277 250 std::array<std::size_t, 6> _make_vtk_extents_array() const {
278 std::array<std::size_t, 6> extents;
279 250 extents[0] = _piece_location.lower_left[0];
280 250 extents[2] = _piece_location.lower_left[1];
281 250 extents[4] = _piece_location.lower_left[2];
282 250 extents[1] = _piece_location.upper_right[0];
283 250 extents[3] = _piece_location.upper_right[1];
284 250 extents[5] = _piece_location.upper_right[2];
285 250 return extents;
286 }
287
288 1052 std::optional<std::size_t> _get_number_of_components(std::string_view path) const {
289
4/8
✓ Branch 1 taken 1052 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1052 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1052 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1052 times.
✗ Branch 11 not taken.
2104 const auto layout = _file.value().get_dimensions(std::string{path}).value();
290
2/2
✓ Branch 1 taken 870 times.
✓ Branch 2 taken 182 times.
1052 const std::size_t step_offset = _is_transient() ? 1 : 0;
291
3/4
✓ Branch 2 taken 1052 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 700 times.
✓ Branch 5 taken 352 times.
1052 if (layout.size() == _grid_dimension() + step_offset + 1)
292 700 return layout.back();
293 352 return {};
294 1052 }
295
296 2084 std::size_t _grid_dimension() const {
297
1/2
✓ Branch 2 taken 2084 times.
✗ Branch 3 not taken.
2084 return VTK::CommonDetail::structured_grid_dimension(_get_extents());
298 }
299
300 4699 std::array<std::size_t, 3> _get_extents() const {
301 return {
302 4699 _piece_location.upper_right[0] - _piece_location.lower_left[0],
303 4699 _piece_location.upper_right[1] - _piece_location.lower_left[1],
304 4699 _piece_location.upper_right[2] - _piece_location.lower_left[2]
305 14097 };
306 }
307
308 1139 bool _is_transient() const {
309 1139 return static_cast<bool>(_num_steps);
310 }
311
312 Communicator _comm;
313 std::optional<HDF5File> _file;
314 typename GridReader::PieceLocation _piece_location;
315 std::array<double, 9> _direction;
316 std::array<double, 3> _cell_spacing;
317 std::array<double, 3> _point_origin;
318 std::optional<std::size_t> _num_steps;
319 std::optional<std::size_t> _step_index;
320 };
321
322 } // namespace GridFormat
323
324 #endif // GRIDFORMAT_HAVE_HIGH_FIVE
325 #endif // GRIDFORMAT_VTK_HDF_IMAGE_GRID_READER_HPP_
326