38 #ifndef MESH_NEIGHBOURS_
39 #define MESH_NEIGHBOURS_
49 namespace mesh_neighbours {
52 constexpr
int NONE = -1;
59 Face(
int a,
int b,
int c) {
60 std::array<int, 3> sorted {a, b, c};
62 std::sort(sorted.begin(), sorted.end());
68 friend bool operator==(
const Face &a,
const Face &b);
69 friend bool operator!=(
const Face &a,
const Face &b);
71 std::array<int, 3> nodes_;
77 Tetrahedron(
int a,
int b,
int c,
int d)
81 if (a == b || a == c || a == d) {
82 throw std::runtime_error(
"duplicate node " + std::to_string(a));
84 if (b == c || b == d) {
85 throw std::runtime_error(
"duplicate node " + std::to_string(b));
88 throw std::runtime_error(
"duplicate node " + std::to_string(c));
100 std::array<int, 4> nodes()
const {
103 int max_node()
const {
104 return *std::max_element(nodes_.begin(), nodes_.end());
106 std::array<Face, 4> faces()
const {
111 std::array<int, 4> nodes_;
112 std::array<Face, 4> faces_;
115 bool operator==(
const Tetrahedron::Face &a,
const Tetrahedron::Face &b) {
116 return a.nodes_ == b.nodes_;
119 bool operator!=(
const Tetrahedron::Face &a,
const Tetrahedron::Face &b) {
120 return a.nodes_ != b.nodes_;
129 SharedNodes(std::vector<std::vector<int>> shared_nodes) :
130 shared_nodes(std::move(shared_nodes)) {}
131 const std::vector<int> &elements_around_node(
int node)
const {
132 return shared_nodes.at(node);
135 std::vector<std::vector<int>> shared_nodes;
139 SharedNodes elements_around_nodes(
const std::vector<mesh_neighbours::Tetrahedron> &elements) {
141 for (
const auto &elt: elements) {
142 if (elt.max_node() > max_node) {
143 max_node = elt.max_node();
149 std::vector<std::vector<int>> shared_nodes(max_node + 1);
150 for (std::size_t i = 0; i < elements.size(); i++) {
151 for (
auto node: elements[i].nodes()) {
152 shared_nodes.at(node).push_back(i);
155 return SharedNodes(shared_nodes);
161 std::vector<std::array<int, 4>> tetrahedron_neighbours(
162 const std::vector<mesh_neighbours::Tetrahedron> &elements,
163 egs_mesh::internal::PercentCounter &progress) {
164 progress.start(elements.size());
165 const std::size_t NUM_FACES = 4;
166 const auto shared_nodes = mesh_neighbours::internal::elements_around_nodes(elements);
169 std::vector<std::array<int, 4>> neighbours(elements.size(), {NONE, NONE, NONE, NONE});
171 for (std::size_t i = 0; i < elements.size(); i++) {
172 auto elt_faces = elements[i].faces();
173 for (std::size_t f = 0; f < NUM_FACES; f++) {
175 if (neighbours[i][f] != NONE) {
178 auto face = elt_faces[f];
180 const auto &elts_sharing_node = shared_nodes.elements_around_node(face.node0());
181 for (
auto j: elts_sharing_node) {
182 if (j == static_cast<int>(i)) {
186 auto other_elt_faces = elements[j].faces();
187 for (std::size_t jf = 0; jf < NUM_FACES; jf++) {
188 if (face == other_elt_faces[jf]) {
189 neighbours[i][f] = j;
190 neighbours[j][jf] = i;
202 #endif // MESH_NEIGHBOURS_
Tetrahedral mesh geometry: header.