Wildmeshing Toolkit
Loading...
Searching...
No Matches
top_dimension_cofaces.cpp
Go to the documentation of this file.
5
6#include <queue>
7#include <set>
8
9#include <wmtk/EdgeMesh.hpp>
10#include <wmtk/PointMesh.hpp>
11#include <wmtk/TetMesh.hpp>
12#include <wmtk/TriMesh.hpp>
13
14namespace wmtk::simplex {
15
16namespace {
17
18
19void top_dimension_cofaces_tuples_vertex(
20 const TriMesh& mesh,
21 const Tuple& t_in,
22 std::vector<Tuple>& collection)
23{
24 assert(mesh.is_valid(t_in));
25 Tuple t = t_in;
26 do {
27 collection.emplace_back(t);
28
29 if (mesh.is_boundary_edge(t)) {
30 break;
31 }
32 t = mesh.switch_tuples(t, {PrimitiveType::Triangle, PrimitiveType::Edge});
33 } while (t != t_in);
34
35 if (t == t_in && !mesh.is_boundary_edge(t)) {
36 return;
37 }
38
39 t = mesh.switch_edge(t_in);
40
41 if (mesh.is_boundary_edge(t)) {
42 return;
43 }
44 t = mesh.switch_tuples(t, {PrimitiveType::Triangle, PrimitiveType::Edge});
45
46 do {
47 collection.emplace_back(t);
48
49 if (mesh.is_boundary_edge(t)) {
50 break;
51 }
52 t = mesh.switch_tuples(t, {PrimitiveType::Triangle, PrimitiveType::Edge});
53 } while (true);
54}
55void top_dimension_cofaces_tuples_edge(
56 const TriMesh& mesh,
57 const Tuple& t,
58 std::vector<Tuple>& collection)
59{
60 collection.emplace_back(t);
61 if (!mesh.is_boundary_edge(t)) {
62 collection.emplace_back(mesh.switch_face(t));
63 }
64}
65void top_dimension_cofaces_tuples_face(
66 const TriMesh& mesh,
67 const Tuple& t,
68 std::vector<Tuple>& collection)
69{
70 collection.emplace_back(t);
71}
72
73void top_dimension_cofaces_tuples_vertex(
74 const TetMesh& mesh,
75 const Tuple& input,
76 std::vector<Tuple>& collection)
77{
78 std::vector<int64_t> visited;
79 visited.reserve(50);
80
81 auto is_visited = [&visited](const Tuple& t) -> bool {
82 const int64_t c = t.global_cid();
83 for (const int64_t v : visited) {
84 if (v == c) {
85 return true;
86 }
87 }
88 visited.emplace_back(c);
89 return false;
90 };
91
92 std::vector<Tuple> q(200);
93 size_t q_front = 0;
94 size_t q_back = 1;
95 q[0] = input;
96
97 while (q_front != q_back) {
98 const Tuple t = q[q_front++];
99
100
101 if (is_visited(t)) {
102 continue;
103 }
104
105 collection.emplace_back(t);
106
107 if (q_back + 4 >= q.size()) {
108 q.resize(q.size() * 1.5);
109 // logger().info(
110 // "Increasing size of queue in top_dimension_cofaces_tuples_vertex to {}.",
111 // q.size());
112 // logger().info("Current collection size: {}", collection.size());
113 }
114
115 const Tuple& t1 = t;
116 const Tuple t2 = mesh.switch_face(t);
117 const Tuple t3 = mesh.switch_tuples(t, {PrimitiveType::Edge, PrimitiveType::Triangle});
118
119 if (!mesh.is_boundary_face(t1)) {
120 const Tuple ts = mesh.switch_tetrahedron(t1);
121 q[q_back++] = ts;
122 }
123 if (!mesh.is_boundary_face(t2)) {
124 const Tuple ts = mesh.switch_tetrahedron(t2);
125 q[q_back++] = ts;
126 }
127 if (!mesh.is_boundary_face(t3)) {
128 const Tuple ts = mesh.switch_tetrahedron(t3);
129 q[q_back++] = ts;
130 }
131 }
132}
133void top_dimension_cofaces_tuples_edge(
134 const TetMesh& mesh,
135 const Tuple& input,
136 std::vector<Tuple>& collection)
137{
138 // std::set<Tuple, wmtk::utils::TupleCellLessThan> touched_cells;
139 // std::queue<Tuple> q;
140 // q.push(input);
141 // while (!q.empty()) {
142 // const Tuple t = q.front();
143 // q.pop();
144 //
145 // {
146 // // check if cell already exists
147 // const auto& [it, was_inserted] = touched_cells.insert(t);
148 // if (!was_inserted) {
149 // continue;
150 // }
151 // }
152 //
153 // collection.emplace_back(t);
154 //
155 // const Tuple& t1 = t;
156 // const Tuple t2 = mesh.switch_face(t);
157 //
158 // if (!mesh.is_boundary_face(t1)) {
159 // q.push(mesh.switch_tuples(t1, {PrimitiveType::Tetrahedron, PrimitiveType::Triangle}));
160 // }
161 // if (!mesh.is_boundary_face(t2)) {
162 // q.push(mesh.switch_tetrahedron(t2));
163 // }
164 //}
165
166
167 assert(mesh.is_valid(input));
168 Tuple t = input;
169 do {
170 collection.emplace_back(t);
171
172 if (mesh.is_boundary_face(t)) {
173 break;
174 }
175 t = mesh.switch_tuples(t, {PrimitiveType::Tetrahedron, PrimitiveType::Triangle});
176 } while (t != input);
177
178 if (t == input && !mesh.is_boundary_face(t)) {
179 return;
180 }
181
182 t = input;
183
184 if (mesh.is_boundary_face(mesh.switch_face(t))) {
185 return;
186 }
187
188 t = mesh.switch_tuples(t, {PrimitiveType::Triangle, PrimitiveType::Tetrahedron});
189
190 do {
191 collection.emplace_back(t);
192
193 if (mesh.is_boundary_face(mesh.switch_face(t))) {
194 break;
195 }
196 t = mesh.switch_tuples(t, {PrimitiveType::Triangle, PrimitiveType::Tetrahedron});
197 } while (true);
198
199 // t = mesh.switch_face(input);
200
201 // if (mesh.is_boundary_face(t)) {
202 // return;
203 // }
204 // t = mesh.switch_tuples(t, {PrimitiveType::Tetrahedron, PrimitiveType::Triangle});
205
206 // do {
207 // collection.emplace_back(t);
208
209 // if (mesh.is_boundary_face(t)) {
210 // break;
211 // }
212 // t = mesh.switch_tuples(t, {PrimitiveType::Tetrahedron, PrimitiveType::Triangle});
213 // } while (true);
214}
215
216void top_dimension_cofaces_tuples_face(
217 const TetMesh& mesh,
218 const Tuple& input,
219 std::vector<Tuple>& collection)
220{
221 collection.emplace_back(input);
222 if (!mesh.is_boundary_face(input)) {
223 collection.emplace_back(mesh.switch_tetrahedron(input));
224 }
225}
226void top_dimension_cofaces_tuples_tet(
227 const TetMesh& mesh,
228 const Tuple& t,
229 std::vector<Tuple>& collection)
230{
231 collection.emplace_back(t);
232}
233
234std::vector<Tuple> top_dimension_cofaces_tuples_vertex(const TriMesh& mesh, const Tuple& t)
235{
236 std::vector<Tuple> collection;
237 top_dimension_cofaces_tuples_vertex(mesh, t, collection);
238 return collection;
239}
240std::vector<Tuple> top_dimension_cofaces_tuples_edge(const TriMesh& mesh, const Tuple& t)
241{
242 std::vector<Tuple> collection;
243 top_dimension_cofaces_tuples_edge(mesh, t, collection);
244 return collection;
245}
246std::vector<Tuple> top_dimension_cofaces_tuples_face(const TriMesh& mesh, const Tuple& t)
247{
248 std::vector<Tuple> collection;
249 top_dimension_cofaces_tuples_face(mesh, t, collection);
250 return collection;
251}
252
253std::vector<Tuple> top_dimension_cofaces_tuples_vertex(const TetMesh& mesh, const Tuple& input)
254{
255 std::vector<Tuple> collection;
256 top_dimension_cofaces_tuples_vertex(mesh, input, collection);
257 return collection;
258}
259std::vector<Tuple> top_dimension_cofaces_tuples_edge(const TetMesh& mesh, const Tuple& input)
260{
261 std::vector<Tuple> collection;
262 top_dimension_cofaces_tuples_edge(mesh, input, collection);
263 return collection;
264}
265std::vector<Tuple> top_dimension_cofaces_tuples_face(const TetMesh& mesh, const Tuple& input)
266{
267 std::vector<Tuple> collection;
268 top_dimension_cofaces_tuples_face(mesh, input, collection);
269 return collection;
270}
271std::vector<Tuple> top_dimension_cofaces_tuples_tet(const TetMesh& mesh, const Tuple& t)
272{
273 std::vector<Tuple> collection;
274 top_dimension_cofaces_tuples_tet(mesh, t, collection);
275 return collection;
276}
277
278
279} // namespace
280
281namespace {
282
283
284void top_dimension_cofaces_tuples_vertex(
285 const TriMesh& mesh,
286 const Tuple& t_in,
287 SimplexCollection& collection)
288{
289 assert(mesh.is_valid(t_in));
290 std::set<Tuple, wmtk::utils::TupleCellLessThan> touched_cells;
291 std::queue<Tuple> q;
292 q.push(t_in);
293 while (!q.empty()) {
294 const Tuple t = q.front();
295 q.pop();
296
297 {
298 // check if cell already exists
299 const auto [it, did_insert] = touched_cells.insert(t);
300 if (!did_insert) {
301 continue;
302 }
303 }
304 collection.add(PrimitiveType::Triangle, t);
305
306 if (!mesh.is_boundary_edge(t)) {
307 q.push(mesh.switch_tuples(t, {PrimitiveType::Triangle, PrimitiveType::Edge}));
308 }
309 const Tuple t_other = mesh.switch_edge(t);
310 if (!mesh.is_boundary_edge(t_other)) {
311 q.push(mesh.switch_face(t_other));
312 }
313 }
314}
315void top_dimension_cofaces_tuples_edge(
316 const TriMesh& mesh,
317 const Tuple& t,
318 SimplexCollection& collection)
319{
320 collection.add(PrimitiveType::Triangle, t);
321 if (!mesh.is_boundary_edge(t)) {
322 collection.add(PrimitiveType::Triangle, mesh.switch_face(t));
323 }
324}
325void top_dimension_cofaces_tuples_face(
326 const TriMesh& mesh,
327 const Tuple& t,
328 SimplexCollection& collection)
329{
330 collection.add(PrimitiveType::Triangle, t);
331}
332
333void top_dimension_cofaces_tuples_vertex(
334 const TetMesh& mesh,
335 const Tuple& input,
336 SimplexCollection& collection)
337{
338 std::set<Tuple, wmtk::utils::TupleCellLessThan> touched_cells;
339 std::queue<Tuple> q;
340 q.push(input);
341 while (!q.empty()) {
342 const Tuple t = q.front();
343 q.pop();
344
345 {
346 // check if cell already exists
347 const auto& [it, was_inserted] = touched_cells.insert(t);
348 if (!was_inserted) {
349 continue;
350 }
351 }
352
353 collection.add(PrimitiveType::Tetrahedron, t);
354
355 const Tuple& t1 = t;
356 const Tuple t2 = mesh.switch_face(t);
357 const Tuple t3 = mesh.switch_tuples(t, {PrimitiveType::Edge, PrimitiveType::Triangle});
358
359 if (!mesh.is_boundary_face(t1)) {
360 q.push(mesh.switch_tetrahedron(t1));
361 }
362 if (!mesh.is_boundary_face(t2)) {
363 q.push(mesh.switch_tetrahedron(t2));
364 }
365 if (!mesh.is_boundary_face(t3)) {
366 q.push(mesh.switch_tetrahedron(t3));
367 }
368 }
369}
370void top_dimension_cofaces_tuples_edge(
371 const TetMesh& mesh,
372 const Tuple& input,
373 SimplexCollection& collection)
374{
375 std::set<Tuple, wmtk::utils::TupleCellLessThan> touched_cells;
376 std::queue<Tuple> q;
377 q.push(input);
378 while (!q.empty()) {
379 const Tuple t = q.front();
380 q.pop();
381
382 {
383 // check if cell already exists
384 const auto& [it, was_inserted] = touched_cells.insert(t);
385 if (!was_inserted) {
386 continue;
387 }
388 }
389
390 collection.add(PrimitiveType::Tetrahedron, t);
391
392 const Tuple& t1 = t;
393 const Tuple t2 = mesh.switch_face(t);
394
395 if (!mesh.is_boundary_face(t1)) {
396 q.push(mesh.switch_tuples(t1, {PrimitiveType::Tetrahedron, PrimitiveType::Triangle}));
397 }
398 if (!mesh.is_boundary_face(t2)) {
399 q.push(mesh.switch_tetrahedron(t2));
400 }
401 }
402}
403
404void top_dimension_cofaces_tuples_face(
405 const TetMesh& mesh,
406 const Tuple& input,
407 SimplexCollection& collection)
408{
409 collection.add(PrimitiveType::Tetrahedron, input);
410 if (!mesh.is_boundary_face(input)) {
411 collection.add(PrimitiveType::Tetrahedron, mesh.switch_tetrahedron(input));
412 }
413}
414void top_dimension_cofaces_tuples_tet(
415 const TetMesh& mesh,
416 const Tuple& t,
417 SimplexCollection& collection)
418{
419 collection.add(PrimitiveType::Tetrahedron, t);
420}
421
422
423} // namespace
424
426 const Simplex& simplex,
427 SimplexCollection& simplex_collection,
428 const bool sort_and_clean)
429{
430 const auto& m = simplex_collection.mesh();
431 top_dimension_cofaces_tuples(m, simplex, simplex_collection);
432 if (sort_and_clean) {
433 simplex_collection.sort_and_clean();
434 }
435}
436
438 const PointMesh& mesh,
439 const Simplex& simplex,
440 SimplexCollection& collection)
441{
442 switch (simplex.primitive_type()) {
444 collection.add(simplex);
445 break;
446 }
447 case PrimitiveType::Edge: {
448 log_and_throw_error("top_dimension_cofaces_tuples not implemented for Edge in PointMesh");
449 break;
450 }
452 log_and_throw_error("top_dimension_cofaces_tuples not implemented for Face in PointMesh");
453 }
456 "top_dimension_cofaces_tuples not implemented for Tetrahedron in PointMesh");
457 default: assert(false); break;
458 }
459}
460
462 const EdgeMesh& mesh,
463 const Simplex& simplex,
464 SimplexCollection& collection)
465{
466 switch (simplex.primitive_type()) {
468 collection.add(simplex);
469 if (!mesh.is_boundary_vertex(simplex.tuple())) {
470 collection.add(simplex.primitive_type(), mesh.switch_edge(simplex.tuple()));
471 }
472 break;
473 }
474 case PrimitiveType::Edge: {
475 collection.add(simplex);
476 break;
477 }
479 log_and_throw_error("top_dimension_cofaces_tuples not implemented for Face in EdgeMesh");
480 }
482 default: assert(false); break;
483 }
484}
485
487 const TriMesh& mesh,
488 const Simplex& simplex,
489 SimplexCollection& collection)
490{
491 switch (simplex.primitive_type()) {
493 top_dimension_cofaces_tuples_vertex(mesh, simplex.tuple(), collection);
494 break;
495 }
496 case PrimitiveType::Edge: {
497 top_dimension_cofaces_tuples_edge(mesh, simplex.tuple(), collection);
498 break;
499 }
501 top_dimension_cofaces_tuples_face(mesh, simplex.tuple(), collection);
502 break;
503 }
505 default: assert(false); break;
506 }
507}
508
510 const TetMesh& mesh,
511 const Simplex& simplex,
512 SimplexCollection& collection)
513{
514 switch (simplex.primitive_type()) {
516 top_dimension_cofaces_tuples_vertex(mesh, simplex.tuple(), collection);
517 break;
518 }
519 case PrimitiveType::Edge: {
520 top_dimension_cofaces_tuples_edge(mesh, simplex.tuple(), collection);
521 break;
522 }
524 top_dimension_cofaces_tuples_face(mesh, simplex.tuple(), collection);
525 break;
526 }
528 top_dimension_cofaces_tuples_tet(mesh, simplex.tuple(), collection);
529 break;
530 }
531 default: assert(false); break;
532 }
533}
534
536 const Mesh& mesh,
537 const Simplex& simplex,
538 SimplexCollection& collection)
539{
540 switch (mesh.top_simplex_type()) {
542 top_dimension_cofaces_tuples(static_cast<const TriMesh&>(mesh), simplex, collection);
543 break;
545 top_dimension_cofaces_tuples(static_cast<const TetMesh&>(mesh), simplex, collection);
546 break;
548 top_dimension_cofaces_tuples(static_cast<const EdgeMesh&>(mesh), simplex, collection);
549 break;
551 top_dimension_cofaces_tuples(static_cast<const PointMesh&>(mesh), simplex, collection);
552 break;
553 default: log_and_throw_error("unknown mesh type in top_dimension_cofaces_tuples");
554 }
555}
556
557
559 const PointMesh& mesh,
560 const Simplex& simplex,
561 std::vector<Tuple>& collection)
562{
563 switch (simplex.primitive_type()) {
565 collection.emplace_back(simplex.tuple());
566 break;
567 }
568 case PrimitiveType::Edge: {
569 log_and_throw_error("top_dimension_cofaces_tuples not implemented for Edge in PointMesh");
570 break;
571 }
573 log_and_throw_error("top_dimension_cofaces_tuples not implemented for Face in PointMesh");
574 }
577 "top_dimension_cofaces_tuples not implemented for Tetrahedron in PointMesh");
578 default: assert(false); break;
579 }
580}
582 const EdgeMesh& mesh,
583 const Simplex& simplex,
584 std::vector<Tuple>& collection)
585{
586 switch (simplex.primitive_type()) {
588 collection.emplace_back(simplex.tuple());
589 if (!mesh.is_boundary_vertex(simplex.tuple())) {
590 collection.emplace_back(mesh.switch_edge(simplex.tuple()));
591 }
592 break;
593 }
594 case PrimitiveType::Edge: {
595 collection.emplace_back(simplex.tuple());
596 break;
597 }
599 throw std::runtime_error(
600 "top_dimension_cofaces_tuples not implemented for Face in EdgeMesh");
601 break;
602 }
604 default: assert(false); break;
605 }
606}
607
609 const TriMesh& mesh,
610 const Simplex& simplex,
611 std::vector<Tuple>& collection)
612{
613 switch (simplex.primitive_type()) {
615 collection = top_dimension_cofaces_tuples_vertex(mesh, simplex.tuple());
616 break;
617 }
618 case PrimitiveType::Edge: {
619 collection = top_dimension_cofaces_tuples_edge(mesh, simplex.tuple());
620 break;
621 }
623 collection = top_dimension_cofaces_tuples_face(mesh, simplex.tuple());
624 break;
625 }
627 default: assert(false); break;
628 }
629}
630
632 const TetMesh& mesh,
633 const Simplex& simplex,
634 std::vector<Tuple>& collection)
635{
636 switch (simplex.primitive_type()) {
638 collection = top_dimension_cofaces_tuples_vertex(mesh, simplex.tuple());
639 break;
640 }
641 case PrimitiveType::Edge: {
642 collection = top_dimension_cofaces_tuples_edge(mesh, simplex.tuple());
643 break;
644 }
646 collection = top_dimension_cofaces_tuples_face(mesh, simplex.tuple());
647 break;
648 }
650 collection = top_dimension_cofaces_tuples_tet(mesh, simplex.tuple());
651 break;
652 }
653 default: assert(false); break;
654 }
655}
656
658 const Mesh& mesh,
659 const Simplex& simplex,
660 std::vector<Tuple>& tuples)
661{
662 switch (mesh.top_simplex_type()) {
664 top_dimension_cofaces_tuples(static_cast<const TriMesh&>(mesh), simplex, tuples);
665 break;
667 top_dimension_cofaces_tuples(static_cast<const TetMesh&>(mesh), simplex, tuples);
668 break;
670 top_dimension_cofaces_tuples(static_cast<const EdgeMesh&>(mesh), simplex, tuples);
671 break;
673 top_dimension_cofaces_tuples(static_cast<const PointMesh&>(mesh), simplex, tuples);
674 break;
675 default: assert(false); //"unknown mesh type in top_dimension_cofaces_tuples"
676 }
677}
678
679
680SimplexCollection
681top_dimension_cofaces(const TriMesh& mesh, const Simplex& simplex, const bool sort_and_clean)
682{
683 SimplexCollection collection(
684 mesh,
686 mesh,
687 top_dimension_cofaces_tuples(mesh, simplex),
689 if (sort_and_clean) {
690 collection.sort_and_clean();
691 }
692
693 return collection;
694}
695
696SimplexCollection
697top_dimension_cofaces(const TetMesh& mesh, const Simplex& simplex, const bool sort_and_clean)
698{
699 SimplexCollection collection(
700 mesh,
702 mesh,
703 top_dimension_cofaces_tuples(mesh, simplex),
705 if (sort_and_clean) {
706 collection.sort_and_clean();
707 }
708
709 return collection;
710}
711
712SimplexCollection
713top_dimension_cofaces(const Mesh& mesh, const Simplex& simplex, const bool sort_and_clean)
714{
715 SimplexCollection collection(
716 mesh,
718 mesh,
719 top_dimension_cofaces_tuples(mesh, simplex),
720 mesh.top_simplex_type()));
721 if (sort_and_clean) {
722 collection.sort_and_clean();
723 }
724
725 return collection;
726}
727
728std::vector<Tuple> top_dimension_cofaces_tuples(const PointMesh& mesh, const Simplex& simplex)
729{
730 std::vector<Tuple> collection;
731 top_dimension_cofaces_tuples(mesh, simplex, collection);
732 return collection;
733}
734
735
736std::vector<Tuple> top_dimension_cofaces_tuples(const EdgeMesh& mesh, const Simplex& simplex)
737{
738 std::vector<Tuple> collection;
739 top_dimension_cofaces_tuples(mesh, simplex, collection);
740 return collection;
741}
742
743std::vector<Tuple> top_dimension_cofaces_tuples(const TriMesh& mesh, const Simplex& simplex)
744{
745 std::vector<Tuple> collection;
746 top_dimension_cofaces_tuples(mesh, simplex, collection);
747 return collection;
748}
749
750std::vector<Tuple> top_dimension_cofaces_tuples(const TetMesh& mesh, const Simplex& simplex)
751{
752 std::vector<Tuple> collection;
753 top_dimension_cofaces_tuples(mesh, simplex, collection);
754 return collection;
755}
756
757std::vector<Tuple> top_dimension_cofaces_tuples(const Mesh& mesh, const Simplex& simplex)
758{
759 switch (mesh.top_simplex_type()) {
761 return top_dimension_cofaces_tuples(static_cast<const TriMesh&>(mesh), simplex);
763 return top_dimension_cofaces_tuples(static_cast<const TetMesh&>(mesh), simplex);
765 return top_dimension_cofaces_tuples(static_cast<const EdgeMesh&>(mesh), simplex);
767 return top_dimension_cofaces_tuples(static_cast<const PointMesh&>(mesh), simplex);
768 default:
769 assert(false);
770 throw std::runtime_error("unknown mesh type in top_dimension_cofaces_tuples");
771 }
772}
773
774} // namespace wmtk::simplex
Tuple switch_edge(const Tuple &tuple) const
Definition EdgeMesh.hpp:94
bool is_boundary_vertex(const Tuple &tuple) const
Definition EdgeMesh.cpp:31
PrimitiveType top_simplex_type() const
Definition Mesh.hpp:982
void add(const Simplex &simplex)
Add simplex to the collection.
void sort_and_clean()
Sort simplex vector and remove duplicates.
const Tuple & tuple() const
Definition Simplex.hpp:53
PrimitiveType primitive_type() const
Definition Simplex.hpp:51
std::shared_ptr< Mesh > input(const std::filesystem::path &file, const bool ignore_z_if_zero, const std::vector< std::string > &tetrahedron_attributes)
Definition input.cpp:12
std::vector< Simplex > tuple_vector_to_homogeneous_simplex_vector(const Mesh &m, const std::vector< Tuple > &tups, PrimitiveType primitive)
void top_dimension_cofaces_tuples(const PointMesh &mesh, const Simplex &simplex, SimplexCollection &collection)
void top_dimension_cofaces(const Simplex &simplex, SimplexCollection &simplex_collection, const bool sort_and_clean)
Get all top dimension cofaces of the given simplex.
void log_and_throw_error(const std::string &msg)
Definition Logger.cpp:101