GCC Code Coverage Report


Directory: gridformat/
File: gridformat/vtk/common.hpp
Date: 2025-03-26 17:08:15
Exec Total Coverage
Lines: 198 222 89.2%
Functions: 929 1383 67.2%
Branches: 282 752 37.5%

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 Common functionality for VTK writers
7 */
8 #ifndef GRIDFORMAT_VTK_COMMON_HPP_
9 #define GRIDFORMAT_VTK_COMMON_HPP_
10
11 #include <ranges>
12 #include <cassert>
13 #include <utility>
14 #include <type_traits>
15 #include <algorithm>
16 #include <array>
17 #include <cmath>
18
19 #include <gridformat/common/field.hpp>
20 #include <gridformat/common/concepts.hpp>
21 #include <gridformat/common/exceptions.hpp>
22 #include <gridformat/common/precision.hpp>
23 #include <gridformat/common/serialization.hpp>
24 #include <gridformat/common/md_layout.hpp>
25 #include <gridformat/common/ranges.hpp>
26 #include <gridformat/common/matrix.hpp>
27 #include <gridformat/common/type_traits.hpp>
28 #include <gridformat/common/string_conversion.hpp>
29 #include <gridformat/common/flat_index_mapper.hpp>
30 #include <gridformat/common/field_transformations.hpp>
31 #include <gridformat/common/field.hpp>
32
33 #include <gridformat/grid/entity_fields.hpp>
34 #include <gridformat/grid/cell_type.hpp>
35 #include <gridformat/grid/concepts.hpp>
36 #include <gridformat/grid/_detail.hpp>
37 #include <gridformat/grid/grid.hpp>
38
39 #ifndef DOXYGEN
40 namespace GridFormat::Encoding { struct Ascii; struct Base64; struct RawBinary; }
41 #endif // DOXYGEN
42
43 namespace GridFormat::VTK {
44
45 //! \addtogroup VTK
46 //! \{
47
48 namespace DataFormat {
49
50 struct Inlined {}; //!< Inline data format (inside xml elements)
51 struct Appended {}; //!< Appended data format (all data is appended at the end of the xml file)
52
53 inline constexpr Inlined inlined; //!< Instance of the inline data format
54 inline constexpr Appended appended; //!< Instance of the appended data format
55
56 } // namespace DataFormat
57
58 #ifndef DOXYGEN
59 namespace Traits {
60
61 template<typename T> struct ProducesValidXML;
62 template<> struct ProducesValidXML<Encoding::Ascii> : public std::true_type {};
63 template<> struct ProducesValidXML<Encoding::Base64> : public std::true_type {};
64 template<> struct ProducesValidXML<Encoding::RawBinary> : public std::false_type {};
65
66 } // namespace Traits
67
68 template<typename Encoder>
69 12148 inline constexpr bool produces_valid_xml(const Encoder&) {
70 static_assert(
71 is_complete<Traits::ProducesValidXML<Encoder>>,
72 "Traits::ProducesValidXML was not specialized for the given encoder"
73 );
74 12148 return Traits::ProducesValidXML<Encoder>::value;
75 }
76
77 34602 inline constexpr std::uint8_t cell_type_number(CellType t) {
78
14/16
✓ Branch 0 taken 135 times.
✓ Branch 1 taken 465 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 655 times.
✓ Branch 4 taken 18050 times.
✓ Branch 5 taken 3039 times.
✓ Branch 6 taken 143 times.
✓ Branch 7 taken 1732 times.
✓ Branch 8 taken 923 times.
✓ Branch 9 taken 3000 times.
✓ Branch 10 taken 46 times.
✓ Branch 11 taken 727 times.
✓ Branch 12 taken 463 times.
✓ Branch 13 taken 4483 times.
✓ Branch 14 taken 741 times.
✗ Branch 15 not taken.
34602 switch (t) {
79 135 case (CellType::vertex): return 1;
80 465 case (CellType::segment): return 3;
81 case (CellType::polyline): return 4;
82 655 case (CellType::triangle): return 5;
83 18050 case (CellType::pixel): return 8;
84 3039 case (CellType::quadrilateral): return 9;
85 143 case (CellType::polygon): return 7;
86 1732 case (CellType::tetrahedron): return 10;
87 923 case (CellType::hexahedron): return 12;
88 3000 case (CellType::voxel): return 11;
89 46 case (CellType::lagrange_segment): return 68;
90 727 case (CellType::lagrange_triangle): return 69;
91 463 case (CellType::lagrange_quadrilateral): return 70;
92 4483 case (CellType::lagrange_tetrahedron): return 71;
93 741 case (CellType::lagrange_hexahedron): return 72;
94 }
95
96 throw NotImplemented("VTK cell type number for the given cell type");
97 }
98
99 10004 inline constexpr CellType cell_type(std::uint8_t vtk_id) {
100
4/16
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 35 times.
✓ Branch 4 taken 1200 times.
✓ Branch 5 taken 8734 times.
✓ Branch 6 taken 35 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
10004 switch (vtk_id) {
101 case 1: return CellType::vertex;
102 case 3: return CellType::segment;
103 case 4: return CellType::polyline;
104 35 case 5: return CellType::triangle;
105 1200 case 8: return CellType::pixel;
106 8734 case 9: return CellType::quadrilateral;
107 35 case 7: return CellType::polygon;
108 case 10: return CellType::tetrahedron;
109 case 12: return CellType::hexahedron;
110 case 11: return CellType::voxel;
111 case 68: return CellType::lagrange_segment;
112 case 69: return CellType::lagrange_triangle;
113 case 70: return CellType::lagrange_quadrilateral;
114 case 71: return CellType::lagrange_tetrahedron;
115 case 72: return CellType::lagrange_hexahedron;
116 }
117
118 throw NotImplemented("Cell type for the given VTK cell type number: " + std::to_string(vtk_id));
119 }
120
121 93336 FieldPtr make_vtk_field(FieldPtr field) {
122
1/2
✓ Branch 2 taken 93336 times.
✗ Branch 3 not taken.
93336 const auto layout = field->layout();
123
3/4
✓ Branch 1 taken 93336 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 32990 times.
✓ Branch 4 taken 60346 times.
93336 if (layout.dimension() < 2)
124 32990 return field;
125 // (maybe) make vector/tensor fields 3d
126
1/2
✓ Branch 1 taken 60346 times.
✗ Branch 2 not taken.
60346 if (std::ranges::all_of(
127
4/6
✓ Branch 1 taken 60346 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 60346 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 16621 times.
✓ Branch 7 taken 43725 times.
120692 std::views::iota(std::size_t{1}, layout.dimension()),
128 68033 [&] (const std::size_t codim) { return layout.extent(codim) < 3; }
129 ))
130
1/2
✓ Branch 3 taken 16621 times.
✗ Branch 4 not taken.
16621 return transform(field, FieldTransformation::extend_all_to(3));
131 43725 return field;
132 93336 }
133
134 template<std::derived_from<Field> F>
135 requires(!std::is_lvalue_reference_v<F>)
136 14122 FieldPtr make_vtk_field(F&& field) {
137
2/4
✓ Branch 2 taken 7061 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 7061 times.
✗ Branch 6 not taken.
14122 return make_vtk_field(make_field_ptr(std::forward<F>(field)));
138 }
139
140 template<typename ctype, GridDetail::ExposesPointRange Grid>
141 6739 auto make_coordinates_field(const Grid& grid, bool structured_grid_ordering) {
142 6739 return make_vtk_field(PointField{
143 grid,
144 145921 [&] (const auto& point) { return coordinates(grid, point); },
145 structured_grid_ordering,
146 Precision<ctype>{}
147
1/2
✓ Branch 1 taken 3419 times.
✗ Branch 2 not taken.
13478 });
148 }
149
150 template<typename HeaderType = std::size_t,
151 Concepts::UnstructuredGrid Grid,
152 std::ranges::forward_range Cells,
153 typename PointMap>
154 requires(std::is_lvalue_reference_v<PointMap>)
155 2751 auto make_connectivity_field(const Grid& grid,
156 Cells&& cells,
157 PointMap&& map) {
158 class ConnectivityField : public Field {
159 public:
160 1425 explicit ConnectivityField(const Grid& g,
161 Cells&& cells,
162 PointMap&& map)
163 1425 : _grid(g)
164 2804 , _cells{std::forward<Cells>(cells)}
165 1471 , _point_map{std::forward<PointMap>(map)} {
166 1425 _num_values = 0;
167
1/2
✓ Branch 1 taken 99 times.
✗ Branch 2 not taken.
75263 std::ranges::for_each(_cells, [&] (const auto& cell) {
168 38290 _num_values += number_of_points(_grid, cell);
169 });
170 1425 }
171
172 private:
173
1/2
✓ Branch 1 taken 396 times.
✗ Branch 2 not taken.
4533 MDLayout _layout() const override { return MDLayout{{_num_values}}; }
174 4153 DynamicPrecision _precision() const override { return Precision<HeaderType>{}; }
175 1403 Serialization _serialized() const override {
176
1/2
✓ Branch 1 taken 99 times.
✗ Branch 2 not taken.
1403 Serialization serialization(sizeof(HeaderType)*_num_values);
177
1/2
✓ Branch 1 taken 99 times.
✗ Branch 2 not taken.
1403 HeaderType* data = serialization.as_span_of<HeaderType>().data();
178
179 1403 std::size_t i = 0;
180
1/2
✓ Branch 1 taken 99 times.
✗ Branch 2 not taken.
75029 std::ranges::for_each(_cells, [&] (const auto& cell) {
181
72/242
✓ Branch 1 taken 6747 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6747 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 434 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 434 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 9173 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 9173 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 3084 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 3084 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 944 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 944 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 13992 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 13992 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 292 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 292 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 312 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 312 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 64 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 64 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 702 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 702 times.
✗ Branch 59 not taken.
✓ Branch 61 taken 950 times.
✗ Branch 62 not taken.
✓ Branch 64 taken 950 times.
✗ Branch 65 not taken.
✓ Branch 67 taken 1170 times.
✗ Branch 68 not taken.
✓ Branch 70 taken 1170 times.
✗ Branch 71 not taken.
✓ Branch 73 taken 42 times.
✗ Branch 74 not taken.
✓ Branch 76 taken 42 times.
✗ Branch 77 not taken.
✓ Branch 79 taken 3 times.
✗ Branch 80 not taken.
✓ Branch 82 taken 3 times.
✗ Branch 83 not taken.
✓ Branch 85 taken 45 times.
✗ Branch 86 not taken.
✓ Branch 88 taken 45 times.
✗ Branch 89 not taken.
✓ Branch 91 taken 3 times.
✗ Branch 92 not taken.
✓ Branch 94 taken 3 times.
✗ Branch 95 not taken.
✓ Branch 97 taken 10 times.
✗ Branch 98 not taken.
✓ Branch 100 taken 10 times.
✗ Branch 101 not taken.
✓ Branch 103 taken 13 times.
✗ Branch 104 not taken.
✓ Branch 106 taken 13 times.
✗ Branch 107 not taken.
✓ Branch 109 taken 14 times.
✗ Branch 110 not taken.
✓ Branch 112 taken 14 times.
✗ Branch 113 not taken.
✓ Branch 115 taken 10 times.
✗ Branch 116 not taken.
✓ Branch 118 taken 10 times.
✗ Branch 119 not taken.
✓ Branch 121 taken 7 times.
✗ Branch 122 not taken.
✓ Branch 124 taken 7 times.
✗ Branch 125 not taken.
✓ Branch 127 taken 9 times.
✗ Branch 128 not taken.
✓ Branch 130 taken 9 times.
✗ Branch 131 not taken.
✓ Branch 133 taken 4 times.
✗ Branch 134 not taken.
✓ Branch 136 taken 4 times.
✗ Branch 137 not taken.
✓ Branch 139 taken 14 times.
✗ Branch 140 not taken.
✓ Branch 142 taken 14 times.
✗ Branch 143 not taken.
✓ Branch 145 taken 4 times.
✗ Branch 146 not taken.
✓ Branch 148 taken 4 times.
✗ Branch 149 not taken.
✓ Branch 151 taken 14 times.
✗ Branch 152 not taken.
✓ Branch 154 taken 14 times.
✗ Branch 155 not taken.
✓ Branch 157 taken 4 times.
✗ Branch 158 not taken.
✓ Branch 160 taken 4 times.
✗ Branch 161 not taken.
✓ Branch 163 taken 22 times.
✗ Branch 164 not taken.
✓ Branch 166 taken 22 times.
✗ Branch 167 not taken.
✓ Branch 169 taken 15 times.
✗ Branch 170 not taken.
✓ Branch 172 taken 15 times.
✗ Branch 173 not taken.
✓ Branch 175 taken 12 times.
✗ Branch 176 not taken.
✓ Branch 178 taken 12 times.
✗ Branch 179 not taken.
✓ Branch 181 taken 15 times.
✗ Branch 182 not taken.
✓ Branch 184 taken 15 times.
✗ Branch 185 not taken.
✓ Branch 187 taken 12 times.
✗ Branch 188 not taken.
✓ Branch 190 taken 12 times.
✗ Branch 191 not taken.
✓ Branch 193 taken 12 times.
✗ Branch 194 not taken.
✓ Branch 196 taken 12 times.
✗ Branch 197 not taken.
✓ Branch 199 taken 12 times.
✗ Branch 200 not taken.
✓ Branch 202 taken 12 times.
✗ Branch 203 not taken.
✓ Branch 205 taken 12 times.
✗ Branch 206 not taken.
✓ Branch 208 taken 12 times.
✗ Branch 209 not taken.
✓ Branch 211 taken 12 times.
✗ Branch 212 not taken.
✓ Branch 214 taken 12 times.
✗ Branch 215 not taken.
✗ Branch 217 not taken.
✗ Branch 218 not taken.
✗ Branch 220 not taken.
✗ Branch 221 not taken.
✗ Branch 223 not taken.
✗ Branch 224 not taken.
✗ Branch 226 not taken.
✗ Branch 227 not taken.
✗ Branch 229 not taken.
✗ Branch 230 not taken.
✗ Branch 232 not taken.
✗ Branch 233 not taken.
✗ Branch 235 not taken.
✗ Branch 236 not taken.
✗ Branch 238 not taken.
✗ Branch 239 not taken.
✗ Branch 241 not taken.
✗ Branch 242 not taken.
✗ Branch 244 not taken.
✗ Branch 245 not taken.
✗ Branch 247 not taken.
✗ Branch 248 not taken.
✗ Branch 250 not taken.
✗ Branch 251 not taken.
✗ Branch 253 not taken.
✗ Branch 254 not taken.
✗ Branch 256 not taken.
✗ Branch 257 not taken.
✗ Branch 259 not taken.
✗ Branch 260 not taken.
✗ Branch 262 not taken.
✗ Branch 263 not taken.
✗ Branch 265 not taken.
✗ Branch 266 not taken.
✗ Branch 268 not taken.
✗ Branch 269 not taken.
✗ Branch 271 not taken.
✗ Branch 272 not taken.
✗ Branch 274 not taken.
✗ Branch 275 not taken.
✗ Branch 277 not taken.
✗ Branch 278 not taken.
✗ Branch 280 not taken.
✗ Branch 281 not taken.
✗ Branch 283 not taken.
✗ Branch 284 not taken.
✗ Branch 286 not taken.
✗ Branch 287 not taken.
✗ Branch 289 not taken.
✗ Branch 290 not taken.
✗ Branch 292 not taken.
✗ Branch 293 not taken.
✗ Branch 295 not taken.
✗ Branch 296 not taken.
✗ Branch 298 not taken.
✗ Branch 299 not taken.
✗ Branch 301 not taken.
✗ Branch 302 not taken.
✗ Branch 304 not taken.
✗ Branch 305 not taken.
✗ Branch 307 not taken.
✗ Branch 308 not taken.
✗ Branch 310 not taken.
✗ Branch 311 not taken.
✗ Branch 313 not taken.
✗ Branch 314 not taken.
✗ Branch 316 not taken.
✗ Branch 317 not taken.
✗ Branch 319 not taken.
✗ Branch 320 not taken.
✗ Branch 322 not taken.
✗ Branch 323 not taken.
✗ Branch 325 not taken.
✗ Branch 326 not taken.
✗ Branch 328 not taken.
✗ Branch 329 not taken.
✗ Branch 331 not taken.
✗ Branch 332 not taken.
✗ Branch 334 not taken.
✗ Branch 335 not taken.
✗ Branch 337 not taken.
✗ Branch 338 not taken.
✗ Branch 340 not taken.
✗ Branch 341 not taken.
✗ Branch 343 not taken.
✗ Branch 344 not taken.
✗ Branch 346 not taken.
✗ Branch 347 not taken.
✗ Branch 349 not taken.
✗ Branch 350 not taken.
✗ Branch 352 not taken.
✗ Branch 353 not taken.
✗ Branch 355 not taken.
✗ Branch 356 not taken.
✗ Branch 358 not taken.
✗ Branch 359 not taken.
380310 std::ranges::for_each(points(_grid, cell), [&] (const auto& point) {
182
84/272
✓ Branch 1 taken 9844 times.
✓ Branch 2 taken 29640 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9844 times.
✓ Branch 5 taken 400 times.
✓ Branch 6 taken 446 times.
✓ Branch 7 taken 694 times.
✓ Branch 8 taken 400 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 33767 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 8406 times.
✓ Branch 14 taken 84 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 8406 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 42 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 12000 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 4882 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 3606 times.
✓ Branch 26 taken 280 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 3606 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 560 times.
✓ Branch 31 taken 25736 times.
✓ Branch 32 taken 25200 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 25904 times.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✓ Branch 37 taken 652 times.
✓ Branch 38 taken 448 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 652 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 168 times.
✓ Branch 43 taken 172 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 452 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 12 times.
✓ Branch 50 taken 342 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 12 times.
✗ Branch 53 not taken.
✓ Branch 54 taken 1191 times.
✓ Branch 55 taken 3852 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 6797 times.
✗ Branch 59 not taken.
✓ Branch 61 taken 3852 times.
✓ Branch 62 taken 11631 times.
✗ Branch 63 not taken.
✓ Branch 64 taken 3852 times.
✗ Branch 65 not taken.
✓ Branch 66 taken 20 times.
✓ Branch 67 taken 12 times.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✓ Branch 70 taken 35 times.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✓ Branch 74 taken 20 times.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✓ Branch 78 taken 15 times.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✓ Branch 82 taken 12 times.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✓ Branch 86 taken 15 times.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✓ Branch 94 taken 20 times.
✗ Branch 95 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✓ Branch 102 taken 20 times.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✓ Branch 109 taken 12 times.
✓ Branch 110 taken 20 times.
✗ Branch 111 not taken.
✓ Branch 112 taken 12 times.
✗ Branch 113 not taken.
✓ Branch 114 taken 12 times.
✓ Branch 115 taken 12 times.
✗ Branch 116 not taken.
✓ Branch 118 taken 12 times.
✗ Branch 119 not taken.
✓ Branch 121 taken 12 times.
✓ Branch 122 taken 12 times.
✗ Branch 123 not taken.
✓ Branch 124 taken 12 times.
✗ Branch 125 not taken.
✗ Branch 126 not taken.
✓ Branch 127 taken 12 times.
✗ Branch 128 not taken.
✓ Branch 130 taken 12 times.
✗ Branch 131 not taken.
✓ Branch 133 taken 12 times.
✗ Branch 134 not taken.
✓ Branch 136 taken 12 times.
✗ Branch 137 not taken.
✓ Branch 139 taken 12 times.
✗ Branch 140 not taken.
✓ Branch 142 taken 12 times.
✗ Branch 143 not taken.
✓ Branch 145 taken 12 times.
✗ Branch 146 not taken.
✓ Branch 148 taken 12 times.
✗ Branch 149 not taken.
✓ Branch 151 taken 12 times.
✗ Branch 152 not taken.
✓ Branch 154 taken 12 times.
✗ Branch 155 not taken.
✓ Branch 157 taken 12 times.
✗ Branch 158 not taken.
✓ Branch 160 taken 12 times.
✗ Branch 161 not taken.
✓ Branch 163 taken 48 times.
✗ Branch 164 not taken.
✓ Branch 166 taken 48 times.
✗ Branch 167 not taken.
✓ Branch 169 taken 48 times.
✗ Branch 170 not taken.
✓ Branch 172 taken 48 times.
✗ Branch 173 not taken.
✓ Branch 175 taken 48 times.
✗ Branch 176 not taken.
✓ Branch 178 taken 48 times.
✗ Branch 179 not taken.
✓ Branch 181 taken 48 times.
✗ Branch 182 not taken.
✓ Branch 184 taken 48 times.
✗ Branch 185 not taken.
✓ Branch 187 taken 48 times.
✗ Branch 188 not taken.
✓ Branch 190 taken 48 times.
✗ Branch 191 not taken.
✓ Branch 193 taken 48 times.
✗ Branch 194 not taken.
✓ Branch 196 taken 48 times.
✗ Branch 197 not taken.
✓ Branch 199 taken 48 times.
✗ Branch 200 not taken.
✓ Branch 202 taken 48 times.
✗ Branch 203 not taken.
✓ Branch 205 taken 48 times.
✗ Branch 206 not taken.
✓ Branch 208 taken 48 times.
✗ Branch 209 not taken.
✓ Branch 211 taken 48 times.
✗ Branch 212 not taken.
✓ Branch 214 taken 48 times.
✗ Branch 215 not taken.
✗ Branch 217 not taken.
✗ Branch 218 not taken.
✗ Branch 220 not taken.
✗ Branch 221 not taken.
✗ Branch 223 not taken.
✗ Branch 224 not taken.
✗ Branch 226 not taken.
✗ Branch 227 not taken.
✗ Branch 229 not taken.
✗ Branch 230 not taken.
✗ Branch 232 not taken.
✗ Branch 233 not taken.
✗ Branch 235 not taken.
✗ Branch 236 not taken.
✗ Branch 238 not taken.
✗ Branch 239 not taken.
✗ Branch 241 not taken.
✗ Branch 242 not taken.
✗ Branch 244 not taken.
✗ Branch 245 not taken.
✗ Branch 247 not taken.
✗ Branch 248 not taken.
✗ Branch 250 not taken.
✗ Branch 251 not taken.
✗ Branch 253 not taken.
✗ Branch 254 not taken.
✗ Branch 256 not taken.
✗ Branch 257 not taken.
✗ Branch 259 not taken.
✗ Branch 260 not taken.
✗ Branch 262 not taken.
✗ Branch 263 not taken.
✗ Branch 265 not taken.
✗ Branch 266 not taken.
✗ Branch 268 not taken.
✗ Branch 269 not taken.
✗ Branch 271 not taken.
✗ Branch 272 not taken.
✗ Branch 274 not taken.
✗ Branch 275 not taken.
✗ Branch 277 not taken.
✗ Branch 278 not taken.
✗ Branch 280 not taken.
✗ Branch 281 not taken.
✗ Branch 283 not taken.
✗ Branch 284 not taken.
✗ Branch 286 not taken.
✗ Branch 287 not taken.
✗ Branch 289 not taken.
✗ Branch 290 not taken.
✗ Branch 292 not taken.
✗ Branch 293 not taken.
✗ Branch 295 not taken.
✗ Branch 296 not taken.
✗ Branch 298 not taken.
✗ Branch 299 not taken.
✗ Branch 301 not taken.
✗ Branch 302 not taken.
✗ Branch 304 not taken.
✗ Branch 305 not taken.
✗ Branch 307 not taken.
✗ Branch 308 not taken.
✗ Branch 310 not taken.
✗ Branch 311 not taken.
✗ Branch 313 not taken.
✗ Branch 314 not taken.
✗ Branch 316 not taken.
✗ Branch 317 not taken.
✗ Branch 319 not taken.
✗ Branch 320 not taken.
✗ Branch 322 not taken.
✗ Branch 323 not taken.
✗ Branch 325 not taken.
✗ Branch 326 not taken.
✗ Branch 328 not taken.
✗ Branch 329 not taken.
✗ Branch 331 not taken.
✗ Branch 332 not taken.
✗ Branch 334 not taken.
✗ Branch 335 not taken.
✗ Branch 337 not taken.
✗ Branch 338 not taken.
✗ Branch 340 not taken.
✗ Branch 341 not taken.
✗ Branch 343 not taken.
✗ Branch 344 not taken.
✗ Branch 346 not taken.
✗ Branch 347 not taken.
✗ Branch 349 not taken.
✗ Branch 350 not taken.
✗ Branch 352 not taken.
✗ Branch 353 not taken.
✗ Branch 355 not taken.
✗ Branch 356 not taken.
✗ Branch 358 not taken.
✗ Branch 359 not taken.
181347 data[i] = _point_map.at(id(_grid, point));
183 181347 i++;
184 });
185 });
186 1403 return serialization;
187 }
188
189 const Grid& _grid;
190 LVReferenceOrValue<Cells> _cells;
191 LVReferenceOrValue<PointMap> _point_map;
192 HeaderType _num_values;
193
1/2
✓ Branch 3 taken 1425 times.
✗ Branch 4 not taken.
2751 } _field{grid, std::forward<Cells>(cells), std::forward<PointMap>(map)};
194
195
1/2
✓ Branch 2 taken 1425 times.
✗ Branch 3 not taken.
5502 return make_vtk_field(std::move(_field));
196 2751 }
197
198 template<typename HeaderType = std::size_t,
199 Concepts::UnstructuredGrid Grid,
200 typename PointMap>
201 1485 auto make_connectivity_field(const Grid& grid, PointMap&& map) {
202
3/5
✓ Branch 2 taken 321 times.
✓ Branch 3 taken 471 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 321 times.
✗ Branch 6 not taken.
2970 return make_connectivity_field<HeaderType>(grid, cells(grid), std::forward<PointMap>(map));
203 }
204
205 template<typename HeaderType = std::size_t,
206 Concepts::UnstructuredGrid Grid,
207 std::ranges::range Cells>
208 2751 auto make_offsets_field(const Grid& grid, Cells&& cells) {
209 class OffsetField : public Field {
210 public:
211 1425 explicit OffsetField(const Grid& g, Cells&& cells)
212 1425 : _grid(g)
213 2804 , _cells{std::forward<Cells>(cells)}
214 1471 , _num_cells{static_cast<HeaderType>(Ranges::size(_cells))}
215 1425 {}
216
217 private:
218
1/2
✓ Branch 1 taken 396 times.
✗ Branch 2 not taken.
4533 MDLayout _layout() const override { return MDLayout{{_num_cells}}; }
219 4153 DynamicPrecision _precision() const override { return Precision<HeaderType>{}; }
220 1403 Serialization _serialized() const override {
221
1/2
✓ Branch 1 taken 99 times.
✗ Branch 2 not taken.
1403 Serialization serialization(sizeof(HeaderType)*_num_cells);
222
1/2
✓ Branch 1 taken 99 times.
✗ Branch 2 not taken.
1403 HeaderType* data = serialization.as_span_of<HeaderType>().data();
223
224 1403 std::size_t i = 0;
225 1403 HeaderType offset = 0;
226
1/2
✓ Branch 1 taken 99 times.
✗ Branch 2 not taken.
75029 std::ranges::for_each(_cells, [&] (const auto& cell) {
227 38184 offset += number_of_points(_grid, cell);
228 38184 data[i] = offset;
229 38184 i++;
230 });
231 1403 return serialization;
232 }
233
234 const Grid& _grid;
235 LVReferenceOrValue<Cells> _cells;
236 HeaderType _num_cells;
237
1/2
✓ Branch 2 taken 800 times.
✗ Branch 3 not taken.
2751 } _field{grid, std::forward<Cells>(cells)};
238
239
1/2
✓ Branch 2 taken 1425 times.
✗ Branch 3 not taken.
5502 return make_vtk_field(std::move(_field));
240 2751 }
241
242 template<typename HeaderType = std::size_t, Concepts::UnstructuredGrid Grid>
243 1485 auto make_offsets_field(const Grid& grid) {
244
3/5
✓ Branch 1 taken 321 times.
✓ Branch 2 taken 471 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 321 times.
✗ Branch 5 not taken.
1485 return make_offsets_field<HeaderType>(grid, cells(grid));
245 }
246
247 template<Concepts::UnstructuredGrid Grid>
248 1300 auto make_cell_types_field(const Grid& grid) {
249 1300 return make_vtk_field(CellField{
250 grid,
251 25325 [&] (const auto& cell) {
252 34602 return VTK::cell_type_number(type(grid, cell));
253 },
254 false
255
1/2
✓ Branch 1 taken 792 times.
✗ Branch 2 not taken.
2600 });
256 }
257
258 107238 inline auto active_array_attribute_for_rank(unsigned int rank) {
259
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 107238 times.
107238 if (rank > 2)
260 throw ValueError("Rank must be <= 2");
261 static constexpr std::array attributes{"Scalars", "Vectors", "Tensors"};
262 107238 return attributes[rank];
263 }
264
265 namespace CommonDetail {
266
267 template<Concepts::StaticallySizedRange R>
268 30486 std::string number_string_3d(const R& r) {
269 static_assert(static_size<R> >= 1 || static_size<R> <= 3);
270 if constexpr (static_size<R> == 3)
271
1/2
✓ Branch 2 taken 12055 times.
✗ Branch 3 not taken.
24110 return as_string(r);
272 if constexpr (static_size<R> == 2)
273
2/4
✓ Branch 2 taken 3188 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3188 times.
✗ Branch 6 not taken.
6376 return as_string(r) + " 0";
274 if constexpr (static_size<R> == 1)
275 return as_string(r) + " 0 0";
276 }
277
278 template<Concepts::StaticallySizedMDRange<2> R>
279 6294 std::string direction_string(const R& basis) {
280
1/2
✓ Branch 1 taken 3208 times.
✗ Branch 2 not taken.
6294 Matrix m{basis};
281 6294 m.transpose();
282
283
1/2
✓ Branch 1 taken 3208 times.
✗ Branch 2 not taken.
6294 std::string result = "";
284
1/2
✓ Branch 1 taken 3208 times.
✗ Branch 2 not taken.
23458 std::ranges::for_each(m, [&] (const auto& row) {
285
4/4
✓ Branch 1 taken 799 times.
✓ Branch 2 taken 798 times.
✓ Branch 4 taken 4820 times.
✓ Branch 5 taken 2410 times.
8827 if (result != "")
286 5619 result += " ";
287
4/8
✓ Branch 1 taken 1597 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1597 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 7230 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 7230 times.
✗ Branch 13 not taken.
8827 result += number_string_3d(row);
288 });
289
2/2
✓ Branch 0 taken 797 times.
✓ Branch 1 taken 3208 times.
7767 for (int i = static_size<R>; i < 3; ++i)
290
1/2
✓ Branch 1 taken 797 times.
✗ Branch 2 not taken.
1473 result += " 0 0 0";
291 6294 return result;
292 }
293
294 template<Concepts::StaticallySizedRange R1,
295 Concepts::StaticallySizedRange R2>
296 requires(std::integral<std::ranges::range_value_t<R1>> and
297 std::integral<std::ranges::range_value_t<R2>>)
298 44313 std::array<std::size_t, 6> get_extents(const R1& from, const R2& to) {
299 static_assert(static_size<R1> == static_size<R2>);
300 static_assert(static_size<R1> <= 3);
301
302 44313 int i = 0;
303 44313 auto result = Ranges::filled_array<6>(std::size_t{0});
304 44313 auto it1 = std::ranges::begin(from);
305 44313 auto it2 = std::ranges::begin(to);
306
2/2
✓ Branch 1 taken 62172 times.
✓ Branch 2 taken 22493 times.
167288 for (; it1 != std::ranges::end(from); ++it1, ++it2, ++i) {
307 122975 result[i*2 + 0] = *it1;
308 122975 result[i*2 + 1] = *it2;
309 }
310 44313 return result;
311 }
312
313 template<Concepts::StaticallySizedRange R>
314 235 std::array<std::size_t, 6> get_extents(const R& to) {
315 using T = std::ranges::range_value_t<R>;
316
2/4
✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
235 return get_extents(Ranges::filled_array<static_size<R>>(T{0}), to);
317 }
318
319 template<Concepts::StaticallySizedRange R1,
320 Concepts::StaticallySizedRange R2>
321 44078 std::string extents_string(const R1& from, const R2& to) {
322
2/4
✓ Branch 2 taken 22338 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 22338 times.
✗ Branch 6 not taken.
44078 return as_string(get_extents(from, to));
323 }
324
325 template<Concepts::StaticallySizedRange R>
326 20222 std::string extents_string(const R& r) {
327 using T = std::ranges::range_value_t<R>;
328
2/4
✓ Branch 1 taken 10274 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10274 times.
✗ Branch 5 not taken.
20222 return extents_string(Ranges::filled_array<static_size<R>>(T{0}), r);
329 }
330
331 template<Concepts::StructuredEntitySet Grid>
332 requires(!Concepts::StaticallySizedRange<Grid>)
333 3980 std::string extents_string(const Grid& grid) {
334
2/4
✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 76 times.
✗ Branch 5 not taken.
3980 return extents_string(extents(grid));
335 }
336
337 template<Concepts::StaticallySizedRange Spacing>
338 4354 auto structured_grid_axis_orientation(const Spacing& spacing) {
339 std::array<bool, static_size<Spacing>> result;
340
1/2
✓ Branch 1 taken 2226 times.
✗ Branch 2 not taken.
4354 std::ranges::copy(
341
2/4
✓ Branch 1 taken 2226 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2226 times.
✗ Branch 5 not taken.
10500 spacing | std::views::transform([&] <typename CT> (const CT dx) { return dx <= CT{0}; }),
342 result.begin()
343 );
344 4354 return result;
345 }
346
347 7634 std::size_t number_of_entities(const std::array<std::size_t, 6>& extents) {
348 7634 return std::max(extents[1] - extents[0], std::size_t{1})
349 7634 *std::max(extents[3] - extents[2], std::size_t{1})
350 7634 *std::max(extents[5] - extents[4], std::size_t{1});
351 }
352
353 3123 unsigned int structured_grid_dimension(const std::array<std::size_t, 3>& cells_per_direction) {
354 12492 return std::ranges::count_if(cells_per_direction, [] (const std::size_t e) { return e > 0; });
355 }
356
357 template<typename T>
358 24050 std::array<T, 3> compute_location(const std::array<T, 3>& origin,
359 const std::array<T, 3>& coordinate,
360 const std::array<T, 9>& direction) {
361 24050 const auto& [x, y, z] = coordinate;
362 return {
363 24050 origin[0] + x*direction[0] + y*direction[1] + z*direction[2],
364 24050 origin[1] + x*direction[3] + y*direction[4] + z*direction[5],
365 24050 origin[2] + x*direction[6] + y*direction[7] + z*direction[8]
366 72150 };
367 }
368
369 template<typename T>
370 282 std::array<T, 3> compute_piece_origin(const std::array<T, 3>& global_origin,
371 const std::array<T, 3>& spacing,
372 const std::array<std::size_t, 3>& extents_begin,
373 const std::array<T, 9>& direction) {
374 282 return compute_location(
375 global_origin,
376 {
377 282 spacing[0]*static_cast<T>(extents_begin[0]),
378 282 spacing[1]*static_cast<T>(extents_begin[1]),
379 282 spacing[2]*static_cast<T>(extents_begin[2])
380 },
381 direction
382 282 );
383 }
384
385 template<typename T>
386 282 Serialization serialize_structured_points(const std::array<std::size_t, 6>& extents,
387 const std::array<T, 3>& origin,
388 const std::array<T, 3>& spacing,
389 const std::array<T, 9>& direction) {
390 const MDLayout layout{{
391 282 extents[1] - extents[0],
392 282 extents[3] - extents[2],
393
1/2
✓ Branch 3 taken 282 times.
✗ Branch 4 not taken.
282 extents[5] - extents[4]
394 }};
395
1/2
✓ Branch 1 taken 282 times.
✗ Branch 2 not taken.
282 const FlatIndexMapper mapper{layout};
396
1/2
✓ Branch 4 taken 282 times.
✗ Branch 5 not taken.
282 const auto piece_origin = compute_piece_origin(
397 origin, spacing, {extents[0], extents[2], extents[4]}, direction
398 );
399
400 static constexpr unsigned int vtk_space_dim = 3;
401
2/4
✓ Branch 1 taken 282 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 282 times.
✗ Branch 5 not taken.
282 Serialization result(layout.number_of_entries()*sizeof(T)*vtk_space_dim);
402
1/2
✓ Branch 1 taken 282 times.
✗ Branch 2 not taken.
282 auto span_out = result.as_span_of(Precision<T>{});
403
8/14
✓ Branch 1 taken 282 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 282 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 282 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 282 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 23768 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 24050 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 23768 times.
✓ Branch 20 taken 282 times.
24050 for (const auto& md_index : MDIndexRange{layout}) {
404
1/2
✓ Branch 1 taken 23768 times.
✗ Branch 2 not taken.
23768 const auto offset = mapper.map(md_index)*vtk_space_dim;
405
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 23768 times.
23768 assert(offset + 2 < span_out.size());
406
1/2
✓ Branch 1 taken 23768 times.
✗ Branch 2 not taken.
23768 std::ranges::copy(
407
1/2
✓ Branch 1 taken 23768 times.
✗ Branch 2 not taken.
23768 compute_location(piece_origin, {
408 23768 static_cast<T>(md_index.get(0))*spacing[0],
409 23768 static_cast<T>(md_index.get(1))*spacing[1],
410 23768 static_cast<T>(md_index.get(2))*spacing[2]
411 }, direction),
412 23768 span_out.data() + offset
413 );
414 }
415 282 return result;
416 282 }
417
418 template<typename Visitor>
419 1039 void visit_structured_cells(const Visitor& visitor,
420 const std::array<std::size_t, 6>& extents,
421 const bool is_axis_aligned = true) {
422 3117 std::array<CellType, 4> grid_dim_to_cell_type{
423 CellType::vertex,
424 CellType::segment,
425
2/2
✓ Branch 0 taken 777 times.
✓ Branch 1 taken 262 times.
1039 (is_axis_aligned ? CellType::pixel : CellType::quadrilateral),
426
2/2
✓ Branch 0 taken 777 times.
✓ Branch 1 taken 262 times.
1039 (is_axis_aligned ? CellType::voxel : CellType::hexahedron)
427 };
428
429 3117 std::array<std::size_t, 3> counts{
430 1039 extents[1] - extents[0],
431 1039 extents[3] - extents[2],
432 1039 extents[5] - extents[4]
433 };
434
435
1/2
✓ Branch 1 taken 1039 times.
✗ Branch 2 not taken.
1039 const std::size_t grid_dim = structured_grid_dimension(counts);
436
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1039 times.
1039 if (grid_dim == 0)
437 throw ValueError("Grid must be at least 1d");
438
439
2/4
✓ Branch 1 taken 1039 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1039 times.
✗ Branch 5 not taken.
1039 const MDLayout point_layout{Ranges::incremented(counts, 1)};
440
1/2
✓ Branch 1 taken 1039 times.
✗ Branch 2 not taken.
1039 const FlatIndexMapper point_mapper{point_layout};
441
2/4
✓ Branch 0 taken 1039 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1039 times.
✗ Branch 4 not taken.
1039 const auto x_offset = grid_dim > 1 ? point_layout.extent(0) : std::size_t{0};
442
4/6
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 998 times.
✓ Branch 3 taken 41 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 41 times.
✗ Branch 7 not taken.
1039 const auto y_offset = grid_dim > 2 ? point_layout.extent(0)*point_layout.extent(1) : std::size_t{0};
443
444 // avoid zero counts s.t. the index range does not degenerate
445
1/2
✓ Branch 1 taken 1039 times.
✗ Branch 2 not taken.
4156 std::ranges::for_each(counts, [] (std::size_t& count) { count = std::max(count, std::size_t{1}); });
446
1/2
✓ Branch 2 taken 1039 times.
✗ Branch 3 not taken.
1039 std::vector<std::size_t> corners(std::pow(2, grid_dim), 0);
447
448
2/4
✓ Branch 1 taken 1039 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1039 times.
✗ Branch 5 not taken.
1039 const MDIndexRange index_range{MDLayout{counts}};
449
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1039 times.
1039 if (grid_dim == 1) {
450 std::ranges::for_each(index_range, [&] (const auto& md_index) {
451 const auto p0 = point_mapper.map(md_index);
452 corners = {p0, p0 + 1};
453 visitor(grid_dim_to_cell_type[grid_dim], corners);
454 });
455
2/2
✓ Branch 0 taken 998 times.
✓ Branch 1 taken 41 times.
1039 } else if (grid_dim == 2) {
456
1/2
✓ Branch 1 taken 998 times.
✗ Branch 2 not taken.
30985 std::ranges::for_each(index_range, [&] (const auto& md_index) {
457 29987 const auto p0 = point_mapper.map(md_index);
458
1/2
✓ Branch 1 taken 29987 times.
✗ Branch 2 not taken.
29987 corners = {p0, p0 + 1, p0 + x_offset, p0 + 1 + x_offset};
459 29987 visitor(grid_dim_to_cell_type[grid_dim], corners);
460 });
461 } else {
462
1/2
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
4961 std::ranges::for_each(index_range, [&] (const auto& md_index) {
463 4920 const auto p0 = point_mapper.map(md_index);
464 9840 corners = {
465 4920 p0, p0 + 1, p0 + x_offset, p0 + 1 + x_offset,
466
1/2
✓ Branch 1 taken 4920 times.
✗ Branch 2 not taken.
4920 p0 + y_offset, p0 + y_offset + 1, p0 + y_offset + x_offset, p0 + 1 + y_offset + x_offset
467 };
468 4920 visitor(grid_dim_to_cell_type[grid_dim], corners);
469 });
470 }
471 1039 }
472
473 } // namespace CommonDetail
474 #endif // DOXYGEN
475
476 //! \} group VTK
477 } // namespace GridFormat::VTK
478
479
480 #endif // GRIDFORMAT_VTK_COMMON_HPP_
481