8#ifndef GRIDFORMAT_VTK_PVTU_WRITER_HPP_
9#define GRIDFORMAT_VTK_PVTU_WRITER_HPP_
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>
21#include <gridformat/grid/grid.hpp>
22#include <gridformat/xml/element.hpp>
32template<Concepts::UnstructuredGrid Grid,
33 Concepts::Communicator Communicator>
38 explicit PVTUWriter(LValueReferenceOf<const Grid> grid,
41 :
ParentType(grid.get(),
".pvtu",
false, xml_opts)
45 const Communicator& communicator()
const {
53 return PVTUWriter{this->grid(), _comm, std::move(xml_opts)};
56 void _write(std::ostream&)
const override {
58 "PVTUWriter does not support direct export into stream. "
59 "Use overload with filename instead!"
63 virtual void _write(
const std::string& filename_with_ext)
const override {
64 _write_piece(filename_with_ext);
65 Parallel::barrier(_comm);
66 if (Parallel::rank(_comm) == 0)
67 _write_pvtu_file(filename_with_ext);
68 Parallel::barrier(_comm);
71 void _write_piece(
const std::string& par_filename)
const {
72 VTUWriter writer{this->grid(), this->_xml_opts};
73 this->copy_fields(writer);
74 writer.write(PVTK::piece_basefilename(par_filename, Parallel::rank(_comm)));
77 void _write_pvtu_file(
const std::string& filename_with_ext)
const {
78 std::ofstream file_stream(filename_with_ext, std::ios::out);
80 XMLElement pvtk_xml(
"VTKFile");
81 pvtk_xml.set_attribute(
"type",
"PUnstructuredGrid");
83 XMLElement& grid = pvtk_xml.add_child(
"PUnstructuredGrid");
84 XMLElement& ppoint_data = grid.add_child(
"PPointData");
85 XMLElement& pcell_data = grid.add_child(
"PCellData");
86 std::visit([&] (
const auto& encoder) {
87 std::visit([&] (
const auto& data_format) {
90 std::ranges::for_each(this->_point_field_names(), [&] (
const std::string& name) {
91 pdata_helper.add(name, this->_get_point_field(name));
93 std::ranges::for_each(this->_cell_field_names(), [&] (
const std::string& name) {
94 cdata_helper.add(name, this->_get_cell_field(name));
96 }, this->_xml_settings.data_format);
97 }, this->_xml_settings.encoder);
99 XMLElement& point_array = grid.add_child(
"PPoints").add_child(
"PDataArray");
100 point_array.set_attribute(
"NumberOfComponents",
"3");
101 std::visit([&] <
typename T> (
const Precision<T>& prec) {
102 point_array.set_attribute(
"type", VTK::attribute_name(prec));
103 }, this->_xml_settings.coordinate_precision);
105 std::ranges::for_each(Parallel::ranks(_comm), [&] (
int rank) {
106 grid.add_child(
"Piece").set_attribute(
"Source", std::filesystem::path{
107 PVTK::piece_basefilename(filename_with_ext, rank) +
".vtu"
111 this->_set_default_active_fields(pvtk_xml.get_child(
"PUnstructuredGrid"));
112 write_xml_with_version_header(pvtk_xml, file_stream, Indentation{{.width = 2}});
116template<
typename G, Concepts::Communicator C>
Helper function for writing parallel VTK files.