43 using CT = CoordinateType<Grid>;
45 static constexpr std::size_t dim = dimension<Grid>;
46 static constexpr int root_rank = 0;
49 explicit PVTIWriter(LValueReferenceOf<const Grid> grid,
52 : ParentType(grid.get(),
".pvti",
true, xml_opts)
56 const Communicator& communicator()
const {
64 return PVTIWriter{this->grid(), _comm, std::move(xml_opts)};
67 void _write(std::ostream&)
const override {
69 "PVTIWriter does not support direct export into stream. "
70 "Use overload with filename instead!"
74 virtual void _write(
const std::string& filename_with_ext)
const override {
75 const auto& local_origin = origin(this->grid());
76 const auto& local_extents = extents(this->grid());
79 const auto all_origins = Parallel::gather(_comm, local_origin, root_rank);
80 const auto all_extents = Parallel::gather(_comm, local_extents, root_rank);
81 const auto is_negative_axis = VTK::CommonDetail::structured_grid_axis_orientation(spacing(this->grid()));
82 const auto [exts_begin, exts_end, whole_extent, origin] = helper.compute_extents_and_origin(
89 const auto my_whole_extent = Parallel::broadcast(_comm, whole_extent, root_rank);
90 const auto my_whole_origin = Parallel::broadcast(_comm, origin, root_rank);
91 const auto my_extent_offset = Parallel::scatter(_comm, Ranges::flat(exts_begin), root_rank);
95 Parallel::invoke_collectively(_comm, [&] () {
96 _write_piece(filename_with_ext, Ranges::to_array<dim>(my_extent_offset), {my_whole_origin, my_whole_extent});
97 },
"Writing the pieces of '" + filename_with_ext +
"'");
98 Parallel::invoke_collectively(_comm, [&] () {
99 if (Parallel::rank(_comm) == 0)
100 _write_pvti_file(filename_with_ext, my_whole_origin, my_whole_extent, exts_begin, exts_end);
101 },
"Writing '" + filename_with_ext +
"'");
104 void _write_piece(
const std::string& par_filename,
105 const std::array<std::size_t, dim>& offset,
107 auto writer =
VTIWriter{this->grid(), this->_xml_opts}
108 .as_piece_for(std::move(domain))
109 .with_offset(offset);
110 this->copy_fields(writer);
114 void _write_pvti_file(
const std::string& filename_with_ext,
115 const std::array<CT, dim>& origin,
116 const std::array<std::size_t, dim>& extents,
117 const std::vector<std::array<std::size_t, dim>>& proc_extents_begin,
118 const std::vector<std::array<std::size_t, dim>>& proc_extents_end)
const {
119 XMLElement pvtk_xml(
"VTKFile");
120 pvtk_xml.set_attribute(
"type",
"PImageData");
122 XMLElement& grid = pvtk_xml.add_child(
"PImageData");
123 grid.set_attribute(
"WholeExtent", VTK::CommonDetail::extents_string(extents));
124 grid.set_attribute(
"Origin", VTK::CommonDetail::number_string_3d(origin));
125 grid.set_attribute(
"Spacing", VTK::CommonDetail::number_string_3d(spacing(this->grid())));
126 grid.set_attribute(
"Direction", VTK::CommonDetail::direction_string(basis(this->grid())));
128 XMLElement& ppoint_data = grid.add_child(
"PPointData");
129 XMLElement& pcell_data = grid.add_child(
"PCellData");
130 std::visit([&] (
const auto& encoder) {
131 std::visit([&] (
const auto& data_format) {
134 std::ranges::for_each(this->_point_field_names(), [&] (
const std::string& name) {
135 pdata_helper.add(name, this->_get_point_field(name));
137 std::ranges::for_each(this->_cell_field_names(), [&] (
const std::string& name) {
138 cdata_helper.add(name, this->_get_cell_field(name));
140 }, this->_xml_settings.data_format);
141 }, this->_xml_settings.encoder);
143 std::ranges::for_each(Parallel::ranks(_comm), [&] (
int rank) {
144 std::array<std::size_t, dim> extents_begin;
145 std::array<std::size_t, dim> extents_end;
146 for (
unsigned dir = 0; dir < dim; ++dir) {
147 extents_begin[dir] = proc_extents_begin[rank][dir];
148 extents_end[dir] = proc_extents_end[rank][dir];
151 auto& piece = grid.add_child(
"Piece");
152 piece.set_attribute(
"Extent", VTK::CommonDetail::extents_string(extents_begin, extents_end));
153 piece.set_attribute(
"Source", std::filesystem::path{
158 this->_set_default_active_fields(pvtk_xml.get_child(
"PImageData"));
159 write_to(filename_with_ext, [&] (std::ostream& s) {
160 write_xml_with_version_header(pvtk_xml, s, Indentation{{.width = 2}});