GCC Code Coverage Report


Directory: src/oiseau/
File: src/oiseau/mesh/topology.cpp
Date: 2025-05-24 01:28:39
Exec Total Coverage
Lines: 4 41 9.8%
Functions: 3 9 33.3%
Branches: 0 48 0.0%

Line Branch Exec Source
1 // Copyright (C) 2025 Tiago V. L. Amorim (@tiagovla)
2 //
3 // This file is part of oiseau (https://github.com/tiagovla/oiseau)
4 //
5 // SPDX-License-Identifier: GPL-3.0-or-later
6
7 #include "oiseau/mesh/topology.hpp"
8
9 #include <algorithm>
10 #include <cstddef>
11 #include <numeric>
12 #include <span>
13 #include <utility>
14 #include <vector>
15 #include <xtensor/containers/xadapt.hpp>
16
17 #include "oiseau/mesh/cell.hpp"
18
19 using namespace oiseau::mesh;
20
21 Topology::Topology() = default;
22 4 Topology::~Topology() = default;
23
24 2 Topology::Topology(std::vector<std::vector<std::size_t>>&& conn, std::vector<CellType>&& cell_types)
25 2 : m_conn(std::move(conn)), m_cell_types(std::move(cell_types)) {};
26
27 std::span<CellType> Topology::cell_types() { return m_cell_types; };
28
29 2 std::span<std::vector<std::size_t>> Topology::conn() { return m_conn; };
30 std::span<std::vector<std::size_t>> Topology::e_to_e() { return m_e_to_e; };
31 std::span<std::vector<std::size_t>> Topology::e_to_f() { return m_e_to_f; };
32
33 std::size_t Topology::n_cells() const { return m_conn.size(); }
34
35 void Topology::calculate_connectivity() {
36 // this should be extended to 3d and for mixed cells squares/triangles
37 std::vector<std::vector<std::vector<std::size_t>>> faces;
38 for (std::size_t i = 0; i < m_conn.size(); i++) {
39 auto cell = m_cell_types[i];
40 if (cell->kind() != CellKind::Triangle) continue;
41 auto _conn = m_conn[i];
42
43 auto face_vertices = cell->get_entity_vertices(1);
44 std::vector<std::vector<std::size_t>> face(face_vertices.size());
45 for (std::size_t j = 0; j < face_vertices.size(); j++) {
46 face[j].resize(face_vertices[j].size());
47 for (std::size_t k = 0; k < face_vertices[j].size(); k++) {
48 face[j][k] = _conn[face_vertices[j][k]];
49 }
50 std::sort(face[j].begin(), face[j].end());
51 }
52 faces.push_back(std::move(face));
53 }
54 m_e_to_e.resize(faces.size());
55 m_e_to_f.resize(faces.size());
56 for (std::size_t i = 0; i < m_e_to_e.size(); i++) {
57 m_e_to_e[i] = std::vector<std::size_t>(faces[i].size(), i);
58 m_e_to_f[i].resize(faces[i].size());
59 std::iota(m_e_to_f[i].begin(), m_e_to_f[i].end(), 0);
60 }
61
62 // TODO(tiagovla): this is not efficient, should use a hash map
63 for (std::size_t i = 0; i < faces.size(); i++) {
64 for (std::size_t j = 0; j < faces[i].size(); j++) {
65 for (std::size_t ii = i + 1; ii < faces.size(); ii++) {
66 for (std::size_t jj = 0; jj < faces[ii].size(); jj++) {
67 if (m_e_to_e[i][j] != i || m_e_to_e[ii][jj] != ii) continue;
68 if (faces[i][j] == faces[ii][jj]) {
69 m_e_to_e[i][j] = ii;
70 m_e_to_e[ii][jj] = i;
71 m_e_to_f[i][j] = jj;
72 m_e_to_f[ii][jj] = j;
73 }
74 }
75 }
76 }
77 }
78 }
79