8#ifndef GRIDFORMAT_VTK_PVTR_READER_HPP_
9#define GRIDFORMAT_VTK_PVTR_READER_HPP_
12#include <unordered_map>
29 using IndexInterval = std::array<std::size_t, 2>;
40 template<Concepts::Communicator C>
46 std::string _name()
const override {
50 std::vector<double> _ordinates(
unsigned int i)
const override {
51 if (this->_num_process_pieces() == 0)
53 if (this->_num_process_pieces() == 1)
54 return this->_readers().front().ordinates(i);
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))
64 else if (_overlap(inserted_interval, interval))
65 throw IOError(
"Cannot determine ordinates for pieces with overlapping intervals");
70 piece_to_interval.emplace(std::make_pair(reader_idx, std::move(interval)));
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];
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)
86 result.reserve(result.size() + piece_ordinates.size());
87 std::ranges::move(std::move(piece_ordinates), std::back_inserter(result));
92 bool _is_same(
const IndexInterval& a,
const IndexInterval& b)
const {
93 return std::ranges::equal(a, b);
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]);
101 return {loc.lower_left.at(i), loc.upper_right.at(i)};