Wildmeshing Toolkit
Loading...
Searching...
No Matches
link.cpp
Go to the documentation of this file.
1#include "link.hpp"
2
3#include <wmtk/TetMesh.hpp>
4#include <wmtk/TriMesh.hpp>
6
7#include "closed_star.hpp"
8#include "faces.hpp"
11
12
13namespace wmtk::simplex {
14
15namespace {
16
17void link_vertex(
18 const TriMesh& mesh,
19 const simplex::Simplex& simplex,
20 std::vector<Simplex>& collection)
21{
25
26 assert(mesh.is_valid(simplex.tuple()));
27 const Tuple t_in = simplex.tuple();
28 Tuple t = t_in;
29
30 do {
31 const Tuple t_collect = mesh.switch_tuples(t, {PV, PE});
32 collection.emplace_back(simplex::Simplex(mesh, PV, t_collect));
33 collection.emplace_back(simplex::Simplex(mesh, PE, t_collect));
34
35 if (mesh.is_boundary_edge(t)) {
36 break;
37 }
38 t = mesh.switch_tuples(t, {PF, PE});
39 } while (t != t_in);
40
41
42 if (t == t_in && !mesh.is_boundary_edge(t)) {
43 return;
44 }
45
46 t = mesh.switch_edge(t_in);
47
48 collection.emplace_back(simplex::Simplex(mesh, PV, mesh.switch_tuple(t, PV)));
49 if (mesh.is_boundary_edge(t)) {
50 return;
51 }
52 t = mesh.switch_tuples(t, {PF, PE});
53
54 do {
55 const Tuple t_collect = mesh.switch_tuples(t, {PV, PE});
56 collection.emplace_back(simplex::Simplex(mesh, PV, t_collect));
57 collection.emplace_back(simplex::Simplex(mesh, PE, t_collect));
58
59 if (mesh.is_boundary_edge(t)) {
60 break;
61 }
62 t = mesh.switch_tuples(t, {PF, PE});
63 } while (true);
64}
65
66// void link_edge(
67// const TriMesh& mesh,
68// const simplex::Simplex& simplex,
69// std::vector<Simplex>& collection)
70// {
71// constexpr PrimitiveType PV = PrimitiveType::Vertex;
72// constexpr PrimitiveType PE = PrimitiveType::Edge;
73// constexpr PrimitiveType PF = PrimitiveType::Triangle;
74// const Tuple& t = simplex.tuple();
75
76// collection.emplace_back(simplex::Simplex(mesh, PV, mesh.switch_tuples(t, {PE, PV})));
77// if (!mesh.is_boundary_edge(t)) {
78// collection.emplace_back(simplex::Simplex(mesh, PV, mesh.switch_tuples(t, {PF, PE, PV})));
79// }
80// }
81
82} // namespace
83
84SimplexCollection link(const Mesh& mesh, const simplex::Simplex& simplex, const bool sort_and_clean)
85{
86 switch (mesh.top_simplex_type()) {
88 return link(static_cast<const TriMesh&>(mesh), simplex, sort_and_clean);
90 return link(static_cast<const TetMesh&>(mesh), simplex, sort_and_clean);
93 default: return link_slow(mesh, simplex, sort_and_clean); break;
94 }
95}
96
97SimplexCollection
98link(const TriMesh& mesh, const simplex::Simplex& simplex, const bool sort_and_clean)
99{
100 // make use of the fact that the top dimension coface tuples always contain the simplex itself
101
102 switch (simplex.primitive_type()) {
104 std::vector<Simplex> link_simplices;
105 link_vertex(mesh, simplex, link_simplices);
106 SimplexCollection collection(mesh, std::move(link_simplices));
107 if (sort_and_clean) {
108 collection.sort();
109 }
110 return collection;
111 }
112 case PrimitiveType::Edge: {
113 return link_single_dimension(mesh, simplex, PrimitiveType::Vertex, sort_and_clean);
114 }
115 case PrimitiveType::Triangle: break;
117 default: log_and_throw_error("Unknown primitive type in open_star."); break;
118 }
119
120 return SimplexCollection(mesh);
121}
122
123SimplexCollection
124link(const TetMesh& mesh, const simplex::Simplex& simplex, const bool sort_and_clean)
125{
126 // make use of the fact that the top dimension coface tuples always contain the simplex itself
127 const std::vector<Tuple> cell_tuples = top_dimension_cofaces_tuples(mesh, simplex);
128
133
134 std::vector<Simplex> all_cofaces;
135 switch (simplex.primitive_type()) {
137 all_cofaces.reserve(cell_tuples.size() * 7);
138 for (Tuple t : cell_tuples) {
139 t = mesh.switch_tuples(t, {PV, PE, PF});
140
141 all_cofaces.emplace_back(Simplex::face(mesh, t));
142
143 all_cofaces.emplace_back(Simplex::edge(mesh, t));
144 all_cofaces.emplace_back(Simplex::vertex(mesh, t));
145 t = mesh.switch_tuples(t, {PV, PE});
146 all_cofaces.emplace_back(Simplex::edge(mesh, t));
147 all_cofaces.emplace_back(Simplex::vertex(mesh, t));
148 t = mesh.switch_tuples(t, {PV, PE});
149 all_cofaces.emplace_back(Simplex::edge(mesh, t));
150 all_cofaces.emplace_back(Simplex::vertex(mesh, t));
151 }
152 break;
154 all_cofaces.reserve(cell_tuples.size() * 3);
155 for (Tuple t : cell_tuples) {
156 t = mesh.switch_tuples(t, {PE, PV, PF, PE});
157
158 all_cofaces.emplace_back(Simplex::edge(mesh, t));
159 all_cofaces.emplace_back(Simplex::vertex(mesh, t));
160 all_cofaces.emplace_back(Simplex::vertex(mesh, mesh.switch_vertex(t)));
161 }
162 break;
164 all_cofaces.reserve(cell_tuples.size() * 7);
165 for (Tuple t : cell_tuples) {
166 t = mesh.switch_tuples(t, {PE, PF, PE, PV});
167
168 all_cofaces.emplace_back(Simplex::vertex(mesh, t));
169 }
170 break;
171 case PrimitiveType::Tetrahedron: break;
172 default: log_and_throw_error("Unknown primitive type in open_star."); break;
173 }
174
175 SimplexCollection collection(mesh, std::move(all_cofaces));
176
177 if (sort_and_clean) {
178 collection.sort_and_clean();
179 }
180
181 return collection;
182}
183
184SimplexCollection
185link_slow(const Mesh& mesh, const simplex::Simplex& simplex, const bool sort_and_clean)
186{
187 SimplexCollection collection(mesh);
188
189 SimplexCollection cs = closed_star(mesh, simplex, sort_and_clean);
190
191 SimplexCollection simplex_w_bd = faces(mesh, simplex, false);
192 simplex_w_bd.add(simplex);
193 simplex_w_bd.sort_and_clean();
194
195 for (const Simplex& s : cs.simplex_vector()) {
196 SimplexCollection bd = faces(mesh, s, false);
197 bd.add(s);
198 bd.sort_and_clean();
199 SimplexCollection intersection = SimplexCollection::get_intersection(simplex_w_bd, bd);
200 if (intersection.simplex_vector().empty()) {
201 collection.add(s);
202 }
203 }
204
205 return collection;
206}
207
208} // namespace wmtk::simplex
Tuple switch_tuples(const Tuple &tuple, const ContainerType &op_sequence) const
Performs a sequence of switch_tuple operations in the order specified in op_sequence.
Definition MeshCRTP.hpp:136
PrimitiveType top_simplex_type() const
Definition Mesh.hpp:982
Tuple switch_vertex(const Tuple &tuple) const
Definition TetMesh.hpp:113
The Tuple is the basic navigation tool in our mesh data structure.
Definition Tuple.hpp:19
void add(const Simplex &simplex)
Add simplex to the collection.
const std::vector< Simplex > & simplex_vector() const
Return const reference to the simplex vector.
static SimplexCollection get_intersection(const SimplexCollection &collection_a, const SimplexCollection &collection_b)
Get intersection of two simplex collections.
void sort_and_clean()
Sort simplex vector and remove duplicates.
static Simplex face(const Mesh &m, const Tuple &t)
Definition Simplex.hpp:63
static Simplex edge(const Mesh &m, const Tuple &t)
Definition Simplex.hpp:61
static Simplex vertex(const Mesh &m, const Tuple &t)
Definition Simplex.hpp:56
PrimitiveType primitive_type() const
Definition Simplex.hpp:51
constexpr wmtk::PrimitiveType PT
constexpr wmtk::PrimitiveType PF
void top_dimension_cofaces_tuples(const PointMesh &mesh, const Simplex &simplex, SimplexCollection &collection)
SimplexCollection closed_star(const Mesh &mesh, const Simplex &simplex, const bool sort_and_clean)
The closed star contains the input simplex, all its top dimension cofaces, and their faces.
SimplexCollection link(const Mesh &mesh, const simplex::Simplex &simplex, const bool sort_and_clean)
Definition link.cpp:84
SimplexCollection link_slow(const Mesh &mesh, const simplex::Simplex &simplex, const bool sort_and_clean)
Definition link.cpp:185
SimplexCollection link_single_dimension(const Mesh &mesh, const simplex::Simplex &simplex, const PrimitiveType link_type, const bool sort_and_clean)
SimplexCollection faces(const Mesh &mesh, const Simplex &simplex, const bool sort_and_clean)
Returns all faces of a simplex.
Definition faces.cpp:10
void log_and_throw_error(const std::string &msg)
Definition Logger.cpp:101
constexpr PrimitiveType PE
constexpr PrimitiveType PV