GridFormat 0.4.0
I/O-Library for grid-like data structures
Loading...
Searching...
No Matches
pvtr_reader.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_PVTR_READER_HPP_
9#define GRIDFORMAT_VTK_PVTR_READER_HPP_
10
11#include <algorithm>
12#include <unordered_map>
13#include <vector>
14#include <ranges>
15#include <array>
16
19
20namespace GridFormat {
21
27class PVTRReader : public VTK::PXMLStructuredGridReader<VTRReader> {
29 using IndexInterval = std::array<std::size_t, 2>;
30
31 public:
33 : ParentType("PRectilinearGrid")
34 {}
35
36 explicit PVTRReader(const NullCommunicator&)
37 : ParentType("PRectilinearGrid")
38 {}
39
40 template<Concepts::Communicator C>
41 explicit PVTRReader(const C& comm)
42 : ParentType("PRectilinearGrid", comm)
43 {}
44
45 private:
46 std::string _name() const override {
47 return "PVTRReader";
48 }
49
50 std::vector<double> _ordinates(unsigned int i) const override {
51 if (this->_num_process_pieces() == 0)
52 return {};
53 if (this->_num_process_pieces() == 1)
54 return this->_readers().front().ordinates(i);
55
56 std::unordered_map<std::size_t, IndexInterval> piece_to_interval;
57 std::ranges::for_each(this->_readers(), [&, reader_idx=0] (const GridReader& reader) mutable {
58 auto interval = _to_interval(reader.location(), i);
59 const bool should_insert = std::ranges::none_of(
60 piece_to_interval | std::views::values,
61 [&] (const auto& inserted_interval) {
62 if (_is_same(inserted_interval, interval))
63 return true;
64 else if (_overlap(inserted_interval, interval))
65 throw IOError("Cannot determine ordinates for pieces with overlapping intervals");
66 return false;
67 }
68 );
69 if (should_insert)
70 piece_to_interval.emplace(std::make_pair(reader_idx, std::move(interval)));
71 reader_idx++;
72 });
73
74
75 std::vector<unsigned int> sorted_piece_indices(piece_to_interval.size());
76 std::ranges::copy(std::views::iota(std::size_t{0}, sorted_piece_indices.size()), sorted_piece_indices.begin());
77 std::ranges::sort(sorted_piece_indices, [&] (unsigned int a, unsigned int b) {
78 return piece_to_interval.at(a)[0] < piece_to_interval.at(b)[0];
79 });
80
81 std::vector<double> result;
82 std::ranges::for_each(sorted_piece_indices, [&] (unsigned int piece_idx) {
83 auto piece_ordinates = this->_readers().at(piece_idx).ordinates(i);
84 if (result.size() > 0)
85 result.pop_back(); // avoid duplicate points at overlaps
86 result.reserve(result.size() + piece_ordinates.size());
87 std::ranges::move(std::move(piece_ordinates), std::back_inserter(result));
88 });
89 return result;
90 }
91
92 bool _is_same(const IndexInterval& a, const IndexInterval& b) const {
93 return std::ranges::equal(a, b);
94 }
95
96 bool _overlap(const IndexInterval& a, const IndexInterval& b) const {
97 return (a[0] < b[0] && a[1] > b[0]) || (b[0] < a[0] && b[1] > a[0]);
98 }
99
100 IndexInterval _to_interval(const typename ParentType::PieceLocation& loc, unsigned int i) const {
101 return {loc.lower_left.at(i), loc.upper_right.at(i)};
102 }
103};
104
105} // namespace GridFormat
106
107#endif // GRIDFORMAT_VTK_PVTR_READER_HPP_
Abstract base class for all readers, defines the common interface.
Definition: reader.hpp:51
PieceLocation location() const
Return the location of this piece in a structured grid (only available for structured grid formats)
Definition: reader.hpp:123
Reader for .pvtr file format.
Definition: pvtr_reader.hpp:27
Base class for readers of parallel vtk-xml file formats for structured grids.
Definition: pxml_reader.hpp:294
Describes the location of a piece within a distributed structured grid.
Definition: reader.hpp:57