Wildmeshing Toolkit
link.cpp
Go to the documentation of this file.
1 #include "link.hpp"
2 
3 #include <wmtk/TetMesh.hpp>
4 #include <wmtk/TriMesh.hpp>
5 #include <wmtk/utils/Logger.hpp>
6 
7 #include "closed_star.hpp"
8 #include "faces.hpp"
11 
12 
13 namespace wmtk::simplex {
14 
15 namespace {
16 
17 void 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 
84 SimplexCollection 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 
97 SimplexCollection
98 link(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()) {
103  case PrimitiveType::Vertex: {
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 
123 SimplexCollection
124 link(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;
153  case PrimitiveType::Edge:
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 
184 SimplexCollection
185 link_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:135
PrimitiveType top_simplex_type() const
Definition: Mesh.hpp:996
Tuple switch_vertex(const Tuple &tuple) const
Definition: TetMesh.hpp:113
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.
Definition: closed_star.cpp:13
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 PV
constexpr PrimitiveType PE