| 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 Writer for the VTK HDF file format for image grids. | ||
| 7 | */ | ||
| 8 | #ifndef GRIDFORMAT_VTK_HDF_IMAGE_GRID_WRITER_HPP_ | ||
| 9 | #define GRIDFORMAT_VTK_HDF_IMAGE_GRID_WRITER_HPP_ | ||
| 10 | #if GRIDFORMAT_HAVE_HIGH_FIVE | ||
| 11 | |||
| 12 | #include <ranges> | ||
| 13 | #include <iterator> | ||
| 14 | #include <algorithm> | ||
| 15 | #include <utility> | ||
| 16 | #include <tuple> | ||
| 17 | |||
| 18 | #include <gridformat/common/exceptions.hpp> | ||
| 19 | #include <gridformat/common/md_layout.hpp> | ||
| 20 | #include <gridformat/common/concepts.hpp> | ||
| 21 | #include <gridformat/common/matrix.hpp> | ||
| 22 | #include <gridformat/common/ranges.hpp> | ||
| 23 | #include <gridformat/common/type_traits.hpp> | ||
| 24 | #include <gridformat/common/lvalue_reference.hpp> | ||
| 25 | #include <gridformat/common/field_transformations.hpp> | ||
| 26 | |||
| 27 | #include <gridformat/parallel/communication.hpp> | ||
| 28 | #include <gridformat/parallel/concepts.hpp> | ||
| 29 | |||
| 30 | #include <gridformat/grid/concepts.hpp> | ||
| 31 | #include <gridformat/grid/writer.hpp> | ||
| 32 | |||
| 33 | #include <gridformat/vtk/common.hpp> | ||
| 34 | #include <gridformat/vtk/parallel.hpp> | ||
| 35 | #include <gridformat/vtk/hdf_common.hpp> | ||
| 36 | |||
| 37 | namespace GridFormat { | ||
| 38 | |||
| 39 | template<bool is_transient, Concepts::ImageGrid Grid, Concepts::Communicator Communicator = NullCommunicator> | ||
| 40 | class VTKHDFImageGridWriterImpl : public GridDetail::WriterBase<is_transient, Grid>::type { | ||
| 41 | static constexpr int root_rank = 0; | ||
| 42 | static constexpr std::size_t dim = dimension<Grid>; | ||
| 43 | static constexpr std::size_t vtk_space_dim = 3; | ||
| 44 | static constexpr std::array<std::size_t, 2> version{1, 0}; | ||
| 45 | |||
| 46 | using CT = CoordinateType<Grid>; | ||
| 47 | using IOContext = VTKHDF::IOContext; | ||
| 48 | using HDF5File = HDF5::File<Communicator>; | ||
| 49 | |||
| 50 | struct ImageSpecs { | ||
| 51 | const std::array<CT, dim> origin; | ||
| 52 | const std::array<CT, dim> spacing; | ||
| 53 | const std::array<std::size_t, dim> extents; | ||
| 54 | |||
| 55 | template<typename O, typename S, typename E> | ||
| 56 | 526 | ImageSpecs(O&& origin, S&& spacing, E&& extents) | |
| 57 | 526 | : origin{Ranges::to_array<dim, CT>(std::forward<O>(origin))} | |
| 58 | 526 | , spacing{Ranges::to_array<dim, CT>(std::forward<S>(spacing))} | |
| 59 | 526 | , extents{Ranges::to_array<dim, std::size_t>(std::forward<E>(extents))} | |
| 60 | 526 | {} | |
| 61 | }; | ||
| 62 | |||
| 63 | static constexpr WriterOptions writer_opts{ | ||
| 64 | .use_structured_grid_ordering = true, | ||
| 65 | .append_null_terminator_to_strings = true | ||
| 66 | }; | ||
| 67 | |||
| 68 | public: | ||
| 69 | 23 | explicit VTKHDFImageGridWriterImpl(LValueReferenceOf<const Grid> grid) | |
| 70 | requires(std::is_same_v<Communicator, NullCommunicator>) | ||
| 71 |
3/6✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
|
115 | : GridWriter<Grid>(grid.get(), ".hdf", writer_opts) |
| 72 | 23 | {} | |
| 73 | |||
| 74 | 149 | explicit VTKHDFImageGridWriterImpl(LValueReferenceOf<const Grid> grid, const Communicator& comm) | |
| 75 | requires(std::is_copy_constructible_v<Communicator>) | ||
| 76 | : GridWriter<Grid>(grid.get(), ".hdf", writer_opts) | ||
| 77 |
3/6✓ Branch 2 taken 77 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 77 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 77 times.
✗ Branch 11 not taken.
|
745 | , _comm{comm} |
| 78 | 149 | {} | |
| 79 | |||
| 80 | 6 | explicit VTKHDFImageGridWriterImpl(LValueReferenceOf<const Grid> grid, | |
| 81 | std::string filename_without_extension, | ||
| 82 | VTK::HDFTransientOptions opts = { | ||
| 83 | .static_grid = true, | ||
| 84 | .static_meta_data = false | ||
| 85 | }) | ||
| 86 | requires(is_transient && std::is_same_v<Communicator, NullCommunicator>) | ||
| 87 |
2/4✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
|
6 | : VTKHDFImageGridWriterImpl(grid.get(), NullCommunicator{}, filename_without_extension, std::move(opts)) |
| 88 | 6 | {} | |
| 89 | |||
| 90 | 15 | explicit VTKHDFImageGridWriterImpl(LValueReferenceOf<const Grid> grid, | |
| 91 | const Communicator& comm, | ||
| 92 | std::string filename_without_extension, | ||
| 93 | VTK::HDFTransientOptions opts = { | ||
| 94 | .static_grid = true, | ||
| 95 | .static_meta_data = false | ||
| 96 | }) | ||
| 97 | requires(is_transient && std::is_copy_constructible_v<Communicator>) | ||
| 98 | : TimeSeriesGridWriter<Grid>(grid.get(), writer_opts) | ||
| 99 | 8 | , _comm{comm} | |
| 100 |
1/2✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
|
15 | , _timeseries_filename{std::move(filename_without_extension) + ".hdf"} |
| 101 |
1/2✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
|
30 | , _transient_opts{std::move(opts)} { |
| 102 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
|
15 | if (!_transient_opts.static_grid) |
| 103 | ✗ | throw ValueError("Transient VTK-HDF ImageData files do not support evolving grids"); | |
| 104 | 15 | } | |
| 105 | |||
| 106 | const Communicator& communicator() const { | ||
| 107 | return _comm; | ||
| 108 | } | ||
| 109 | |||
| 110 | private: | ||
| 111 | ✗ | void _write(std::ostream&) const { | |
| 112 | ✗ | throw InvalidState("VTKHDFImageGridWriter does not support export into stream"); | |
| 113 | } | ||
| 114 | |||
| 115 | 63 | std::string _write([[maybe_unused]] double t) { | |
| 116 | if constexpr (!is_transient) | ||
| 117 | throw InvalidState("This overload only works for transient output"); | ||
| 118 | |||
| 119 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 48 times.
|
63 | if (this->_step_count == 0) |
| 120 |
1/2✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
|
15 | HDF5File::clear(_timeseries_filename, _comm); |
| 121 | |||
| 122 |
1/2✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
|
63 | HDF5File file{_timeseries_filename, _comm, HDF5File::Mode::append}; |
| 123 |
1/2✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
|
63 | _write_to(file); |
| 124 |
2/4✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 63 times.
✗ Branch 5 not taken.
|
63 | file.write_attribute(this->_step_count+1, "/VTKHDF/Steps/NSteps"); |
| 125 |
2/4✓ Branch 2 taken 63 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 63 times.
✗ Branch 6 not taken.
|
189 | file.write(std::array{t}, "/VTKHDF/Steps/Values"); |
| 126 |
1/2✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
|
126 | return _timeseries_filename; |
| 127 | 63 | } | |
| 128 | |||
| 129 | 174 | void _write(const std::string& filename_with_ext) const { | |
| 130 | if constexpr (is_transient) | ||
| 131 | throw InvalidState("This overload only works for non-transient output"); | ||
| 132 |
1/2✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
|
174 | HDF5File file{filename_with_ext, _comm, HDF5File::Mode::overwrite}; |
| 133 |
1/2✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
|
174 | _write_to(file); |
| 134 | 174 | } | |
| 135 | |||
| 136 | 274 | void _write_to(HDF5File& file) const { | |
| 137 |
6/10✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 22 times.
✓ Branch 7 taken 133 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 21 times.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
274 | const ImageSpecs my_specs{origin(this->grid()), spacing(this->grid()), extents(this->grid())}; |
| 138 |
1/2✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
|
274 | const auto [overall_specs, my_offset] = _get_image_specs(my_specs); |
| 139 | 274 | const auto cell_slice_base = _make_slice( | |
| 140 |
1/2✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
|
274 | overall_specs.extents, |
| 141 | my_specs.extents, | ||
| 142 | my_offset | ||
| 143 | ); | ||
| 144 | |||
| 145 | // in order to avoid overlapping hyperslabs for point data in parallel I/O, | ||
| 146 | // we only write the last entries of the slab (per direction) when our portion | ||
| 147 | // of the image is the last portion of the overall image in that direction. | ||
| 148 |
1/2✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
|
274 | const auto my_point_extents = Ranges::to_array<dim>( |
| 149 |
1/2✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
|
274 | std::views::iota(std::size_t{0}, dim) |
| 150 |
2/4✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
|
866 | | std::views::transform([&] (std::size_t dir) { |
| 151 | 390 | const auto overall_end = overall_specs.extents[dir]; | |
| 152 | 390 | const auto my_end = my_specs.extents[dir] + my_offset[dir]; | |
| 153 |
8/8✓ Branch 0 taken 23 times.
✓ Branch 1 taken 98 times.
✓ Branch 4 taken 45 times.
✓ Branch 5 taken 174 times.
✓ Branch 8 taken 5 times.
✓ Branch 9 taken 24 times.
✓ Branch 12 taken 5 times.
✓ Branch 13 taken 16 times.
|
390 | return my_end < overall_end ? my_specs.extents[dir] : my_specs.extents[dir] + 1; |
| 154 | })); | ||
| 155 | 274 | const auto point_slice_base = _make_slice<true>( | |
| 156 |
1/2✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
|
274 | overall_specs.extents, |
| 157 | my_point_extents, | ||
| 158 | my_offset | ||
| 159 | ); | ||
| 160 | |||
| 161 |
2/4✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
|
548 | file.write_attribute(std::array<std::size_t, 2>{(is_transient ? 2 : 1), 0}, "/VTKHDF/Version"); |
| 162 |
3/6✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 155 times.
✗ Branch 8 not taken.
|
548 | file.write_attribute(Ranges::to_array<vtk_space_dim>(overall_specs.origin), "/VTKHDF/Origin"); |
| 163 |
3/6✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 155 times.
✗ Branch 8 not taken.
|
548 | file.write_attribute(Ranges::to_array<vtk_space_dim>(overall_specs.spacing), "/VTKHDF/Spacing"); |
| 164 |
3/6✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 155 times.
✗ Branch 8 not taken.
|
548 | file.write_attribute(VTK::CommonDetail::get_extents(overall_specs.extents), "/VTKHDF/WholeExtent"); |
| 165 |
3/6✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 155 times.
✗ Branch 8 not taken.
|
548 | file.write_attribute(_get_direction(), "/VTKHDF/Direction"); |
| 166 |
2/4✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
|
274 | file.write_attribute("ImageData", "/VTKHDF/Type"); |
| 167 | |||
| 168 |
2/4✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
|
367 | std::ranges::for_each(this->_meta_data_field_names(), [&] (const std::string& name) { |
| 169 | if constexpr (is_transient) { | ||
| 170 |
3/4✓ Branch 0 taken 108 times.
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 108 times.
|
144 | if (this->_step_count > 0 && _transient_opts.static_meta_data) { |
| 171 | ✗ | file.write(std::array{0}, "/VTKHDF/Steps/FieldDataOffsets/" + name); | |
| 172 | ✗ | return; | |
| 173 | } else { | ||
| 174 |
2/4✓ Branch 2 taken 144 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 144 times.
✗ Branch 6 not taken.
|
144 | file.write(std::array{this->_step_count}, "/VTKHDF/Steps/FieldDataOffsets/" + name); |
| 175 | } | ||
| 176 |
1/2✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
|
144 | auto field_ptr = this->_get_meta_data_field_ptr(name); |
| 177 |
2/4✓ Branch 2 taken 144 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 144 times.
✗ Branch 6 not taken.
|
144 | auto sub = make_field_ptr(TransformedField{field_ptr, FieldTransformation::as_sub_field}); |
| 178 |
3/6✓ Branch 2 taken 144 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 144 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 144 times.
✗ Branch 10 not taken.
|
144 | _write_field(file, sub, "/VTKHDF/FieldData/" + name, _slice_from(sub)); |
| 179 | 144 | } else { | |
| 180 |
1/8✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
18 | auto field_ptr = this->_get_meta_data_field_ptr(name); |
| 181 |
3/24✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 18 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 18 times.
✗ Branch 10 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
|
18 | _write_field(file, field_ptr, "/VTKHDF/FieldData/" + name, _slice_from(field_ptr)); |
| 182 | 18 | } | |
| 183 | |||
| 184 | }); | ||
| 185 | |||
| 186 | 274 | std::vector<std::size_t> non_zero_extents; | |
| 187 |
2/4✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
|
548 | std::ranges::copy( |
| 188 |
2/4✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
|
664 | my_specs.extents | std::views::filter([] (auto e) { return e != 0; }), |
| 189 | std::back_inserter(non_zero_extents) | ||
| 190 | ); | ||
| 191 | |||
| 192 |
2/4✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
|
1099 | std::ranges::for_each(this->_point_field_names(), [&] (const std::string& name) { |
| 193 |
4/8✓ Branch 1 taken 243 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 468 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 72 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 42 times.
✗ Branch 11 not taken.
|
825 | auto field_ptr = _reshape( |
| 194 |
8/16✓ Branch 1 taken 243 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 243 times.
✗ Branch 5 not taken.
✓ Branch 11 taken 468 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 468 times.
✗ Branch 15 not taken.
✓ Branch 21 taken 72 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 72 times.
✗ Branch 25 not taken.
✓ Branch 31 taken 42 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 42 times.
✗ Branch 35 not taken.
|
1650 | VTK::make_vtk_field(this->_get_point_field_ptr(name)), |
| 195 |
4/8✓ Branch 1 taken 243 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 468 times.
✗ Branch 9 not taken.
✓ Branch 15 taken 72 times.
✗ Branch 16 not taken.
✓ Branch 22 taken 42 times.
✗ Branch 23 not taken.
|
1650 | Ranges::incremented(non_zero_extents, 1) | std::views::reverse, |
| 196 |
4/8✓ Branch 1 taken 243 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 468 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 72 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 42 times.
✗ Branch 11 not taken.
|
825 | point_slice_base.count |
| 197 | ); | ||
| 198 |
8/16✓ Branch 1 taken 243 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 243 times.
✗ Branch 6 not taken.
✓ Branch 12 taken 468 times.
✗ Branch 13 not taken.
✓ Branch 16 taken 468 times.
✗ Branch 17 not taken.
✓ Branch 23 taken 72 times.
✗ Branch 24 not taken.
✓ Branch 27 taken 72 times.
✗ Branch 28 not taken.
✓ Branch 34 taken 42 times.
✗ Branch 35 not taken.
✓ Branch 38 taken 42 times.
✗ Branch 39 not taken.
|
825 | _write_field(file, field_ptr, "/VTKHDF/PointData/" + name, point_slice_base); |
| 199 | 825 | }); | |
| 200 | |||
| 201 |
2/4✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
|
553 | std::ranges::for_each(this->_cell_field_names(), [&] (const std::string& name) { |
| 202 |
2/8✓ Branch 1 taken 129 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 150 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
279 | auto field_ptr = _reshape( |
| 203 |
4/16✓ Branch 1 taken 129 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 129 times.
✗ Branch 5 not taken.
✓ Branch 11 taken 150 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 150 times.
✗ Branch 15 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
|
558 | VTK::make_vtk_field(this->_get_cell_field_ptr(name)), |
| 204 | ✗ | non_zero_extents | std::views::reverse, | |
| 205 |
2/8✓ Branch 1 taken 129 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 150 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
279 | cell_slice_base.count |
| 206 | ); | ||
| 207 |
4/16✓ Branch 1 taken 129 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 129 times.
✗ Branch 6 not taken.
✓ Branch 12 taken 150 times.
✗ Branch 13 not taken.
✓ Branch 16 taken 150 times.
✗ Branch 17 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
|
279 | _write_field(file, field_ptr, "/VTKHDF/CellData/" + name, cell_slice_base); |
| 208 | 279 | }); | |
| 209 | 274 | } | |
| 210 | |||
| 211 | template<std::ranges::range E, std::ranges::range S> | ||
| 212 | 2208 | FieldPtr _reshape(FieldPtr f, const E& row_major_extents, S&& _slice_end) const { | |
| 213 |
1/2✓ Branch 2 taken 1104 times.
✗ Branch 3 not taken.
|
2208 | auto flat = _flatten(f); |
| 214 |
1/2✓ Branch 2 taken 1104 times.
✗ Branch 3 not taken.
|
2208 | auto structured = _make_structured(flat, row_major_extents); |
| 215 |
1/2✓ Branch 2 taken 1104 times.
✗ Branch 3 not taken.
|
2208 | const auto structured_layout = structured->layout(); |
| 216 | |||
| 217 | 2208 | std::vector<std::size_t> slice_end; | |
| 218 |
2/4✓ Branch 1 taken 1104 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1104 times.
✗ Branch 5 not taken.
|
2208 | std::ranges::copy(_slice_end, std::back_inserter(slice_end)); |
| 219 |
3/4✓ Branch 2 taken 1812 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 708 times.
✓ Branch 5 taken 1104 times.
|
3624 | for (std::size_t i = slice_end.size(); i < structured_layout.dimension(); ++i) |
| 220 |
2/4✓ Branch 1 taken 708 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 708 times.
✗ Branch 5 not taken.
|
1416 | slice_end.push_back(structured_layout.extent(i)); |
| 221 | 4416 | return transform(structured, FieldTransformation::take_slice({ | |
| 222 | 2208 | .from = std::vector<std::size_t>(slice_end.size(), 0), | |
| 223 | .to = slice_end | ||
| 224 |
1/2✓ Branch 1 taken 1104 times.
✗ Branch 2 not taken.
|
4416 | })); |
| 225 |
2/6✓ Branch 2 taken 1104 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1104 times.
✗ Branch 6 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
4416 | } |
| 226 | |||
| 227 | 1986 | FieldPtr _flatten(FieldPtr f) const { | |
| 228 |
1/2✓ Branch 2 taken 1104 times.
✗ Branch 3 not taken.
|
1986 | const auto layout = f->layout(); |
| 229 |
3/4✓ Branch 1 taken 1104 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 756 times.
✓ Branch 4 taken 348 times.
|
1986 | if (layout.dimension() <= 2) |
| 230 | 1350 | return f; | |
| 231 | // vtk requires tensors to be made flat | ||
| 232 |
3/6✓ Branch 1 taken 348 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 348 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 348 times.
✗ Branch 8 not taken.
|
636 | auto nl = MDLayout{{layout.extent(0), layout.number_of_entries(1)}}; |
| 233 |
3/6✓ Branch 2 taken 348 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 348 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 348 times.
✗ Branch 10 not taken.
|
636 | return transform(f, FieldTransformation::reshape_to(std::move(nl))); |
| 234 | 1986 | } | |
| 235 | |||
| 236 | template<std::ranges::range E> | ||
| 237 | 2208 | FieldPtr _make_structured(FieldPtr f, const E& row_major_extents) const { | |
| 238 |
1/2✓ Branch 2 taken 1104 times.
✗ Branch 3 not taken.
|
2208 | const auto layout = f->layout(); |
| 239 |
1/2✓ Branch 2 taken 1104 times.
✗ Branch 3 not taken.
|
2208 | std::vector<std::size_t> target_layout(Ranges::size(row_major_extents)); |
| 240 |
1/2✓ Branch 2 taken 1104 times.
✗ Branch 3 not taken.
|
2208 | std::ranges::copy(row_major_extents, target_layout.begin()); |
| 241 |
3/4✓ Branch 1 taken 1104 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 708 times.
✓ Branch 4 taken 396 times.
|
2208 | if (layout.dimension() > 1) |
| 242 |
2/4✓ Branch 1 taken 708 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 708 times.
✗ Branch 5 not taken.
|
1416 | target_layout.push_back(layout.extent(1)); |
| 243 |
3/6✓ Branch 2 taken 1104 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1104 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1104 times.
✗ Branch 10 not taken.
|
4416 | return transform(f, FieldTransformation::reshape_to(MDLayout{std::move(target_layout)})); |
| 244 | 2208 | } | |
| 245 | |||
| 246 | 274 | auto _get_image_specs(const ImageSpecs& piece_specs) const { | |
| 247 | using OffsetType = std::ranges::range_value_t<decltype(piece_specs.extents)>; | ||
| 248 |
2/2✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47 times.
|
274 | if (Parallel::size(_comm) > 1) { |
| 249 | 192 | PVTK::StructuredParallelGridHelper helper{_comm}; | |
| 250 |
1/2✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
|
192 | const auto all_origins = Parallel::gather(_comm, piece_specs.origin, root_rank); |
| 251 |
1/2✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
|
192 | const auto all_extents = Parallel::gather(_comm, piece_specs.extents, root_rank); |
| 252 |
1/2✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
|
192 | const auto is_negative_axis = VTK::CommonDetail::structured_grid_axis_orientation(piece_specs.spacing); |
| 253 |
2/3✓ Branch 1 taken 96 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
360 | const auto [exts_begin, exts_end, whole_extent, origin] = helper.compute_extents_and_origin( |
| 254 | all_origins, | ||
| 255 | all_extents, | ||
| 256 | is_negative_axis, | ||
| 257 |
1/2✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
|
360 | basis(this->grid()) |
| 258 | ); | ||
| 259 | |||
| 260 |
1/2✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
|
192 | const auto my_whole_extent = Parallel::broadcast(_comm, whole_extent, root_rank); |
| 261 |
1/2✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
|
192 | const auto my_whole_origin = Parallel::broadcast(_comm, origin, root_rank); |
| 262 |
2/4✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 108 times.
✗ Branch 5 not taken.
|
192 | const auto my_extent_offset = Parallel::scatter(_comm, Ranges::flat(exts_begin), root_rank); |
| 263 | ✗ | return std::make_tuple( | |
| 264 |
1/2✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
|
192 | ImageSpecs{my_whole_origin, piece_specs.spacing, my_whole_extent}, |
| 265 | my_extent_offset | ||
| 266 |
1/2✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
|
192 | ); |
| 267 | 192 | } else { | |
| 268 |
1/2✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
|
82 | return std::make_tuple(piece_specs, std::vector<OffsetType>(dim, 0)); |
| 269 | } | ||
| 270 | } | ||
| 271 | |||
| 272 | template<bool increment = false, typename TotalExtents, typename Extents, typename Offsets> | ||
| 273 | 620 | HDF5::Slice _make_slice(const TotalExtents& total_extents, | |
| 274 | const Extents& extents, | ||
| 275 | const Offsets& offsets) const { | ||
| 276 | 620 | HDF5::Slice result; | |
| 277 | 620 | result.total_size.emplace(); | |
| 278 | |||
| 279 | // use only those dimensions that are not zero | ||
| 280 | 620 | std::vector<bool> is_nonzero; | |
| 281 |
2/4✓ Branch 1 taken 310 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 310 times.
✗ Branch 5 not taken.
|
1240 | std::ranges::copy( |
| 282 |
2/4✓ Branch 1 taken 310 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 310 times.
✗ Branch 5 not taken.
|
1400 | total_extents | std::views::transform([] (const auto& v) { return v != 0; }), |
| 283 | std::back_inserter(is_nonzero) | ||
| 284 | ); | ||
| 285 |
1/2✓ Branch 1 taken 310 times.
✗ Branch 2 not taken.
|
1400 | std::ranges::for_each(total_extents, [&, i=0] (const auto& value) mutable { |
| 286 |
16/32✓ Branch 1 taken 121 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 121 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 121 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 121 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 219 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 219 times.
✗ Branch 19 not taken.
✓ Branch 22 taken 219 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 219 times.
✗ Branch 26 not taken.
✓ Branch 29 taken 29 times.
✗ Branch 30 not taken.
✓ Branch 32 taken 29 times.
✗ Branch 33 not taken.
✓ Branch 36 taken 29 times.
✗ Branch 37 not taken.
✓ Branch 39 taken 29 times.
✗ Branch 40 not taken.
✓ Branch 43 taken 21 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 21 times.
✗ Branch 47 not taken.
✓ Branch 50 taken 21 times.
✗ Branch 51 not taken.
✓ Branch 53 taken 21 times.
✗ Branch 54 not taken.
|
780 | if (is_nonzero[i++]) |
| 287 |
8/16✓ Branch 2 taken 121 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 121 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 219 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 219 times.
✗ Branch 15 not taken.
✓ Branch 18 taken 29 times.
✗ Branch 19 not taken.
✓ Branch 22 taken 29 times.
✗ Branch 23 not taken.
✓ Branch 26 taken 21 times.
✗ Branch 27 not taken.
✓ Branch 30 taken 21 times.
✗ Branch 31 not taken.
|
780 | result.total_size.value().push_back(value + (increment ? 1 : 0)); |
| 288 | }); | ||
| 289 |
1/2✓ Branch 1 taken 310 times.
✗ Branch 2 not taken.
|
1400 | std::ranges::for_each(extents, [&, i=0] (const auto& value) mutable { |
| 290 |
16/32✓ Branch 1 taken 121 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 121 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 121 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 121 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 219 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 219 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 219 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 219 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 29 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 29 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 29 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 29 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 21 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 21 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 21 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 21 times.
✗ Branch 47 not taken.
|
780 | if (is_nonzero[i++]) |
| 291 | 780 | result.count.push_back(value); | |
| 292 | }); | ||
| 293 |
1/2✓ Branch 1 taken 310 times.
✗ Branch 2 not taken.
|
1400 | std::ranges::for_each(offsets, [&, i=0] (const auto& value) mutable { |
| 294 |
16/32✓ Branch 1 taken 121 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 121 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 121 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 121 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 219 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 219 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 219 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 219 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 29 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 29 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 29 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 29 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 21 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 21 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 21 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 21 times.
✗ Branch 47 not taken.
|
780 | if (is_nonzero[i++]) |
| 295 | 780 | result.offset.push_back(value); | |
| 296 | }); | ||
| 297 | |||
| 298 | // slices in VTK are accessed with the last coordinate first (i.e. values[z][y][x]) | ||
| 299 |
2/4✓ Branch 1 taken 310 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 310 times.
✗ Branch 5 not taken.
|
620 | std::ranges::reverse(result.total_size.value()); |
| 300 |
1/2✓ Branch 1 taken 310 times.
✗ Branch 2 not taken.
|
620 | std::ranges::reverse(result.count); |
| 301 |
1/2✓ Branch 1 taken 310 times.
✗ Branch 2 not taken.
|
620 | std::ranges::reverse(result.offset); |
| 302 | |||
| 303 | 620 | return result; | |
| 304 | 620 | } | |
| 305 | |||
| 306 | 274 | auto _get_direction() const { | |
| 307 | using T = MDRangeScalar<decltype(basis(this->grid()))>; | ||
| 308 | std::array<T, vtk_space_dim*vtk_space_dim> coefficients; | ||
| 309 |
1/2✓ Branch 1 taken 134 times.
✗ Branch 2 not taken.
|
274 | std::ranges::fill(coefficients, T{0}); |
| 310 |
2/4✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
|
274 | std::ranges::for_each( |
| 311 |
3/5✓ Branch 1 taken 141 times.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
|
274 | Matrix{basis(this->grid())}.transposed(), |
| 312 | 910 | [it = coefficients.begin()] (const std::ranges::range auto& row) mutable { | |
| 313 | 390 | std::ranges::copy(row, it); | |
| 314 | 390 | std::advance(it, vtk_space_dim); | |
| 315 | } | ||
| 316 | ); | ||
| 317 | 274 | return coefficients; | |
| 318 | } | ||
| 319 | |||
| 320 | 2232 | void _write_field(HDF5File& file, | |
| 321 | FieldPtr field, | ||
| 322 | const std::string& path, | ||
| 323 | const HDF5::Slice& slice) const { | ||
| 324 | 2232 | const std::size_t dimension_offset = is_transient ? 1 : 0; | |
| 325 |
2/4✓ Branch 1 taken 1266 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1266 times.
✗ Branch 6 not taken.
|
4464 | std::vector<std::size_t> size(slice.total_size.value().size() + dimension_offset); |
| 326 |
1/2✓ Branch 2 taken 1266 times.
✗ Branch 3 not taken.
|
4464 | std::vector<std::size_t> count(slice.count.size() + dimension_offset); |
| 327 |
1/2✓ Branch 2 taken 1266 times.
✗ Branch 3 not taken.
|
2232 | std::vector<std::size_t> offset(slice.offset.size() + dimension_offset); |
| 328 |
5/10✓ Branch 1 taken 1266 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1266 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1266 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1266 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1266 times.
✗ Branch 14 not taken.
|
2232 | std::ranges::copy(slice.total_size.value(), std::ranges::begin(size | std::views::drop(dimension_offset))); |
| 329 |
4/8✓ Branch 1 taken 1266 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1266 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1266 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1266 times.
✗ Branch 11 not taken.
|
2232 | std::ranges::copy(slice.count, std::ranges::begin(count | std::views::drop(dimension_offset))); |
| 330 |
4/8✓ Branch 1 taken 1266 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1266 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1266 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1266 times.
✗ Branch 11 not taken.
|
2232 | std::ranges::copy(slice.offset, std::ranges::begin(offset | std::views::drop(dimension_offset))); |
| 331 | |||
| 332 |
1/2✓ Branch 2 taken 1266 times.
✗ Branch 3 not taken.
|
2232 | const auto layout = field->layout(); |
| 333 |
1/2✓ Branch 1 taken 1266 times.
✗ Branch 2 not taken.
|
2232 | const bool is_vector_field = layout.dimension() > size.size() - dimension_offset; |
| 334 |
2/2✓ Branch 0 taken 708 times.
✓ Branch 1 taken 558 times.
|
2232 | if (is_vector_field) |
| 335 |
1/2✓ Branch 1 taken 708 times.
✗ Branch 2 not taken.
|
1296 | std::ranges::for_each( |
| 336 |
2/4✓ Branch 1 taken 708 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 708 times.
✗ Branch 6 not taken.
|
2592 | std::views::iota(size.size() - dimension_offset, layout.dimension()), |
| 337 | 1416 | [&] (const std::size_t codim) { | |
| 338 |
8/16✓ Branch 1 taken 220 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 220 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 412 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 412 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 48 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 48 times.
✗ Branch 19 not taken.
✓ Branch 22 taken 28 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 28 times.
✗ Branch 26 not taken.
|
708 | size.push_back(layout.extent(codim)); |
| 339 |
8/16✓ Branch 1 taken 220 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 220 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 412 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 412 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 48 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 48 times.
✗ Branch 19 not taken.
✓ Branch 22 taken 28 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 28 times.
✗ Branch 26 not taken.
|
708 | count.push_back(layout.extent(codim)); |
| 340 |
4/8✓ Branch 1 taken 220 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 412 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 48 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 28 times.
✗ Branch 11 not taken.
|
708 | offset.push_back(0); |
| 341 | } | ||
| 342 | ); | ||
| 343 | |||
| 344 | if constexpr (is_transient) { | ||
| 345 |
1/2✓ Branch 1 taken 690 times.
✗ Branch 2 not taken.
|
1095 | size.at(0) = 1; |
| 346 |
1/2✓ Branch 1 taken 690 times.
✗ Branch 2 not taken.
|
1095 | count.at(0) = 1; |
| 347 |
1/2✓ Branch 1 taken 690 times.
✗ Branch 2 not taken.
|
1095 | offset.at(0) = 0; |
| 348 |
1/2✓ Branch 2 taken 690 times.
✗ Branch 3 not taken.
|
1095 | FieldPtr sub_field = transform(field, FieldTransformation::as_sub_field); |
| 349 |
1/2✓ Branch 2 taken 690 times.
✗ Branch 3 not taken.
|
1095 | file.write(*sub_field, path, HDF5::Slice{ |
| 350 | 1095 | .offset = std::move(offset), | |
| 351 | 1095 | .count = std::move(count), | |
| 352 | 1095 | .total_size = std::move(size) | |
| 353 | }); | ||
| 354 | 1095 | } else { | |
| 355 |
1/2✓ Branch 2 taken 576 times.
✗ Branch 3 not taken.
|
1137 | file.write(*field, path, HDF5::Slice{ |
| 356 | 1137 | .offset = std::move(offset), | |
| 357 | 1137 | .count = std::move(count), | |
| 358 | 1137 | .total_size = std::move(size) | |
| 359 | }); | ||
| 360 | } | ||
| 361 |
0/4✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
4464 | } |
| 362 | |||
| 363 | 246 | HDF5::Slice _slice_from(FieldPtr field) const { | |
| 364 |
1/2✓ Branch 2 taken 162 times.
✗ Branch 3 not taken.
|
246 | const auto layout = field->layout(); |
| 365 |
2/4✓ Branch 1 taken 162 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 162 times.
✗ Branch 5 not taken.
|
492 | std::vector<std::size_t> dims(layout.dimension()); |
| 366 |
2/4✓ Branch 1 taken 162 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 162 times.
✗ Branch 5 not taken.
|
246 | std::vector<std::size_t> offset(layout.dimension(), 0); |
| 367 |
1/2✓ Branch 1 taken 162 times.
✗ Branch 2 not taken.
|
246 | layout.export_to(dims); |
| 368 | return { | ||
| 369 | 246 | .offset = std::move(offset), | |
| 370 | .count = dims, | ||
| 371 | .total_size = dims | ||
| 372 | 246 | }; | |
| 373 |
2/8✓ Branch 3 taken 162 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 162 times.
✗ Branch 7 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
|
246 | } |
| 374 | |||
| 375 | Communicator _comm; | ||
| 376 | std::string _timeseries_filename = ""; | ||
| 377 | VTK::HDFTransientOptions _transient_opts; | ||
| 378 | }; | ||
| 379 | |||
| 380 | /*! | ||
| 381 | * \ingroup VTK | ||
| 382 | * \brief Writer for the VTK HDF file format for image grids. | ||
| 383 | */ | ||
| 384 | template<Concepts::ImageGrid G, Concepts::Communicator C = NullCommunicator> | ||
| 385 | class VTKHDFImageGridWriter : public VTKHDFImageGridWriterImpl<false, G, C> { | ||
| 386 | using ParentType = VTKHDFImageGridWriterImpl<false, G, C>; | ||
| 387 | public: | ||
| 388 | using ParentType::ParentType; | ||
| 389 | }; | ||
| 390 | |||
| 391 | /*! | ||
| 392 | * \ingroup VTK | ||
| 393 | * \brief Writer for the transient VTK HDF file format for image grids. | ||
| 394 | */ | ||
| 395 | template<Concepts::ImageGrid G, Concepts::Communicator C = NullCommunicator> | ||
| 396 | class VTKHDFImageGridTimeSeriesWriter : public VTKHDFImageGridWriterImpl<true, G, C> { | ||
| 397 | using ParentType = VTKHDFImageGridWriterImpl<true, G, C>; | ||
| 398 | public: | ||
| 399 | using ParentType::ParentType; | ||
| 400 | }; | ||
| 401 | |||
| 402 | template<Concepts::ImageGrid G> | ||
| 403 | VTKHDFImageGridWriter(const G&) -> VTKHDFImageGridWriter<G, NullCommunicator>; | ||
| 404 | template<Concepts::ImageGrid G, Concepts::Communicator C> | ||
| 405 | VTKHDFImageGridWriter(const G&, const C&) -> VTKHDFImageGridWriter<G, C>; | ||
| 406 | |||
| 407 | template<Concepts::ImageGrid G> | ||
| 408 | VTKHDFImageGridTimeSeriesWriter(const G&, std::string, VTK::HDFTransientOptions = {}) -> VTKHDFImageGridTimeSeriesWriter<G, NullCommunicator>; | ||
| 409 | template<Concepts::ImageGrid G, Concepts::Communicator C> | ||
| 410 | VTKHDFImageGridTimeSeriesWriter(const G&, const C&, std::string, VTK::HDFTransientOptions = {}) -> VTKHDFImageGridTimeSeriesWriter<G, C>; | ||
| 411 | |||
| 412 | |||
| 413 | namespace Traits { | ||
| 414 | |||
| 415 | template<typename... Args> | ||
| 416 | struct WritesConnectivity<VTKHDFImageGridWriter<Args...>> : public std::false_type {}; | ||
| 417 | |||
| 418 | template<typename... Args> | ||
| 419 | struct WritesConnectivity<VTKHDFImageGridTimeSeriesWriter<Args...>> : public std::false_type {}; | ||
| 420 | |||
| 421 | } // namespace Traits | ||
| 422 | } // namespace GridFormat | ||
| 423 | |||
| 424 | #endif // GRIDFORMAT_HAVE_HIGH_FIVE | ||
| 425 | #endif // GRIDFORMAT_VTK_HDF_IMAGE_GRID_WRITER_HPP_ | ||
| 426 |