| 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 | 638 | ImageSpecs(O&& origin, S&& spacing, E&& extents) | |
| 57 | 638 | : origin{Ranges::to_array<dim, CT>(std::forward<O>(origin))} | |
| 58 | 638 | , spacing{Ranges::to_array<dim, CT>(std::forward<S>(spacing))} | |
| 59 | 638 | , extents{Ranges::to_array<dim, std::size_t>(std::forward<E>(extents))} | |
| 60 | 638 | {} | |
| 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 | 24 | explicit VTKHDFImageGridWriterImpl(LValueReferenceOf<const Grid> grid) | |
| 70 | requires(std::is_same_v<Communicator, NullCommunicator>) | ||
| 71 |
3/6✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 14 times.
✗ Branch 11 not taken.
|
120 | : GridWriter<Grid>(grid.get(), ".hdf", writer_opts) |
| 72 | 24 | {} | |
| 73 | |||
| 74 | 151 | 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 79 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 79 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 79 times.
✗ Branch 11 not taken.
|
755 | , _comm{comm} |
| 78 | 151 | {} | |
| 79 | |||
| 80 | 11 | 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 11 times.
✗ Branch 3 not taken.
✓ Branch 7 taken 11 times.
✗ Branch 8 not taken.
|
11 | : VTKHDFImageGridWriterImpl(grid.get(), NullCommunicator{}, filename_without_extension, std::move(opts)) |
| 88 | 11 | {} | |
| 89 | |||
| 90 | 26 | 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 | 14 | , _comm{comm} | |
| 100 |
1/2✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
|
26 | , _timeseries_filename{std::move(filename_without_extension) + ".hdf"} |
| 101 |
1/2✓ Branch 3 taken 25 times.
✗ Branch 4 not taken.
|
52 | , _transient_opts{std::move(opts)} { |
| 102 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
|
26 | if (!_transient_opts.static_grid) |
| 103 | ✗ | throw ValueError("Transient VTK-HDF ImageData files do not support evolving grids"); | |
| 104 | 26 | } | |
| 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 | 96 | 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 26 times.
✓ Branch 1 taken 70 times.
|
96 | if (this->_step_count == 0) |
| 120 | 26 | HDF5File::clear(_timeseries_filename, _comm); | |
| 121 | |||
| 122 | { // scope to close the file before writing meta data on rank 0 with serial I/O | ||
| 123 |
1/2✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
|
96 | HDF5File file{_timeseries_filename, _comm, HDF5File::Mode::append}; |
| 124 |
1/2✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
|
96 | _write_to(file); |
| 125 |
2/4✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
|
96 | file.write_attribute(this->_step_count+1, "/VTKHDF/Steps/NSteps"); |
| 126 |
2/4✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 96 times.
✗ Branch 6 not taken.
|
288 | file.write(std::array{t}, "/VTKHDF/Steps/Values"); |
| 127 | 96 | } | |
| 128 | 96 | _write_meta_data(_timeseries_filename); | |
| 129 | 96 | return _timeseries_filename; | |
| 130 | } | ||
| 131 | |||
| 132 | 177 | void _write(const std::string& filename_with_ext) const { | |
| 133 | if constexpr (is_transient) | ||
| 134 | throw InvalidState("This overload only works for non-transient output"); | ||
| 135 | { // scope to close the file before writing meta data on rank 0 with serial I/O | ||
| 136 |
1/2✓ Branch 1 taken 95 times.
✗ Branch 2 not taken.
|
177 | HDF5File file{filename_with_ext, _comm, HDF5File::Mode::overwrite}; |
| 137 |
1/2✓ Branch 1 taken 95 times.
✗ Branch 2 not taken.
|
177 | _write_to(file); |
| 138 | 177 | } | |
| 139 | 177 | _write_meta_data(filename_with_ext); | |
| 140 | 177 | } | |
| 141 | |||
| 142 | // hdf5 cannot write variable-length strings into files opened for parallel I/O, not even from | ||
| 143 | // a single rank. Therefore, all meta data is written by rank 0 once the (parallel) file is closed, | ||
| 144 | // reopened with the default driver. Meta data is assumed to be the same on all ranks. | ||
| 145 | 316 | void _write_meta_data(const std::string& filename) const { | |
| 146 |
1/2✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
|
458 | VTKHDF::write_on_root(filename, _comm, root_rank, [&] (HDF5::File<>& file) { |
| 147 | 115 | _write_meta_data(file); | |
| 148 | }); | ||
| 149 | 316 | } | |
| 150 | |||
| 151 | 186 | void _write_meta_data(HDF5::File<>& file) const { | |
| 152 |
2/4✓ Branch 1 taken 115 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 115 times.
✗ Branch 5 not taken.
|
727 | std::ranges::for_each(this->_meta_data_field_names(), [&] (const std::string& name) { |
| 153 | 405 | VTKHDF::check_array_name(name); | |
| 154 | if constexpr (is_transient) { | ||
| 155 |
4/4✓ Branch 0 taken 174 times.
✓ Branch 1 taken 63 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 164 times.
|
237 | if (this->_step_count > 0 && _transient_opts.static_meta_data) |
| 156 | 10 | VTKHDF::write_field_data_step_referencing(0, file, name); | |
| 157 | else | ||
| 158 |
2/4✓ Branch 1 taken 227 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 227 times.
✗ Branch 5 not taken.
|
227 | VTKHDF::write_field_data_step(file, name, this->_get_meta_data_field_ptr(name)); |
| 159 | } else { | ||
| 160 |
8/16✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 64 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 80 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 80 times.
✗ Branch 13 not taken.
✓ Branch 17 taken 12 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 12 times.
✗ Branch 21 not taken.
✓ Branch 25 taken 12 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 12 times.
✗ Branch 29 not taken.
|
168 | VTKHDF::write_field_data(file, name, this->_get_meta_data_field_ptr(name)); |
| 161 | } | ||
| 162 | }); | ||
| 163 | 186 | } | |
| 164 | |||
| 165 | 316 | void _write_to(HDF5File& file) const { | |
| 166 |
6/10✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 46 times.
✓ Branch 7 taken 145 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 45 times.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
316 | const ImageSpecs my_specs{origin(this->grid()), spacing(this->grid()), extents(this->grid())}; |
| 167 |
1/2✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
|
316 | const auto [overall_specs, my_offset] = _get_image_specs(my_specs); |
| 168 | 316 | const auto cell_slice_base = _make_slice( | |
| 169 |
1/2✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
|
316 | overall_specs.extents, |
| 170 | my_specs.extents, | ||
| 171 | my_offset | ||
| 172 | ); | ||
| 173 | |||
| 174 | // in order to avoid overlapping hyperslabs for point data in parallel I/O, | ||
| 175 | // we only write the last entries of the slab (per direction) when our portion | ||
| 176 | // of the image is the last portion of the overall image in that direction. | ||
| 177 |
1/2✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
|
316 | const auto my_point_extents = Ranges::to_array<dim>( |
| 178 |
1/2✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
|
316 | std::views::iota(std::size_t{0}, dim) |
| 179 |
2/4✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 191 times.
✗ Branch 5 not taken.
|
968 | | std::views::transform([&] (std::size_t dir) { |
| 180 | 468 | const auto overall_end = overall_specs.extents[dir]; | |
| 181 | 468 | const auto my_end = my_specs.extents[dir] + my_offset[dir]; | |
| 182 |
8/8✓ Branch 0 taken 33 times.
✓ Branch 1 taken 184 times.
✓ Branch 4 taken 45 times.
✓ Branch 5 taken 156 times.
✓ Branch 8 taken 5 times.
✓ Branch 9 taken 24 times.
✓ Branch 12 taken 5 times.
✓ Branch 13 taken 16 times.
|
468 | return my_end < overall_end ? my_specs.extents[dir] : my_specs.extents[dir] + 1; |
| 183 | })); | ||
| 184 | 316 | const auto point_slice_base = _make_slice<true>( | |
| 185 |
1/2✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
|
316 | overall_specs.extents, |
| 186 | my_point_extents, | ||
| 187 | my_offset | ||
| 188 | ); | ||
| 189 | |||
| 190 |
2/4✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 191 times.
✗ Branch 5 not taken.
|
632 | file.write_attribute(std::array<std::size_t, 2>{(is_transient ? 2 : 1), 0}, "/VTKHDF/Version"); |
| 191 |
3/6✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 191 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 191 times.
✗ Branch 8 not taken.
|
632 | file.write_attribute(Ranges::to_array<vtk_space_dim>(overall_specs.origin), "/VTKHDF/Origin"); |
| 192 |
3/6✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 191 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 191 times.
✗ Branch 8 not taken.
|
632 | file.write_attribute(Ranges::to_array<vtk_space_dim>(overall_specs.spacing), "/VTKHDF/Spacing"); |
| 193 |
3/6✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 191 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 191 times.
✗ Branch 8 not taken.
|
632 | file.write_attribute(VTK::CommonDetail::get_extents(overall_specs.extents), "/VTKHDF/WholeExtent"); |
| 194 |
3/6✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 191 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 191 times.
✗ Branch 8 not taken.
|
632 | file.write_attribute(_get_direction(), "/VTKHDF/Direction"); |
| 195 |
2/4✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 191 times.
✗ Branch 5 not taken.
|
316 | file.write_attribute("ImageData", "/VTKHDF/Type"); |
| 196 | |||
| 197 | 316 | std::vector<std::size_t> non_zero_extents; | |
| 198 |
2/4✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 191 times.
✗ Branch 5 not taken.
|
632 | std::ranges::copy( |
| 199 |
2/4✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 191 times.
✗ Branch 5 not taken.
|
784 | my_specs.extents | std::views::filter([] (auto e) { return e != 0; }), |
| 200 | std::back_inserter(non_zero_extents) | ||
| 201 | ); | ||
| 202 | |||
| 203 |
2/4✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 191 times.
✗ Branch 5 not taken.
|
1165 | std::ranges::for_each(this->_point_field_names(), [&] (const std::string& name) { |
| 204 |
4/8✓ Branch 1 taken 303 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 432 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 72 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 42 times.
✗ Branch 11 not taken.
|
849 | VTKHDF::check_array_name(name); |
| 205 |
4/8✓ Branch 1 taken 303 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 432 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 72 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 42 times.
✗ Branch 11 not taken.
|
849 | auto field_ptr = _reshape( |
| 206 |
8/16✓ Branch 1 taken 303 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 303 times.
✗ Branch 5 not taken.
✓ Branch 11 taken 432 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 432 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.
|
1698 | VTK::make_vtk_field(this->_get_point_field_ptr(name)), |
| 207 |
4/8✓ Branch 1 taken 303 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 432 times.
✗ Branch 9 not taken.
✓ Branch 15 taken 72 times.
✗ Branch 16 not taken.
✓ Branch 22 taken 42 times.
✗ Branch 23 not taken.
|
1698 | Ranges::incremented(non_zero_extents, 1) | std::views::reverse, |
| 208 |
4/8✓ Branch 1 taken 303 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 432 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 72 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 42 times.
✗ Branch 11 not taken.
|
849 | point_slice_base.count |
| 209 | ); | ||
| 210 |
8/16✓ Branch 1 taken 303 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 303 times.
✗ Branch 6 not taken.
✓ Branch 12 taken 432 times.
✗ Branch 13 not taken.
✓ Branch 16 taken 432 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.
|
849 | _write_field(file, field_ptr, "/VTKHDF/PointData/" + name, point_slice_base); |
| 211 | 849 | }); | |
| 212 | |||
| 213 |
2/4✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 191 times.
✗ Branch 5 not taken.
|
1123 | std::ranges::for_each(this->_cell_field_names(), [&] (const std::string& name) { |
| 214 |
4/8✓ Branch 1 taken 297 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 426 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 42 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 42 times.
✗ Branch 11 not taken.
|
807 | VTKHDF::check_array_name(name); |
| 215 |
4/8✓ Branch 1 taken 297 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 426 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 42 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 42 times.
✗ Branch 11 not taken.
|
807 | auto field_ptr = _reshape( |
| 216 |
8/16✓ Branch 1 taken 297 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 297 times.
✗ Branch 5 not taken.
✓ Branch 11 taken 426 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 426 times.
✗ Branch 15 not taken.
✓ Branch 21 taken 42 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 42 times.
✗ Branch 25 not taken.
✓ Branch 31 taken 42 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 42 times.
✗ Branch 35 not taken.
|
1614 | VTK::make_vtk_field(this->_get_cell_field_ptr(name)), |
| 217 | ✗ | non_zero_extents | std::views::reverse, | |
| 218 |
4/8✓ Branch 1 taken 297 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 426 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 42 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 42 times.
✗ Branch 11 not taken.
|
807 | cell_slice_base.count |
| 219 | ); | ||
| 220 |
8/16✓ Branch 1 taken 297 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 297 times.
✗ Branch 6 not taken.
✓ Branch 12 taken 426 times.
✗ Branch 13 not taken.
✓ Branch 16 taken 426 times.
✗ Branch 17 not taken.
✓ Branch 23 taken 42 times.
✗ Branch 24 not taken.
✓ Branch 27 taken 42 times.
✗ Branch 28 not taken.
✓ Branch 34 taken 42 times.
✗ Branch 35 not taken.
✓ Branch 38 taken 42 times.
✗ Branch 39 not taken.
|
807 | _write_field(file, field_ptr, "/VTKHDF/CellData/" + name, cell_slice_base); |
| 221 | 807 | }); | |
| 222 | 316 | } | |
| 223 | |||
| 224 | template<std::ranges::range E, std::ranges::range S> | ||
| 225 | 3312 | FieldPtr _reshape(FieldPtr f, const E& row_major_extents, S&& _slice_end) const { | |
| 226 |
1/2✓ Branch 2 taken 1656 times.
✗ Branch 3 not taken.
|
3312 | auto flat = _flatten(f); |
| 227 |
1/2✓ Branch 2 taken 1656 times.
✗ Branch 3 not taken.
|
3312 | auto structured = _make_structured(flat, row_major_extents); |
| 228 |
1/2✓ Branch 2 taken 1656 times.
✗ Branch 3 not taken.
|
3312 | const auto structured_layout = structured->layout(); |
| 229 | |||
| 230 | 3312 | std::vector<std::size_t> slice_end; | |
| 231 |
2/4✓ Branch 1 taken 1656 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1656 times.
✗ Branch 5 not taken.
|
3312 | std::ranges::copy(_slice_end, std::back_inserter(slice_end)); |
| 232 |
3/4✓ Branch 2 taken 2700 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1044 times.
✓ Branch 5 taken 1656 times.
|
5400 | for (std::size_t i = slice_end.size(); i < structured_layout.dimension(); ++i) |
| 233 |
2/4✓ Branch 1 taken 1044 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1044 times.
✗ Branch 5 not taken.
|
2088 | slice_end.push_back(structured_layout.extent(i)); |
| 234 | 6624 | return transform(structured, FieldTransformation::take_slice({ | |
| 235 | 3312 | .from = std::vector<std::size_t>(slice_end.size(), 0), | |
| 236 | .to = slice_end | ||
| 237 |
1/2✓ Branch 1 taken 1656 times.
✗ Branch 2 not taken.
|
6624 | })); |
| 238 |
2/6✓ Branch 2 taken 1656 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1656 times.
✗ Branch 6 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
6624 | } |
| 239 | |||
| 240 | 3042 | FieldPtr _flatten(FieldPtr f) const { | |
| 241 |
1/2✓ Branch 2 taken 1656 times.
✗ Branch 3 not taken.
|
3042 | const auto layout = f->layout(); |
| 242 |
3/4✓ Branch 1 taken 1656 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1144 times.
✓ Branch 4 taken 512 times.
|
3042 | if (layout.dimension() <= 2) |
| 243 | 2078 | return f; | |
| 244 | // vtk requires tensors to be made flat | ||
| 245 |
3/6✓ Branch 1 taken 512 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 512 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 512 times.
✗ Branch 8 not taken.
|
964 | auto nl = MDLayout{{layout.extent(0), layout.number_of_entries(1)}}; |
| 246 |
3/6✓ Branch 2 taken 512 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 512 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 512 times.
✗ Branch 10 not taken.
|
964 | return transform(f, FieldTransformation::reshape_to(std::move(nl))); |
| 247 | 3042 | } | |
| 248 | |||
| 249 | template<std::ranges::range E> | ||
| 250 | 3312 | FieldPtr _make_structured(FieldPtr f, const E& row_major_extents) const { | |
| 251 |
1/2✓ Branch 2 taken 1656 times.
✗ Branch 3 not taken.
|
3312 | const auto layout = f->layout(); |
| 252 |
1/2✓ Branch 2 taken 1656 times.
✗ Branch 3 not taken.
|
3312 | std::vector<std::size_t> target_layout(Ranges::size(row_major_extents)); |
| 253 |
1/2✓ Branch 2 taken 1656 times.
✗ Branch 3 not taken.
|
3312 | std::ranges::copy(row_major_extents, target_layout.begin()); |
| 254 |
3/4✓ Branch 1 taken 1656 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1044 times.
✓ Branch 4 taken 612 times.
|
3312 | if (layout.dimension() > 1) |
| 255 |
2/4✓ Branch 1 taken 1044 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1044 times.
✗ Branch 5 not taken.
|
2088 | target_layout.push_back(layout.extent(1)); |
| 256 |
3/6✓ Branch 2 taken 1656 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1656 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1656 times.
✗ Branch 10 not taken.
|
6624 | return transform(f, FieldTransformation::reshape_to(MDLayout{std::move(target_layout)})); |
| 257 | 3312 | } | |
| 258 | |||
| 259 | 316 | auto _get_image_specs(const ImageSpecs& piece_specs) const { | |
| 260 | using OffsetType = std::ranges::range_value_t<decltype(piece_specs.extents)>; | ||
| 261 |
2/2✓ Branch 1 taken 128 times.
✓ Branch 2 taken 63 times.
|
316 | if (Parallel::size(_comm) > 1) { |
| 262 | 212 | PVTK::StructuredParallelGridHelper helper{_comm}; | |
| 263 |
1/2✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
|
212 | const auto all_origins = Parallel::gather(_comm, piece_specs.origin, root_rank); |
| 264 |
1/2✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
|
212 | const auto all_extents = Parallel::gather(_comm, piece_specs.extents, root_rank); |
| 265 |
1/2✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
|
212 | const auto is_negative_axis = VTK::CommonDetail::structured_grid_axis_orientation(piece_specs.spacing); |
| 266 |
2/3✓ Branch 1 taken 116 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
400 | const auto [exts_begin, exts_end, whole_extent, origin] = helper.compute_extents_and_origin( |
| 267 | all_origins, | ||
| 268 | all_extents, | ||
| 269 | is_negative_axis, | ||
| 270 |
1/2✓ Branch 2 taken 116 times.
✗ Branch 3 not taken.
|
400 | basis(this->grid()) |
| 271 | ); | ||
| 272 | |||
| 273 |
1/2✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
|
212 | const auto my_whole_extent = Parallel::broadcast(_comm, whole_extent, root_rank); |
| 274 |
1/2✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
|
212 | const auto my_whole_origin = Parallel::broadcast(_comm, origin, root_rank); |
| 275 |
2/4✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 128 times.
✗ Branch 5 not taken.
|
212 | const auto my_extent_offset = Parallel::scatter(_comm, Ranges::flat(exts_begin), root_rank); |
| 276 | ✗ | return std::make_tuple( | |
| 277 |
1/2✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
|
212 | ImageSpecs{my_whole_origin, piece_specs.spacing, my_whole_extent}, |
| 278 | my_extent_offset | ||
| 279 |
1/2✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
|
212 | ); |
| 280 | 212 | } else { | |
| 281 |
1/2✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
|
104 | return std::make_tuple(piece_specs, std::vector<OffsetType>(dim, 0)); |
| 282 | } | ||
| 283 | } | ||
| 284 | |||
| 285 | template<bool increment = false, typename TotalExtents, typename Extents, typename Offsets> | ||
| 286 | 764 | HDF5::Slice _make_slice(const TotalExtents& total_extents, | |
| 287 | const Extents& extents, | ||
| 288 | const Offsets& offsets) const { | ||
| 289 | 764 | HDF5::Slice result; | |
| 290 | 764 | result.total_size.emplace(); | |
| 291 | |||
| 292 | // use only those dimensions that are not zero | ||
| 293 | 764 | std::vector<bool> is_nonzero; | |
| 294 |
2/4✓ Branch 1 taken 382 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 382 times.
✗ Branch 5 not taken.
|
1528 | std::ranges::copy( |
| 295 |
2/4✓ Branch 1 taken 382 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 382 times.
✗ Branch 5 not taken.
|
1700 | total_extents | std::views::transform([] (const auto& v) { return v != 0; }), |
| 296 | std::back_inserter(is_nonzero) | ||
| 297 | ); | ||
| 298 |
1/2✓ Branch 1 taken 382 times.
✗ Branch 2 not taken.
|
1700 | std::ranges::for_each(total_extents, [&, i=0] (const auto& value) mutable { |
| 299 |
16/32✓ Branch 1 taken 217 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 217 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 217 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 217 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 201 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 201 times.
✗ Branch 19 not taken.
✓ Branch 22 taken 201 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 201 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.
|
936 | if (is_nonzero[i++]) |
| 300 |
8/16✓ Branch 2 taken 217 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 217 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 201 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 201 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.
|
936 | result.total_size.value().push_back(value + (increment ? 1 : 0)); |
| 301 | }); | ||
| 302 |
1/2✓ Branch 1 taken 382 times.
✗ Branch 2 not taken.
|
1700 | std::ranges::for_each(extents, [&, i=0] (const auto& value) mutable { |
| 303 |
16/32✓ Branch 1 taken 217 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 217 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 217 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 217 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 201 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 201 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 201 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 201 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.
|
936 | if (is_nonzero[i++]) |
| 304 | 936 | result.count.push_back(value); | |
| 305 | }); | ||
| 306 |
1/2✓ Branch 1 taken 382 times.
✗ Branch 2 not taken.
|
1700 | std::ranges::for_each(offsets, [&, i=0] (const auto& value) mutable { |
| 307 |
16/32✓ Branch 1 taken 217 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 217 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 217 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 217 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 201 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 201 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 201 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 201 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.
|
936 | if (is_nonzero[i++]) |
| 308 | 936 | result.offset.push_back(value); | |
| 309 | }); | ||
| 310 | |||
| 311 | // slices in VTK are accessed with the last coordinate first (i.e. values[z][y][x]) | ||
| 312 |
2/4✓ Branch 1 taken 382 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 382 times.
✗ Branch 5 not taken.
|
764 | std::ranges::reverse(result.total_size.value()); |
| 313 |
1/2✓ Branch 1 taken 382 times.
✗ Branch 2 not taken.
|
764 | std::ranges::reverse(result.count); |
| 314 |
1/2✓ Branch 1 taken 382 times.
✗ Branch 2 not taken.
|
764 | std::ranges::reverse(result.offset); |
| 315 | |||
| 316 | 764 | return result; | |
| 317 | 764 | } | |
| 318 | |||
| 319 | 316 | auto _get_direction() const { | |
| 320 | using T = MDRangeScalar<decltype(basis(this->grid()))>; | ||
| 321 | std::array<T, vtk_space_dim*vtk_space_dim> coefficients; | ||
| 322 |
1/2✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
|
316 | std::ranges::fill(coefficients, T{0}); |
| 323 |
2/4✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 191 times.
✗ Branch 5 not taken.
|
316 | std::ranges::for_each( |
| 324 |
3/5✓ Branch 1 taken 177 times.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 177 times.
✗ Branch 5 not taken.
|
316 | Matrix{basis(this->grid())}.transposed(), |
| 325 | 988 | [it = coefficients.begin()] (const std::ranges::range auto& row) mutable { | |
| 326 | 468 | std::ranges::copy(row, it); | |
| 327 | 468 | std::advance(it, vtk_space_dim); | |
| 328 | } | ||
| 329 | ); | ||
| 330 | 316 | return coefficients; | |
| 331 | } | ||
| 332 | |||
| 333 | 3042 | void _write_field(HDF5File& file, | |
| 334 | FieldPtr field, | ||
| 335 | const std::string& path, | ||
| 336 | const HDF5::Slice& slice) const { | ||
| 337 | 3042 | const std::size_t dimension_offset = is_transient ? 1 : 0; | |
| 338 |
2/4✓ Branch 1 taken 1656 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1656 times.
✗ Branch 6 not taken.
|
6084 | std::vector<std::size_t> size(slice.total_size.value().size() + dimension_offset); |
| 339 |
1/2✓ Branch 2 taken 1656 times.
✗ Branch 3 not taken.
|
6084 | std::vector<std::size_t> count(slice.count.size() + dimension_offset); |
| 340 |
1/2✓ Branch 2 taken 1656 times.
✗ Branch 3 not taken.
|
3042 | std::vector<std::size_t> offset(slice.offset.size() + dimension_offset); |
| 341 |
5/10✓ Branch 1 taken 1656 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1656 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1656 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1656 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1656 times.
✗ Branch 14 not taken.
|
3042 | std::ranges::copy(slice.total_size.value(), std::ranges::begin(size | std::views::drop(dimension_offset))); |
| 342 |
4/8✓ Branch 1 taken 1656 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1656 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1656 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1656 times.
✗ Branch 11 not taken.
|
3042 | std::ranges::copy(slice.count, std::ranges::begin(count | std::views::drop(dimension_offset))); |
| 343 |
4/8✓ Branch 1 taken 1656 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1656 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1656 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1656 times.
✗ Branch 11 not taken.
|
3042 | std::ranges::copy(slice.offset, std::ranges::begin(offset | std::views::drop(dimension_offset))); |
| 344 | |||
| 345 |
1/2✓ Branch 2 taken 1656 times.
✗ Branch 3 not taken.
|
3042 | const auto layout = field->layout(); |
| 346 |
1/2✓ Branch 1 taken 1656 times.
✗ Branch 2 not taken.
|
3042 | const bool is_vector_field = layout.dimension() > size.size() - dimension_offset; |
| 347 |
2/2✓ Branch 0 taken 1044 times.
✓ Branch 1 taken 612 times.
|
3042 | if (is_vector_field) |
| 348 |
1/2✓ Branch 1 taken 1044 times.
✗ Branch 2 not taken.
|
1968 | std::ranges::for_each( |
| 349 |
2/4✓ Branch 1 taken 1044 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1044 times.
✗ Branch 6 not taken.
|
3936 | std::views::iota(size.size() - dimension_offset, layout.dimension()), |
| 350 | 2088 | [&] (const std::size_t codim) { | |
| 351 |
8/16✓ Branch 1 taken 340 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 340 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 572 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 572 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 76 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 76 times.
✗ Branch 19 not taken.
✓ Branch 22 taken 56 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 56 times.
✗ Branch 26 not taken.
|
1044 | size.push_back(layout.extent(codim)); |
| 352 |
8/16✓ Branch 1 taken 340 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 340 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 572 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 572 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 76 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 76 times.
✗ Branch 19 not taken.
✓ Branch 22 taken 56 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 56 times.
✗ Branch 26 not taken.
|
1044 | count.push_back(layout.extent(codim)); |
| 353 |
4/8✓ Branch 1 taken 340 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 572 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 76 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 56 times.
✗ Branch 11 not taken.
|
1044 | offset.push_back(0); |
| 354 | } | ||
| 355 | ); | ||
| 356 | |||
| 357 | if constexpr (is_transient) { | ||
| 358 |
1/2✓ Branch 1 taken 588 times.
✗ Branch 2 not taken.
|
918 | size.at(0) = 1; |
| 359 |
1/2✓ Branch 1 taken 588 times.
✗ Branch 2 not taken.
|
918 | count.at(0) = 1; |
| 360 |
1/2✓ Branch 1 taken 588 times.
✗ Branch 2 not taken.
|
918 | offset.at(0) = 0; |
| 361 |
1/2✓ Branch 2 taken 588 times.
✗ Branch 3 not taken.
|
918 | FieldPtr sub_field = transform(field, FieldTransformation::as_sub_field); |
| 362 |
1/2✓ Branch 2 taken 588 times.
✗ Branch 3 not taken.
|
918 | file.write(*sub_field, path, HDF5::Slice{ |
| 363 | 918 | .offset = std::move(offset), | |
| 364 | 918 | .count = std::move(count), | |
| 365 | 918 | .total_size = std::move(size) | |
| 366 | }); | ||
| 367 | 918 | } else { | |
| 368 |
1/2✓ Branch 2 taken 1068 times.
✗ Branch 3 not taken.
|
2124 | file.write(*field, path, HDF5::Slice{ |
| 369 | 2124 | .offset = std::move(offset), | |
| 370 | 2124 | .count = std::move(count), | |
| 371 | 2124 | .total_size = std::move(size) | |
| 372 | }); | ||
| 373 | } | ||
| 374 |
0/4✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
6084 | } |
| 375 | |||
| 376 | Communicator _comm; | ||
| 377 | std::string _timeseries_filename = ""; | ||
| 378 | VTK::HDFTransientOptions _transient_opts; | ||
| 379 | }; | ||
| 380 | |||
| 381 | /*! | ||
| 382 | * \ingroup VTK | ||
| 383 | * \brief Writer for the VTK HDF file format for image grids. | ||
| 384 | */ | ||
| 385 | template<Concepts::ImageGrid G, Concepts::Communicator C = NullCommunicator> | ||
| 386 | class VTKHDFImageGridWriter : public VTKHDFImageGridWriterImpl<false, G, C> { | ||
| 387 | using ParentType = VTKHDFImageGridWriterImpl<false, G, C>; | ||
| 388 | public: | ||
| 389 | using ParentType::ParentType; | ||
| 390 | }; | ||
| 391 | |||
| 392 | /*! | ||
| 393 | * \ingroup VTK | ||
| 394 | * \brief Writer for the transient VTK HDF file format for image grids. | ||
| 395 | */ | ||
| 396 | template<Concepts::ImageGrid G, Concepts::Communicator C = NullCommunicator> | ||
| 397 | class VTKHDFImageGridTimeSeriesWriter : public VTKHDFImageGridWriterImpl<true, G, C> { | ||
| 398 | using ParentType = VTKHDFImageGridWriterImpl<true, G, C>; | ||
| 399 | public: | ||
| 400 | using ParentType::ParentType; | ||
| 401 | }; | ||
| 402 | |||
| 403 | template<Concepts::ImageGrid G> | ||
| 404 | VTKHDFImageGridWriter(const G&) -> VTKHDFImageGridWriter<G, NullCommunicator>; | ||
| 405 | template<Concepts::ImageGrid G, Concepts::Communicator C> | ||
| 406 | VTKHDFImageGridWriter(const G&, const C&) -> VTKHDFImageGridWriter<G, C>; | ||
| 407 | |||
| 408 | template<Concepts::ImageGrid G> | ||
| 409 | VTKHDFImageGridTimeSeriesWriter(const G&, std::string, VTK::HDFTransientOptions = {}) -> VTKHDFImageGridTimeSeriesWriter<G, NullCommunicator>; | ||
| 410 | template<Concepts::ImageGrid G, Concepts::Communicator C> | ||
| 411 | VTKHDFImageGridTimeSeriesWriter(const G&, const C&, std::string, VTK::HDFTransientOptions = {}) -> VTKHDFImageGridTimeSeriesWriter<G, C>; | ||
| 412 | |||
| 413 | |||
| 414 | namespace Traits { | ||
| 415 | |||
| 416 | template<typename... Args> | ||
| 417 | struct WritesConnectivity<VTKHDFImageGridWriter<Args...>> : public std::false_type {}; | ||
| 418 | |||
| 419 | template<typename... Args> | ||
| 420 | struct WritesConnectivity<VTKHDFImageGridTimeSeriesWriter<Args...>> : public std::false_type {}; | ||
| 421 | |||
| 422 | } // namespace Traits | ||
| 423 | } // namespace GridFormat | ||
| 424 | |||
| 425 | #endif // GRIDFORMAT_HAVE_HIGH_FIVE | ||
| 426 | #endif // GRIDFORMAT_VTK_HDF_IMAGE_GRID_WRITER_HPP_ | ||
| 427 |