Line | Branch | Exec | Source |
---|---|---|---|
1 | // SPDX-FileCopyrightText: 2022-2023 Dennis Gläser <dennis.glaeser@iws.uni-stuttgart.de> | ||
2 | // SPDX-License-Identifier: MIT | ||
3 | /*! | ||
4 | * \file | ||
5 | * \ingroup VTK | ||
6 | * \copydoc GridFormat::PVTRReader | ||
7 | */ | ||
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 | |||
17 | #include <gridformat/vtk/vtr_reader.hpp> | ||
18 | #include <gridformat/vtk/pxml_reader.hpp> | ||
19 | |||
20 | namespace GridFormat { | ||
21 | |||
22 | /*! | ||
23 | * \ingroup VTK | ||
24 | * \brief Reader for .pvtr file format | ||
25 | * \copydetails VTK::PXMLStructuredGridReader | ||
26 | */ | ||
27 | class PVTRReader : public VTK::PXMLStructuredGridReader<VTRReader> { | ||
28 | using ParentType = VTK::PXMLStructuredGridReader<VTRReader>; | ||
29 | using IndexInterval = std::array<std::size_t, 2>; | ||
30 | |||
31 | public: | ||
32 | 1 | PVTRReader() | |
33 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
2 | : ParentType("PRectilinearGrid") |
34 | 1 | {} | |
35 | |||
36 | 50 | explicit PVTRReader(const NullCommunicator&) | |
37 |
2/4✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
|
100 | : ParentType("PRectilinearGrid") |
38 | 50 | {} | |
39 | |||
40 | template<Concepts::Communicator C> | ||
41 | 84 | explicit PVTRReader(const C& comm) | |
42 |
2/4✓ Branch 2 taken 84 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 84 times.
✗ Branch 6 not taken.
|
168 | : ParentType("PRectilinearGrid", comm) |
43 | 84 | {} | |
44 | |||
45 | private: | ||
46 | 2 | std::string _name() const override { | |
47 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | return "PVTRReader"; |
48 | } | ||
49 | |||
50 | 9 | std::vector<double> _ordinates(unsigned int i) const override { | |
51 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
|
9 | if (this->_num_process_pieces() == 0) |
52 | ✗ | return {}; | |
53 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 3 times.
|
9 | if (this->_num_process_pieces() == 1) |
54 |
1/2✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
|
6 | return this->_readers().front().ordinates(i); |
55 | |||
56 | 3 | std::unordered_map<std::size_t, IndexInterval> piece_to_interval; | |
57 |
1/2✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
3 | std::ranges::for_each(this->_readers(), [&, reader_idx=0] (const GridReader& reader) mutable { |
58 |
2/4✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
|
6 | auto interval = _to_interval(reader.location(), i); |
59 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
6 | const bool should_insert = std::ranges::none_of( |
60 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
6 | piece_to_interval | std::views::values, |
61 | 3 | [&] (const auto& inserted_interval) { | |
62 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
|
3 | if (_is_same(inserted_interval, interval)) |
63 | 2 | return true; | |
64 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | else if (_overlap(inserted_interval, interval)) |
65 | ✗ | throw IOError("Cannot determine ordinates for pieces with overlapping intervals"); | |
66 | 1 | return false; | |
67 | } | ||
68 | ); | ||
69 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
|
6 | if (should_insert) |
70 |
1/2✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
4 | piece_to_interval.emplace(std::make_pair(reader_idx, std::move(interval))); |
71 | 6 | reader_idx++; | |
72 | 6 | }); | |
73 | |||
74 | |||
75 |
1/2✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
3 | std::vector<unsigned int> sorted_piece_indices(piece_to_interval.size()); |
76 |
2/4✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
|
3 | std::ranges::copy(std::views::iota(std::size_t{0}, sorted_piece_indices.size()), sorted_piece_indices.begin()); |
77 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | std::ranges::sort(sorted_piece_indices, [&] (unsigned int a, unsigned int b) { |
78 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
2 | return piece_to_interval.at(a)[0] < piece_to_interval.at(b)[0]; |
79 | }); | ||
80 | |||
81 | 3 | std::vector<double> result; | |
82 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | std::ranges::for_each(sorted_piece_indices, [&] (unsigned int piece_idx) { |
83 |
2/4✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
|
4 | auto piece_ordinates = this->_readers().at(piece_idx).ordinates(i); |
84 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
|
4 | if (result.size() > 0) |
85 | 1 | result.pop_back(); // avoid duplicate points at overlaps | |
86 |
1/2✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
4 | result.reserve(result.size() + piece_ordinates.size()); |
87 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
|
4 | std::ranges::move(std::move(piece_ordinates), std::back_inserter(result)); |
88 | 4 | }); | |
89 | 3 | return result; | |
90 | 3 | } | |
91 | |||
92 | 3 | bool _is_same(const IndexInterval& a, const IndexInterval& b) const { | |
93 | 3 | return std::ranges::equal(a, b); | |
94 | } | ||
95 | |||
96 | 1 | bool _overlap(const IndexInterval& a, const IndexInterval& b) const { | |
97 |
3/8✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
|
1 | return (a[0] < b[0] && a[1] > b[0]) || (b[0] < a[0] && b[1] > a[0]); |
98 | } | ||
99 | |||
100 | 6 | IndexInterval _to_interval(const typename ParentType::PieceLocation& loc, unsigned int i) const { | |
101 | 6 | 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_ | ||
108 |