GCC Code Coverage Report


Directory: gridformat/
File: gridformat/vtk/pvtr_reader.hpp
Date: 2024-11-20 14:41:59
Exec Total Coverage
Lines: 49 51 96.1%
Functions: 12 12 100.0%
Branches: 39 74 52.7%

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