GCC Code Coverage Report


Directory: gridformat/
File: gridformat/grid/writer.hpp
Date: 2024-11-10 16:24:00
Exec Total Coverage
Lines: 158 162 97.5%
Functions: 2641 2725 96.9%
Branches: 267 609 43.8%

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 Grid
6 * \brief Base classes for grid data writers.
7 */
8 #ifndef GRIDFORMAT_GRID_WRITER_HPP_
9 #define GRIDFORMAT_GRID_WRITER_HPP_
10
11 #include <string>
12 #include <utility>
13 #include <ranges>
14 #include <fstream>
15 #include <ostream>
16 #include <concepts>
17 #include <type_traits>
18
19 #include <gridformat/parallel/communication.hpp>
20 #include <gridformat/common/type_traits.hpp>
21 #include <gridformat/common/precision.hpp>
22 #include <gridformat/common/concepts.hpp>
23 #include <gridformat/common/field_storage.hpp>
24 #include <gridformat/common/range_field.hpp>
25 #include <gridformat/common/scalar_field.hpp>
26 #include <gridformat/common/logging.hpp>
27
28 #include <gridformat/grid/grid.hpp>
29 #include <gridformat/grid/_detail.hpp>
30 #include <gridformat/grid/entity_fields.hpp>
31
32 namespace GridFormat {
33 namespace Traits {
34
35 //! Can be specialized by writers in case the file format does not contain connectivity information
36 template<typename Writer> struct WritesConnectivity : public std::true_type {};
37
38 //! Can be specialized by parallel writers to expose their underlying communicator
39 template<typename Writer>
40 struct CommunicatorAccess {
41 210 static constexpr auto get(const Writer&) { return NullCommunicator{}; }
42 };
43
44 //! Default specialization for writers that have a communicator() function
45 template<typename Writer>
46 requires( requires(const Writer& w) { { w.communicator() }; } )
47 struct CommunicatorAccess<Writer> {
48 474 static constexpr Concepts::Communicator decltype(auto) get(const Writer& w) {
49 474 return w.communicator();
50 }
51 };
52
53 } // namespace Traits
54
55 //! \addtogroup Grid
56 //! \{
57
58 //! Options that writer implementations can pass to the base class.
59 struct WriterOptions {
60 bool use_structured_grid_ordering; //!< Use row-major structured grid ordering
61 bool append_null_terminator_to_strings; //!< If true, '\0' is appended to string meta data
62
63 34861 bool operator==(const WriterOptions& other) const {
64 34861 return use_structured_grid_ordering == other.use_structured_grid_ordering
65
2/4
✓ Branch 0 taken 34861 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34861 times.
✗ Branch 3 not taken.
34861 && append_null_terminator_to_strings == other.append_null_terminator_to_strings;
66 }
67 };
68
69 //! Base class for all writer implementations.
70 template<typename G>
71 class GridWriterBase {
72 public:
73 using Grid = G;
74 using Field = typename FieldStorage::Field;
75 using FieldPtr = typename FieldStorage::FieldPtr;
76
77 83448 explicit GridWriterBase(const Grid& grid, std::optional<WriterOptions> opts)
78 83448 : _grid(grid)
79 83448 , _opts{std::move(opts)}
80 83448 {}
81
82 template<std::ranges::range R>
83 13665 void set_meta_data(const std::string& name, R&& range) {
84
1/2
✓ Branch 3 taken 6939 times.
✗ Branch 4 not taken.
13665 _meta_data.set(name, RangeField{std::forward<R>(range)});
85 13665 }
86
87 13665 void set_meta_data(const std::string& name, std::string text) {
88
3/6
✓ Branch 1 taken 6939 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6939 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6939 times.
✗ Branch 7 not taken.
13665 if (_opts && _opts.value().append_null_terminator_to_strings)
89 13665 text.push_back('\0');
90
1/2
✓ Branch 3 taken 6939 times.
✗ Branch 4 not taken.
13665 _meta_data.set(name, RangeField{std::move(text)});
91 13665 }
92
93 template<Concepts::Scalar T>
94 47 void set_meta_data(const std::string& name, T value) {
95
1/2
✓ Branch 2 taken 47 times.
✗ Branch 3 not taken.
47 _meta_data.set(name, ScalarField{value});
96 47 }
97
98 template<std::derived_from<Field> F>
99 13665 void set_meta_data(const std::string& name, F&& field) {
100 static_assert(!std::is_lvalue_reference_v<F>, "Cannot take metadata fields by reference, please move");
101
2/4
✓ Branch 2 taken 6939 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 6939 times.
✗ Branch 6 not taken.
13665 set_meta_data(name, make_field_ptr(std::move(field)));
102 13665 }
103
104 50049 void set_meta_data(const std::string& name, FieldPtr ptr) {
105
1/2
✓ Branch 2 taken 25757 times.
✗ Branch 3 not taken.
50049 _meta_data.set(name, ptr);
106 50049 }
107
108 3 FieldPtr remove_meta_data(const std::string& name) {
109 3 return _meta_data.pop(name);
110 }
111
112 template<Concepts::PointFunction<Grid> F, Concepts::Scalar T = GridDetail::PointFunctionScalarType<Grid, F>>
113 81749 void set_point_field(const std::string& name, F&& point_function, const Precision<T>& prec = {}) {
114 static_assert(!std::is_lvalue_reference_v<F>, "Cannot take functions by reference, please move");
115
2/4
✓ Branch 2 taken 40950 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 40950 times.
✗ Branch 6 not taken.
81749 set_point_field(name, _make_point_field(std::move(point_function), prec));
116 81749 }
117
118 template<std::derived_from<Field> F>
119 81921 void set_point_field(const std::string& name, F&& field) {
120 static_assert(!std::is_lvalue_reference_v<F>, "Cannot take fields by reference, please move");
121
2/4
✓ Branch 2 taken 41036 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 41036 times.
✗ Branch 6 not taken.
81921 set_point_field(name, make_field_ptr(std::forward<F>(field)));
122 81921 }
123
124 153671 void set_point_field(const std::string& name, FieldPtr field_ptr) {
125
1/2
✓ Branch 3 taken 78208 times.
✗ Branch 4 not taken.
153671 _point_fields.set(name, std::move(field_ptr));
126 153671 }
127
128 3 FieldPtr remove_point_field(const std::string& name) {
129 3 return _point_fields.pop(name);
130 }
131
132 template<Concepts::CellFunction<Grid> F, Concepts::Scalar T = GridDetail::CellFunctionScalarType<Grid, F>>
133 80596 void set_cell_field(const std::string& name, F&& cell_function, const Precision<T>& prec = {}) {
134 static_assert(!std::is_lvalue_reference_v<F>, "Cannot take functions by reference, please move");
135
2/4
✓ Branch 2 taken 40381 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 40381 times.
✗ Branch 6 not taken.
80596 set_cell_field(name, _make_cell_field(std::move(cell_function), prec));
136 80596 }
137
138 template<std::derived_from<Field> F>
139 80768 void set_cell_field(const std::string& name, F&& field) {
140 static_assert(!std::is_lvalue_reference_v<F>, "Cannot take fields by reference, please move");
141
2/4
✓ Branch 2 taken 40467 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 40467 times.
✗ Branch 6 not taken.
80768 set_cell_field(name, make_field_ptr(std::forward<F>(field)));
142 80768 }
143
144 152285 void set_cell_field(const std::string& name, FieldPtr field_ptr) {
145
1/2
✓ Branch 2 taken 77515 times.
✗ Branch 3 not taken.
152285 _cell_fields.set(name, field_ptr);
146 152285 }
147
148 3 FieldPtr remove_cell_field(const std::string& name) {
149 3 return _cell_fields.pop(name);
150 }
151
152 930 void clear() {
153 930 _meta_data.clear();
154 930 _point_fields.clear();
155 930 _cell_fields.clear();
156 930 }
157
158 void set_ignore_warnings(bool value) {
159 _ignore_warnings = value;
160 }
161
162 887545 const Grid& grid() const {
163 887545 return _grid;
164 }
165
166 207186 const std::optional<WriterOptions>& writer_options() const {
167 207186 return _opts;
168 }
169
170 template<typename Writer>
171 69633 void copy_fields(Writer& w) const {
172
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 34861 times.
69633 if (_opts.has_value() != w.writer_options().has_value())
173 throw TypeError("Cannot copy fields into writers with different options");
174
3/6
✓ Branch 1 taken 34861 times.
✗ Branch 2 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 34861 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 34861 times.
69633 if (_opts.has_value() && writer_options().value() != w.writer_options().value())
175 throw TypeError("Cannot copy fields into writers with different options");
176
177
12/16
✓ Branch 1 taken 34861 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 34861 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 34861 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 18407 times.
✗ Branch 11 not taken.
✓ Branch 15 taken 17876 times.
✓ Branch 16 taken 531 times.
✓ Branch 17 taken 180 times.
✓ Branch 18 taken 52553 times.
✓ Branch 19 taken 16 times.
✓ Branch 20 taken 17876 times.
✓ Branch 21 taken 34689 times.
✓ Branch 22 taken 4 times.
141959 for (const auto& [name, field_ptr] : meta_data_fields(*this))
178
2/3
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 18395 times.
✗ Branch 3 not taken.
36682 w.set_meta_data(name, field_ptr);
179
12/16
✓ Branch 1 taken 34861 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 34861 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 34861 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 36134 times.
✗ Branch 11 not taken.
✓ Branch 15 taken 35330 times.
✓ Branch 16 taken 804 times.
✓ Branch 17 taken 177 times.
✓ Branch 18 taken 70010 times.
✓ Branch 19 taken 8 times.
✓ Branch 20 taken 35330 times.
✓ Branch 21 taken 34684 times.
✓ Branch 22 taken 4 times.
212101 for (const auto& [name, field_ptr] : point_fields(*this))
180
2/3
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 36130 times.
✗ Branch 3 not taken.
72034 w.set_point_field(name, field_ptr);
181
12/16
✓ Branch 1 taken 34861 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 34861 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 34861 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 36091 times.
✗ Branch 11 not taken.
✓ Branch 15 taken 35287 times.
✓ Branch 16 taken 804 times.
✓ Branch 17 taken 177 times.
✓ Branch 18 taken 69967 times.
✓ Branch 19 taken 8 times.
✓ Branch 20 taken 35287 times.
✓ Branch 21 taken 34684 times.
✓ Branch 22 taken 4 times.
211989 for (const auto& [name, field_ptr] : cell_fields(*this))
182
2/3
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 36087 times.
✗ Branch 3 not taken.
71978 w.set_cell_field(name, field_ptr);
183 69633 }
184
185 //! Return a range over the fields with the given rank (0=scalars, 1=vectors, 2=tensors)
186 friend Concepts::RangeOf<std::pair<std::string, FieldPtr>> auto
187 113649 point_fields_of_rank(unsigned int rank, const GridWriterBase& writer) {
188
1/2
✓ Branch 1 taken 57993 times.
✗ Branch 2 not taken.
113649 return writer._point_field_names()
189
2/4
✓ Branch 1 taken 57993 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57993 times.
✗ Branch 5 not taken.
435836 | std::views::filter([&, r=rank] (const std::string& n) {
190
72/144
✓ Branch 1 taken 53188 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 53188 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 53188 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 155738 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 155738 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 155738 times.
✗ Branch 19 not taken.
✓ Branch 23 taken 1158 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 1158 times.
✗ Branch 27 not taken.
✓ Branch 29 taken 1158 times.
✗ Branch 30 not taken.
✓ Branch 34 taken 1134 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 1134 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 1134 times.
✗ Branch 41 not taken.
✓ Branch 45 taken 810 times.
✗ Branch 46 not taken.
✓ Branch 48 taken 810 times.
✗ Branch 49 not taken.
✓ Branch 51 taken 810 times.
✗ Branch 52 not taken.
✓ Branch 56 taken 810 times.
✗ Branch 57 not taken.
✓ Branch 59 taken 810 times.
✗ Branch 60 not taken.
✓ Branch 62 taken 810 times.
✗ Branch 63 not taken.
✓ Branch 67 taken 804 times.
✗ Branch 68 not taken.
✓ Branch 70 taken 804 times.
✗ Branch 71 not taken.
✓ Branch 73 taken 804 times.
✗ Branch 74 not taken.
✓ Branch 78 taken 804 times.
✗ Branch 79 not taken.
✓ Branch 81 taken 804 times.
✗ Branch 82 not taken.
✓ Branch 84 taken 804 times.
✗ Branch 85 not taken.
✓ Branch 89 taken 372 times.
✗ Branch 90 not taken.
✓ Branch 92 taken 372 times.
✗ Branch 93 not taken.
✓ Branch 95 taken 372 times.
✗ Branch 96 not taken.
✓ Branch 100 taken 372 times.
✗ Branch 101 not taken.
✓ Branch 103 taken 372 times.
✗ Branch 104 not taken.
✓ Branch 106 taken 372 times.
✗ Branch 107 not taken.
✓ Branch 111 taken 372 times.
✗ Branch 112 not taken.
✓ Branch 114 taken 372 times.
✗ Branch 115 not taken.
✓ Branch 117 taken 372 times.
✗ Branch 118 not taken.
✓ Branch 122 taken 12 times.
✗ Branch 123 not taken.
✓ Branch 125 taken 12 times.
✗ Branch 126 not taken.
✓ Branch 128 taken 12 times.
✗ Branch 129 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 144 taken 12 times.
✗ Branch 145 not taken.
✓ Branch 147 taken 12 times.
✗ Branch 148 not taken.
✓ Branch 150 taken 12 times.
✗ Branch 151 not taken.
✓ Branch 155 taken 12 times.
✗ Branch 156 not taken.
✓ Branch 158 taken 12 times.
✗ Branch 159 not taken.
✓ Branch 161 taken 12 times.
✗ Branch 162 not taken.
✓ Branch 166 taken 12 times.
✗ Branch 167 not taken.
✓ Branch 169 taken 12 times.
✗ Branch 170 not taken.
✓ Branch 172 taken 12 times.
✗ Branch 173 not taken.
✓ Branch 177 taken 12 times.
✗ Branch 178 not taken.
✓ Branch 180 taken 12 times.
✗ Branch 181 not taken.
✓ Branch 183 taken 12 times.
✗ Branch 184 not taken.
✓ Branch 188 taken 12 times.
✗ Branch 189 not taken.
✓ Branch 191 taken 12 times.
✗ Branch 192 not taken.
✓ Branch 194 taken 12 times.
✗ Branch 195 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 210 taken 12 times.
✗ Branch 211 not taken.
✓ Branch 213 taken 12 times.
✗ Branch 214 not taken.
✓ Branch 216 taken 12 times.
✗ Branch 217 not taken.
✓ Branch 221 taken 12 times.
✗ Branch 222 not taken.
✓ Branch 224 taken 12 times.
✗ Branch 225 not taken.
✓ Branch 227 taken 12 times.
✗ Branch 228 not taken.
✓ Branch 232 taken 12 times.
✗ Branch 233 not taken.
✓ Branch 235 taken 12 times.
✗ Branch 236 not taken.
✓ Branch 238 taken 12 times.
✗ Branch 239 not taken.
✓ Branch 243 taken 12 times.
✗ Branch 244 not taken.
✓ Branch 246 taken 12 times.
✗ Branch 247 not taken.
✓ Branch 249 taken 12 times.
✗ Branch 250 not taken.
✓ Branch 254 taken 12 times.
✗ Branch 255 not taken.
✓ Branch 257 taken 12 times.
✗ Branch 258 not taken.
✓ Branch 260 taken 12 times.
✗ Branch 261 not taken.
215718 return writer._get_point_field(n).layout().dimension() - 1 == r;
191 })
192
1/2
✓ Branch 1 taken 57993 times.
✗ Branch 2 not taken.
382738 | std::views::transform([&] (std::string n) {
193
24/48
✓ Branch 1 taken 39490 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 116158 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 862 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 844 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 594 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 594 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 590 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 590 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 278 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 278 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 278 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 8 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 8 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 8 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 8 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 8 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 8 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 8 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 8 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 8 times.
✗ Branch 59 not taken.
✓ Branch 61 taken 8 times.
✗ Branch 62 not taken.
✓ Branch 64 taken 8 times.
✗ Branch 65 not taken.
✓ Branch 67 taken 8 times.
✗ Branch 68 not taken.
✓ Branch 70 taken 8 times.
✗ Branch 71 not taken.
160660 auto field_ptr = writer._get_point_field_ptr(n);
194 321320 return std::make_pair(std::move(n), std::move(field_ptr));
195
1/2
✓ Branch 1 taken 57993 times.
✗ Branch 2 not taken.
387958 });
196 }
197
198 //! Return a range over the fields with the given rank (0=scalars, 1=vectors, 2=tensors)
199 friend Concepts::RangeOf<std::pair<std::string, FieldPtr>> auto
200 113649 cell_fields_of_rank(unsigned int rank, const GridWriterBase& writer) {
201
1/2
✓ Branch 1 taken 57993 times.
✗ Branch 2 not taken.
113649 return writer._cell_field_names()
202
2/4
✓ Branch 1 taken 57993 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57993 times.
✗ Branch 5 not taken.
435424 | std::views::filter([&, r=rank] (const std::string& n) {
203
45/144
✓ Branch 1 taken 52902 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 52902 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 52902 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 155578 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 155578 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 155578 times.
✗ Branch 19 not taken.
✓ Branch 23 taken 1140 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 1140 times.
✗ Branch 27 not taken.
✓ Branch 29 taken 1140 times.
✗ Branch 30 not taken.
✓ Branch 34 taken 1122 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 1122 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 1122 times.
✗ Branch 41 not taken.
✓ Branch 45 taken 804 times.
✗ Branch 46 not taken.
✓ Branch 48 taken 804 times.
✗ Branch 49 not taken.
✓ Branch 51 taken 804 times.
✗ Branch 52 not taken.
✓ Branch 56 taken 804 times.
✗ Branch 57 not taken.
✓ Branch 59 taken 804 times.
✗ Branch 60 not taken.
✓ Branch 62 taken 804 times.
✗ Branch 63 not taken.
✓ Branch 67 taken 816 times.
✗ Branch 68 not taken.
✓ Branch 70 taken 816 times.
✗ Branch 71 not taken.
✓ Branch 73 taken 816 times.
✗ Branch 74 not taken.
✓ Branch 78 taken 804 times.
✗ Branch 79 not taken.
✓ Branch 81 taken 804 times.
✗ Branch 82 not taken.
✓ Branch 84 taken 804 times.
✗ Branch 85 not taken.
✓ Branch 89 taken 360 times.
✗ Branch 90 not taken.
✓ Branch 92 taken 360 times.
✗ Branch 93 not taken.
✓ Branch 95 taken 360 times.
✗ Branch 96 not taken.
✓ Branch 100 taken 372 times.
✗ Branch 101 not taken.
✓ Branch 103 taken 372 times.
✗ Branch 104 not taken.
✓ Branch 106 taken 372 times.
✗ Branch 107 not taken.
✓ Branch 111 taken 360 times.
✗ Branch 112 not taken.
✓ Branch 114 taken 360 times.
✗ Branch 115 not taken.
✓ Branch 117 taken 360 times.
✗ Branch 118 not taken.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✗ Branch 125 not taken.
✗ Branch 126 not taken.
✗ Branch 128 not taken.
✗ Branch 129 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 144 not taken.
✗ Branch 145 not taken.
✗ Branch 147 not taken.
✗ Branch 148 not taken.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✗ Branch 155 not taken.
✗ Branch 156 not taken.
✗ Branch 158 not taken.
✗ Branch 159 not taken.
✗ Branch 161 not taken.
✗ Branch 162 not taken.
✓ Branch 166 taken 12 times.
✗ Branch 167 not taken.
✓ Branch 169 taken 12 times.
✗ Branch 170 not taken.
✓ Branch 172 taken 12 times.
✗ Branch 173 not taken.
✗ Branch 177 not taken.
✗ Branch 178 not taken.
✗ Branch 180 not taken.
✗ Branch 181 not taken.
✗ Branch 183 not taken.
✗ Branch 184 not taken.
✗ Branch 188 not taken.
✗ Branch 189 not taken.
✗ Branch 191 not taken.
✗ Branch 192 not taken.
✗ Branch 194 not taken.
✗ Branch 195 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 210 not taken.
✗ Branch 211 not taken.
✗ Branch 213 not taken.
✗ Branch 214 not taken.
✗ Branch 216 not taken.
✗ Branch 217 not taken.
✗ Branch 221 not taken.
✗ Branch 222 not taken.
✗ Branch 224 not taken.
✗ Branch 225 not taken.
✗ Branch 227 not taken.
✗ Branch 228 not taken.
✓ Branch 232 taken 12 times.
✗ Branch 233 not taken.
✓ Branch 235 taken 12 times.
✗ Branch 236 not taken.
✓ Branch 238 taken 12 times.
✗ Branch 239 not taken.
✗ Branch 243 not taken.
✗ Branch 244 not taken.
✗ Branch 246 not taken.
✗ Branch 247 not taken.
✗ Branch 249 not taken.
✗ Branch 250 not taken.
✗ Branch 254 not taken.
✗ Branch 255 not taken.
✗ Branch 257 not taken.
✗ Branch 258 not taken.
✗ Branch 260 not taken.
✗ Branch 261 not taken.
215110 return writer._get_cell_field(n).layout().dimension() - 1 == r;
204 })
205
1/2
✓ Branch 1 taken 57993 times.
✗ Branch 2 not taken.
382462 | std::views::transform([&] (std::string n) {
206
15/48
✓ Branch 1 taken 39318 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 116080 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 850 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 838 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 582 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 582 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 590 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 582 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 270 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 278 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 270 times.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✓ Branch 37 taken 8 times.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✓ Branch 46 taken 8 times.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✓ Branch 55 taken 8 times.
✗ Branch 56 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✓ Branch 64 taken 8 times.
✗ Branch 65 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
160272 auto field_ptr = writer._get_cell_field_ptr(n);
207 320544 return std::make_pair(std::move(n), std::move(field_ptr));
208
1/2
✓ Branch 1 taken 57993 times.
✗ Branch 2 not taken.
387570 });
209 }
210
211 69286 friend Concepts::RangeOf<std::pair<std::string, FieldPtr>> auto point_fields(const GridWriterBase& writer) {
212
3/6
✓ Branch 1 taken 35033 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 35033 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 35033 times.
✗ Branch 8 not taken.
173533 return writer._point_field_names() | std::views::transform([&] (std::string n) {
213
4/18
✓ Branch 1 taken 29037 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8073 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
37116 auto field_ptr = writer._get_point_field_ptr(n);
214 74232 return std::make_pair(std::move(n), std::move(field_ptr));
215 175688 });
216 }
217
218 69280 friend Concepts::RangeOf<std::pair<std::string, FieldPtr>> auto cell_fields(const GridWriterBase& writer) {
219
3/6
✓ Branch 1 taken 35030 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 35030 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 35030 times.
✗ Branch 8 not taken.
173526 return writer._cell_field_names() | std::views::transform([&] (std::string n) {
220
4/18
✓ Branch 1 taken 28987 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8086 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
37079 auto field_ptr = writer._get_cell_field_ptr(n);
221 74158 return std::make_pair(std::move(n), std::move(field_ptr));
222 175639 });
223 }
224
225 69274 friend Concepts::RangeOf<std::pair<std::string, FieldPtr>> auto meta_data_fields(const GridWriterBase& writer) {
226
3/6
✓ Branch 1 taken 35027 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 35027 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 35027 times.
✗ Branch 8 not taken.
156058 return writer._meta_data_field_names() | std::views::transform([&] (std::string n) {
227
4/18
✓ Branch 1 taken 14767 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4106 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
18891 auto field_ptr = writer._get_meta_data_field_ptr(n);
228 37782 return std::make_pair(std::move(n), std::move(field_ptr));
229 157439 });
230 }
231
232 protected:
233 4 void _log_warning(std::string_view warning) const {
234
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
4 if (!_ignore_warnings)
235
1/2
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
4 log_warning(
236
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
8 std::string{warning}
237
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
12 + (warning.ends_with("\n") ? "" : "\n")
238
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
12 + "To deactivate this warning, call set_ignore_warnings(true);"
239 );
240 4 }
241
242 template<typename EntityFunction, Concepts::Scalar T>
243 81749 auto _make_point_field(EntityFunction&& f, const Precision<T>& prec) const {
244
1/2
✓ Branch 1 taken 40950 times.
✗ Branch 2 not taken.
81749 if (_opts.has_value())
245 81749 return PointField{_grid, std::move(f), _opts.value().use_structured_grid_ordering, prec};
246 return PointField{_grid, std::move(f), false, prec};
247 }
248
249 template<typename EntityFunction, Concepts::Scalar T>
250 80596 auto _make_cell_field(EntityFunction&& f, const Precision<T>& prec) const {
251
1/2
✓ Branch 1 taken 40381 times.
✗ Branch 2 not taken.
80596 if (_opts.has_value())
252 80596 return CellField{_grid, std::move(f), _opts.value().use_structured_grid_ordering, prec};
253 return CellField{_grid, std::move(f), false, prec};
254 }
255
256 203670 std::ranges::range auto _point_field_names() const {
257 203670 return _point_fields.field_names();
258 }
259
260 204055 std::ranges::range auto _cell_field_names() const {
261 204055 return _cell_fields.field_names();
262 }
263
264 447302 const Field& _get_point_field(const std::string& name) const {
265 447302 return _point_fields.get(name);
266 }
267
268 473477 FieldPtr _get_point_field_ptr(const std::string& name) const {
269 473477 return _point_fields.get_ptr(name);
270 }
271
272 446270 const Field& _get_cell_field(const std::string& name) const {
273 446270 return _cell_fields.get(name);
274 }
275
276 471333 FieldPtr _get_cell_field_ptr(const std::string& name) const {
277 471333 return _cell_fields.get_ptr(name);
278 }
279
280 85826 std::ranges::range auto _meta_data_field_names() const {
281 85826 return _meta_data.field_names();
282 }
283
284 42101 const Field& _get_meta_data_field(const std::string& name) const {
285 42101 return _meta_data.get(name);
286 }
287
288 36929 FieldPtr _get_meta_data_field_ptr(const std::string& name) const {
289 36929 return _meta_data.get_ptr(name);
290 }
291
292 private:
293 const Grid& _grid;
294 FieldStorage _point_fields;
295 FieldStorage _cell_fields;
296 FieldStorage _meta_data;
297 std::optional<WriterOptions> _opts;
298 bool _ignore_warnings = false;
299 };
300
301 //! Abstract base class for grid file writers.
302 template<typename Grid>
303 class GridWriter : public GridWriterBase<Grid> {
304 public:
305 84248 virtual ~GridWriter() = default;
306
307 222 GridWriter(GridWriter&&) = default;
308 GridWriter(const GridWriter&) = delete;
309 GridWriter& operator=(GridWriter&&) = default;
310 GridWriter& operator=(const GridWriter&) = delete;
311
312 83253 explicit GridWriter(const Grid& grid, std::string extension, std::optional<WriterOptions> opts)
313 83253 : GridWriterBase<Grid>(grid, std::move(opts))
314 83253 , _extension(std::move(extension))
315 83253 {}
316
317 29239 std::string write(const std::string& filename) const {
318 29239 std::string filename_with_ext = filename + _extension;
319
2/2
✓ Branch 1 taken 13804 times.
✓ Branch 2 taken 1082 times.
29239 _write(filename_with_ext);
320 27091 return filename_with_ext;
321 2148 }
322
323 void write(std::ostream& s) const {
324 _write(s);
325 }
326
327 23 const std::string& extension() const {
328 23 return _extension;
329 }
330
331 private:
332 std::string _extension;
333
334 15987 virtual void _write(const std::string& filename_with_ext) const {
335
1/2
✓ Branch 1 taken 8139 times.
✗ Branch 2 not taken.
15987 std::ofstream result_file(filename_with_ext, std::ios::out);
336
2/2
✓ Branch 1 taken 7545 times.
✓ Branch 2 taken 594 times.
15987 _write(result_file);
337 15987 }
338
339 virtual void _write(std::ostream&) const = 0;
340 };
341
342 //! Abstract base class for time series file writers.
343 template<typename Grid>
344 class TimeSeriesGridWriter : public GridWriterBase<Grid> {
345 public:
346 350 virtual ~TimeSeriesGridWriter() = default;
347
348 41 TimeSeriesGridWriter(TimeSeriesGridWriter&&) = default;
349 TimeSeriesGridWriter(const TimeSeriesGridWriter&) = delete;
350 TimeSeriesGridWriter& operator=(TimeSeriesGridWriter&&) = default;
351 TimeSeriesGridWriter& operator=(const TimeSeriesGridWriter&) = delete;
352
353 193 explicit TimeSeriesGridWriter(const Grid& grid, std::optional<WriterOptions> opts)
354 193 : GridWriterBase<Grid>(grid, std::move(opts))
355 193 {}
356
357 606 std::string write(double t) {
358 606 std::string filename = _write(t);
359 606 _step_count++;
360 606 return filename;
361 }
362
363 protected:
364 unsigned _step_count = 0;
365
366 private:
367 virtual std::string _write(double) = 0;
368 };
369
370 #ifndef DOXYGEN
371 namespace GridDetail {
372
373 template<bool is_transient, typename G>
374 struct WriterBase;
375 template<typename G>
376 struct WriterBase<true, G> : std::type_identity<TimeSeriesGridWriter<G>> {};
377 template<typename G>
378 struct WriterBase<false, G> : std::type_identity<GridWriter<G>> {};
379
380 } // namespace GridDetail
381 #endif // DOXYGEN
382
383 //! \} group Grid
384
385 } // namespace GridFormat
386
387 #endif // GRIDFORMAT_GRID_WRITER_HPP_
388