GridFormat 0.6.0
I/O-Library for grid-like data structures
Loading...
Searching...
No Matches
pvtp_writer.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2022-2023 Dennis Gläser <dennis.glaeser@iws.uni-stuttgart.de>
2// SPDX-License-Identifier: MIT
8#ifndef GRIDFORMAT_VTK_PVTP_WRITER_HPP_
9#define GRIDFORMAT_VTK_PVTP_WRITER_HPP_
10
11#include <ostream>
12#include <string>
13#include <filesystem>
14
15#include <gridformat/common/exceptions.hpp>
16#include <gridformat/common/lvalue_reference.hpp>
17#include <gridformat/common/output_file.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>
25
26namespace GridFormat {
27
32template<Concepts::UnstructuredGrid Grid,
33 Concepts::Communicator Communicator>
34class PVTPWriter : public VTK::XMLWriterBase<Grid, PVTPWriter<Grid, Communicator>> {
36
37 public:
38 explicit PVTPWriter(LValueReferenceOf<const Grid> grid,
39 Communicator comm,
40 VTK::XMLOptions xml_opts = {})
41 : ParentType(grid.get(), ".pvtp", false, xml_opts)
42 , _comm(comm)
43 {}
44
45 const Communicator& communicator() const {
46 return _comm;
47 }
48
49 private:
50 Communicator _comm;
51
52 PVTPWriter _with(VTK::XMLOptions xml_opts) const override {
53 return PVTPWriter{this->grid(), _comm, std::move(xml_opts)};
54 }
55
56 void _write(std::ostream&) const override {
57 throw InvalidState(
58 "PVTPWriter does not support direct export into stream. "
59 "Use overload with filename instead!"
60 );
61 }
62
63 virtual void _write(const std::string& filename_with_ext) const override {
64 // the collective invocations also ensure that all pieces are written before the main file,
65 // and that the main file is written before returning
66 Parallel::invoke_collectively(_comm, [&] () {
67 _write_piece(filename_with_ext);
68 }, "Writing the pieces of '" + filename_with_ext + "'");
69 Parallel::invoke_collectively(_comm, [&] () {
70 if (Parallel::rank(_comm) == 0)
71 _write_pvtu_file(filename_with_ext);
72 }, "Writing '" + filename_with_ext + "'");
73 }
74
75 void _write_piece(const std::string& par_filename) const {
76 VTPWriter writer{this->grid(), this->_xml_opts};
77 this->copy_fields(writer);
78 writer.write(PVTK::piece_basefilename(par_filename, Parallel::rank(_comm)));
79 }
80
81 void _write_pvtu_file(const std::string& filename_with_ext) const {
82 XMLElement pvtk_xml("VTKFile");
83 pvtk_xml.set_attribute("type", "PPolyData");
84
85 XMLElement& grid = pvtk_xml.add_child("PPolyData");
86 XMLElement& ppoint_data = grid.add_child("PPointData");
87 XMLElement& pcell_data = grid.add_child("PCellData");
88 std::visit([&] (const auto& encoder) {
89 std::visit([&] (const auto& data_format) {
90 PVTK::PDataArrayHelper pdata_helper{encoder, data_format, ppoint_data};
91 PVTK::PDataArrayHelper cdata_helper{encoder, data_format, pcell_data};
92 std::ranges::for_each(this->_point_field_names(), [&] (const std::string& name) {
93 pdata_helper.add(name, this->_get_point_field(name));
94 });
95 std::ranges::for_each(this->_cell_field_names(), [&] (const std::string& name) {
96 cdata_helper.add(name, this->_get_cell_field(name));
97 });
98 }, this->_xml_settings.data_format);
99 }, this->_xml_settings.encoder);
100
101 XMLElement& point_array = grid.add_child("PPoints").add_child("PDataArray");
102 point_array.set_attribute("NumberOfComponents", "3");
103 std::visit([&] <typename T> (const Precision<T>& prec) {
104 point_array.set_attribute("type", VTK::attribute_name(prec));
105 }, this->_xml_settings.coordinate_precision);
106
107 std::ranges::for_each(Parallel::ranks(_comm), [&] (int rank) {
108 grid.add_child("Piece").set_attribute("Source", std::filesystem::path{
109 PVTK::piece_basefilename(filename_with_ext, rank) + ".vtp"
110 }.filename());
111 });
112
113 this->_set_default_active_fields(pvtk_xml.get_child("PPolyData"));
114 write_to(filename_with_ext, [&] (std::ostream& s) {
115 write_xml_with_version_header(pvtk_xml, s, Indentation{{.width = 2}});
116 });
117 }
118};
119
120template<typename G, Concepts::Communicator C>
121PVTPWriter(G&&, const C&, VTK::XMLOptions = {}) -> PVTPWriter<std::remove_cvref_t<G>, C>;
122
123} // namespace GridFormat
124
125#endif // GRIDFORMAT_VTK_PVTP_WRITER_HPP_
Helper to add a PDataArray child to an xml element.
Definition parallel.hpp:45
Writer for parallel .pvtu files.
Definition pvtp_writer.hpp:34
Base class for VTK-XML Writer implementations.
Definition xml.hpp:191
Writer for .vtu file format.
Definition vtp_writer.hpp:57
Concept for grids to be used as unstructured grids.
Definition concepts.hpp:82
Helper function for writing parallel VTK files.
std::string piece_basefilename(const std::string &par_filename, int rank)
Return the piece filename (w/o extension) for the given rank.
Definition parallel.hpp:38
Options for VTK-XML files for setting the desired encoding, data format and compression.
Definition xml.hpp:100
Writer for .vtu file format.