| 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 | * \copydoc GridFormat::PVTUWriter | ||
| 7 | */ | ||
| 8 | #ifndef GRIDFORMAT_VTK_PVTU_WRITER_HPP_ | ||
| 9 | #define GRIDFORMAT_VTK_PVTU_WRITER_HPP_ | ||
| 10 | |||
| 11 | #include <ostream> | ||
| 12 | #include <string> | ||
| 13 | #include <fstream> | ||
| 14 | #include <filesystem> | ||
| 15 | |||
| 16 | #include <gridformat/common/exceptions.hpp> | ||
| 17 | #include <gridformat/common/lvalue_reference.hpp> | ||
| 18 | #include <gridformat/parallel/communication.hpp> | ||
| 19 | #include <gridformat/parallel/helpers.hpp> | ||
| 20 | |||
| 21 | #include <gridformat/grid/grid.hpp> | ||
| 22 | #include <gridformat/xml/element.hpp> | ||
| 23 | #include <gridformat/vtk/vtu_writer.hpp> | ||
| 24 | #include <gridformat/vtk/parallel.hpp> | ||
| 25 | |||
| 26 | namespace GridFormat { | ||
| 27 | |||
| 28 | /*! | ||
| 29 | * \ingroup VTK | ||
| 30 | * \brief Writer for parallel .pvtu files | ||
| 31 | */ | ||
| 32 | template<Concepts::UnstructuredGrid Grid, | ||
| 33 | Concepts::Communicator Communicator> | ||
| 34 | class PVTUWriter : public VTK::XMLWriterBase<Grid, PVTUWriter<Grid, Communicator>> { | ||
| 35 | using ParentType = VTK::XMLWriterBase<Grid, PVTUWriter<Grid, Communicator>>; | ||
| 36 | |||
| 37 | public: | ||
| 38 | 323 | explicit PVTUWriter(LValueReferenceOf<const Grid> grid, | |
| 39 | Communicator comm, | ||
| 40 | VTK::XMLOptions xml_opts = {}) | ||
| 41 | 323 | : ParentType(grid.get(), ".pvtu", false, xml_opts) | |
| 42 |
2/4✓ Branch 1 taken 221 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 221 times.
✗ Branch 5 not taken.
|
969 | , _comm(comm) |
| 43 | 323 | {} | |
| 44 | |||
| 45 | 178 | const Communicator& communicator() const { | |
| 46 | 178 | return _comm; | |
| 47 | } | ||
| 48 | |||
| 49 | private: | ||
| 50 | Communicator _comm; | ||
| 51 | |||
| 52 | 70 | PVTUWriter _with(VTK::XMLOptions xml_opts) const override { | |
| 53 |
1/2✓ Branch 4 taken 70 times.
✗ Branch 5 not taken.
|
70 | return PVTUWriter{this->grid(), _comm, std::move(xml_opts)}; |
| 54 | } | ||
| 55 | |||
| 56 | ✗ | void _write(std::ostream&) const override { | |
| 57 | ✗ | throw InvalidState( | |
| 58 | "PVTUWriter does not support direct export into stream. " | ||
| 59 | "Use overload with filename instead!" | ||
| 60 | ); | ||
| 61 | } | ||
| 62 | |||
| 63 | 446 | virtual void _write(const std::string& filename_with_ext) const override { | |
| 64 | 446 | _write_piece(filename_with_ext); | |
| 65 | 442 | Parallel::barrier(_comm); // ensure all pieces finished successfully | |
| 66 |
2/2✓ Branch 1 taken 137 times.
✓ Branch 2 taken 131 times.
|
442 | if (Parallel::rank(_comm) == 0) |
| 67 | 228 | _write_pvtu_file(filename_with_ext); | |
| 68 | 442 | Parallel::barrier(_comm); // ensure .pvtu file is written before returning | |
| 69 | 442 | } | |
| 70 | |||
| 71 | 446 | void _write_piece(const std::string& par_filename) const { | |
| 72 |
1/2✓ Branch 3 taken 272 times.
✗ Branch 4 not taken.
|
446 | VTUWriter writer{this->grid(), this->_xml_opts}; |
| 73 |
1/2✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
|
446 | this->copy_fields(writer); |
| 74 |
4/6✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 272 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 268 times.
✓ Branch 8 taken 4 times.
|
450 | writer.write(PVTK::piece_basefilename(par_filename, Parallel::rank(_comm))); |
| 75 | 446 | } | |
| 76 | |||
| 77 | 228 | void _write_pvtu_file(const std::string& filename_with_ext) const { | |
| 78 |
1/2✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
|
228 | std::ofstream file_stream(filename_with_ext, std::ios::out); |
| 79 | |||
| 80 |
1/2✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
|
456 | XMLElement pvtk_xml("VTKFile"); |
| 81 |
2/4✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 137 times.
✗ Branch 5 not taken.
|
456 | pvtk_xml.set_attribute("type", "PUnstructuredGrid"); |
| 82 | |||
| 83 |
2/4✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 137 times.
✗ Branch 5 not taken.
|
456 | XMLElement& grid = pvtk_xml.add_child("PUnstructuredGrid"); |
| 84 |
2/4✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 137 times.
✗ Branch 5 not taken.
|
456 | XMLElement& ppoint_data = grid.add_child("PPointData"); |
| 85 |
2/4✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 137 times.
✗ Branch 5 not taken.
|
228 | XMLElement& pcell_data = grid.add_child("PCellData"); |
| 86 | 594 | std::visit([&] (const auto& encoder) { | |
| 87 | 503 | std::visit([&] (const auto& data_format) { | |
| 88 | 137 | PVTK::PDataArrayHelper pdata_helper{encoder, data_format, ppoint_data}; | |
| 89 | 137 | PVTK::PDataArrayHelper cdata_helper{encoder, data_format, pcell_data}; | |
| 90 |
10/96✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 95 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 95 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 19 taken 33 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 33 times.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✓ Branch 31 taken 4 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 4 times.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✓ Branch 43 taken 1 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✗ Branch 139 not taken.
✗ Branch 140 not taken.
✗ Branch 142 not taken.
✗ Branch 143 not taken.
|
1623 | std::ranges::for_each(this->_point_field_names(), [&] (const std::string& name) { |
| 91 | 502 | pdata_helper.add(name, this->_get_point_field(name)); | |
| 92 | }); | ||
| 93 |
10/96✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 95 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 95 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 19 taken 33 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 33 times.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✓ Branch 31 taken 4 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 4 times.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✓ Branch 43 taken 1 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✗ Branch 139 not taken.
✗ Branch 140 not taken.
✗ Branch 142 not taken.
✗ Branch 143 not taken.
|
1617 | std::ranges::for_each(this->_cell_field_names(), [&] (const std::string& name) { |
| 94 | 499 | cdata_helper.add(name, this->_get_cell_field(name)); | |
| 95 | }); | ||
| 96 |
6/24✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 32 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
|
137 | }, this->_xml_settings.data_format); |
| 97 |
1/2✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
|
228 | }, this->_xml_settings.encoder); |
| 98 | |||
| 99 |
4/8✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 137 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 137 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 137 times.
✗ Branch 11 not taken.
|
684 | XMLElement& point_array = grid.add_child("PPoints").add_child("PDataArray"); |
| 100 |
2/4✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 137 times.
✗ Branch 5 not taken.
|
456 | point_array.set_attribute("NumberOfComponents", "3"); |
| 101 | 366 | std::visit([&] <typename T> (const Precision<T>& prec) { | |
| 102 |
12/48✓ Branch 2 taken 101 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 101 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 101 times.
✗ Branch 9 not taken.
✓ Branch 16 taken 34 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 34 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 34 times.
✗ Branch 23 not taken.
✓ Branch 30 taken 1 times.
✗ Branch 31 not taken.
✓ Branch 33 taken 1 times.
✗ Branch 34 not taken.
✓ Branch 36 taken 1 times.
✗ Branch 37 not taken.
✓ Branch 44 taken 1 times.
✗ Branch 45 not taken.
✓ Branch 47 taken 1 times.
✗ Branch 48 not taken.
✓ Branch 50 taken 1 times.
✗ Branch 51 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
|
411 | point_array.set_attribute("type", VTK::attribute_name(prec)); |
| 103 |
1/2✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
|
228 | }, this->_xml_settings.coordinate_precision); |
| 104 | |||
| 105 |
2/4✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 137 times.
✗ Branch 5 not taken.
|
576 | std::ranges::for_each(Parallel::ranks(_comm), [&] (int rank) { |
| 106 |
20/40✓ Branch 1 taken 195 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 195 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 195 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 195 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 195 times.
✗ Branch 14 not taken.
✓ Branch 21 taken 69 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 69 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 69 times.
✗ Branch 28 not taken.
✓ Branch 30 taken 69 times.
✗ Branch 31 not taken.
✓ Branch 33 taken 69 times.
✗ Branch 34 not taken.
✓ Branch 41 taken 2 times.
✗ Branch 42 not taken.
✓ Branch 44 taken 2 times.
✗ Branch 45 not taken.
✓ Branch 47 taken 2 times.
✗ Branch 48 not taken.
✓ Branch 50 taken 2 times.
✗ Branch 51 not taken.
✓ Branch 53 taken 2 times.
✗ Branch 54 not taken.
✓ Branch 61 taken 2 times.
✗ Branch 62 not taken.
✓ Branch 64 taken 2 times.
✗ Branch 65 not taken.
✓ Branch 67 taken 2 times.
✗ Branch 68 not taken.
✓ Branch 70 taken 2 times.
✗ Branch 71 not taken.
✓ Branch 73 taken 2 times.
✗ Branch 74 not taken.
|
1608 | grid.add_child("Piece").set_attribute("Source", std::filesystem::path{ |
| 107 |
8/16✓ Branch 1 taken 195 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 195 times.
✗ Branch 5 not taken.
✓ Branch 11 taken 69 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 69 times.
✗ Branch 15 not taken.
✓ Branch 21 taken 2 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 2 times.
✗ Branch 25 not taken.
✓ Branch 31 taken 2 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 2 times.
✗ Branch 35 not taken.
|
536 | PVTK::piece_basefilename(filename_with_ext, rank) + ".vtu" |
| 108 |
4/8✓ Branch 1 taken 195 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 69 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
|
804 | }.filename()); |
| 109 | }); | ||
| 110 | |||
| 111 |
2/4✓ Branch 2 taken 137 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 137 times.
✗ Branch 6 not taken.
|
228 | this->_set_default_active_fields(pvtk_xml.get_child("PUnstructuredGrid")); |
| 112 |
2/4✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 137 times.
✗ Branch 5 not taken.
|
228 | write_xml_with_version_header(pvtk_xml, file_stream, Indentation{{.width = 2}}); |
| 113 | 228 | } | |
| 114 | }; | ||
| 115 | |||
| 116 | template<typename G, Concepts::Communicator C> | ||
| 117 | PVTUWriter(G&&, const C&, VTK::XMLOptions = {}) -> PVTUWriter<std::remove_cvref_t<G>, C>; | ||
| 118 | |||
| 119 | } // namespace GridFormat | ||
| 120 | |||
| 121 | #endif // GRIDFORMAT_VTK_PVTU_WRITER_HPP_ | ||
| 122 |