Wildmeshing Toolkit
Loading...
Searching...
No Matches
TetMesh.h
1#pragma once
2
3#include <wmtk/utils/VectorUtils.h>
4#include <wmtk/AttributeCollection.hpp>
5#include <wmtk/Types.hpp>
6#include <wmtk/simplex/Simplex.hpp>
7#include <wmtk/simplex/SimplexCollection.hpp>
8#include <wmtk/utils/Logger.hpp>
9
10#include <tbb/concurrent_vector.h>
11#include <tbb/enumerable_thread_specific.h>
12#include <tbb/spin_mutex.h>
13
14#include <array>
15#include <cassert>
16#include <limits>
17#include <map>
18#include <optional>
19#include <vector>
20
21namespace wmtk {
23{
24private:
29 static constexpr std::array<std::array<int, 2>, 6> m_local_edges = {
30 {{{0, 1}}, {{1, 2}}, {{0, 2}}, {{0, 3}}, {{1, 3}}, {{2, 3}}}};
31
32 static constexpr std::array<int, 4> m_map_vertex2edge = {{0, 0, 1, 3}};
33 static constexpr std::array<int, 4> m_map_vertex2oppo_face = {{3, 1, 2, 0}};
34 static constexpr std::array<int, 6> m_map_edge2face = {{0, 0, 0, 1, 2, 1}};
35 static constexpr std::array<std::array<int, 3>, 4> m_local_faces = {
36 {{{0, 1, 2}}, {{0, 2, 3}}, {{0, 1, 3}}, {{1, 2, 3}}}}; // sorted local vids
37 static constexpr std::array<std::array<int, 3>, 4> m_local_edges_in_a_face = {
38 {{{0, 1, 2}}, {{2, 5, 3}}, {{3, 4, 0}}, {{5, 1, 4}}}};
39
40public:
41 // Cell Tuple Navigator
47 class Tuple
48 {
49 size_t m_global_vid = std::numeric_limits<size_t>::max();
50 size_t m_local_eid = std::numeric_limits<size_t>::max();
51 size_t m_local_fid = std::numeric_limits<size_t>::max();
52 size_t m_global_tid = std::numeric_limits<size_t>::max();
53
54 int m_hash = 0;
55
56 private:
66 Tuple(const TetMesh& m, size_t vid, size_t local_eid, size_t local_fid, size_t tid);
67
68 public:
69 Tuple() {}
70
71 friend TetMesh;
72
80 bool is_valid(const TetMesh& m) const;
87 bool is_boundary_edge(const TetMesh& m) const;
94 bool is_boundary_face(const TetMesh& m) const;
95
100 void print_info() const;
101
107 void print_info(const TetMesh& m) const;
108
114 size_t vid(const TetMesh& m) const;
115
124 size_t eid(const TetMesh& m) const;
125
133 size_t fid(const TetMesh& m) const;
134
141 size_t tid(const TetMesh& m) const;
142
149 Tuple switch_vertex(const TetMesh& m) const;
156 Tuple switch_edge(const TetMesh& m) const;
163 Tuple switch_face(const TetMesh& m) const;
164
172 std::optional<Tuple> switch_tetrahedron(const TetMesh& m) const;
173 std::optional<Tuple> switch_tetrahedron_slow(const TetMesh& m) const;
174
175
177
180 void check_validity(const TetMesh& m) const;
181 friend bool operator==(const Tuple& a, const Tuple& t)
182 {
183 return (
184 std::tie(a.m_global_vid, a.m_local_eid, a.m_local_fid, a.m_global_tid, a.m_hash) ==
185 std::tie(t.m_global_vid, t.m_local_eid, t.m_local_fid, t.m_global_tid, t.m_hash));
186 }
187 friend bool operator<(const Tuple& a, const Tuple& t)
188 {
189 return (
190 std::tie(a.m_global_vid, a.m_local_eid, a.m_local_fid, a.m_global_tid, a.m_hash) <
191 std::tie(t.m_global_vid, t.m_local_eid, t.m_local_fid, t.m_global_tid, t.m_hash));
192 }
193 };
194
200 {
201 Tuple m_tuple;
202 const TetMesh& m_mesh;
203
204 public:
205 SmartTuple(const TetMesh& mesh, const Tuple& t)
206 : m_mesh(mesh)
207 , m_tuple(t)
208 {}
209
210 const Tuple& tuple() { return m_tuple; }
211 const TetMesh& mesh() { return m_mesh; }
212
213 SmartTuple& operator=(const SmartTuple& t)
214 {
215 m_tuple = t.m_tuple;
216 return *this;
217 }
218
219 bool is_valid() const { return m_tuple.is_valid(m_mesh); }
220 bool is_boundary_edge() const { return m_tuple.is_boundary_edge(m_mesh); }
221 bool is_boundary_face() const { return m_tuple.is_boundary_face(m_mesh); }
222 size_t vid() const { return m_tuple.vid(m_mesh); }
223 size_t eid() const { return m_tuple.eid(m_mesh); }
224 size_t fid() const { return m_tuple.fid(m_mesh); }
225 size_t tid() const { return m_tuple.tid(m_mesh); }
226 SmartTuple switch_vertex() const { return {m_mesh, m_tuple.switch_vertex(m_mesh)}; }
227 SmartTuple switch_edge() const { return {m_mesh, m_tuple.switch_edge(m_mesh)}; }
228 SmartTuple switch_face() const { return {m_mesh, m_tuple.switch_face(m_mesh)}; }
229 std::optional<SmartTuple> switch_tetrahedron() const
230 {
231 const std::optional<Tuple> t = m_tuple.switch_tetrahedron(m_mesh);
232 if (t) {
233 return std::optional<SmartTuple>({m_mesh, t.value()});
234 }
235 return {};
236 }
237 void check_validity() const { return m_tuple.check_validity(m_mesh); }
238 };
239
246 {
247 public:
248 std::vector<size_t> m_conn_tets; // todo: always keep it sorted
249 bool m_is_removed = false;
250
251 size_t& operator[](const size_t index)
252 {
253 assert(index < m_conn_tets.size());
254 return m_conn_tets[index];
255 }
256
257 size_t operator[](const size_t index) const
258 {
259 assert(index < m_conn_tets.size());
260 return m_conn_tets[index];
261 }
262
263 friend bool operator==(const VertexConnectivity& l, const VertexConnectivity& r)
264 {
265 return std::tie(l.m_conn_tets, l.m_is_removed) ==
266 std::tie(r.m_conn_tets, r.m_is_removed); // keep the same order
267 }
268
269 void print_info() {}
270 };
271
277 {
278 public:
279 std::array<size_t, 4> m_indices;
280 bool m_is_removed = false;
281
282 int hash = 0;
283
284 size_t& operator[](size_t index)
285 {
286 assert(index < 4);
287 return m_indices[index];
288 }
289
290 size_t operator[](size_t index) const
291 {
292 assert(index < 4);
293 return m_indices[index];
294 }
295
296 int find(size_t v_id) const
297 {
298 for (int j = 0; j < 4; j++) {
299 if (v_id == m_indices[j]) return j;
300 }
301 return -1;
302 }
303
304 int find_local_edge(size_t v1_id, size_t v2_id) const
305 {
306 std::array<int, 2> e;
307 for (int j = 0; j < 4; j++) {
308 if (v1_id == m_indices[j])
309 e[0] = j;
310 else if (v2_id == m_indices[j])
311 e[1] = j;
312 }
313 if (e[0] > e[1]) std::swap(e[0], e[1]);
314 int i =
315 std::find(m_local_edges.begin(), m_local_edges.end(), e) - m_local_edges.begin();
316 if (i >= m_local_edges.size()) return -1;
317 return i;
318 }
319
320 int find_local_face(size_t v1_id, size_t v2_id, size_t v3_id) const
321 {
322 std::array<int, 3> f;
323 for (int j = 0; j < 4; j++) {
324 if (v1_id == m_indices[j])
325 f[0] = j;
326 else if (v2_id == m_indices[j])
327 f[1] = j;
328 else if (v3_id == m_indices[j])
329 f[2] = j;
330 }
331 std::sort(f.begin(), f.end());
332 int i =
333 std::find(m_local_faces.begin(), m_local_faces.end(), f) - m_local_faces.begin();
334 if (i >= m_local_edges.size()) return -1;
335 return i;
336 }
337
338 friend bool operator==(const TetrahedronConnectivity& l, const TetrahedronConnectivity& r)
339 {
340 return std::tie(l.m_indices, l.m_is_removed, l.hash) ==
341 std::tie(r.m_indices, r.m_is_removed, r.hash); // keep the same order
342 }
343
344 void print_info() {}
345 };
346
347 TetMesh();
348 virtual ~TetMesh() = default;
354 size_t vert_capacity() const { return current_vert_size; }
360 size_t tet_capacity() const { return current_tet_size; }
361
366 size_t vertex_size() const
367 {
368 int cnt = 0;
369 for (auto i = 0; i < vert_capacity(); i++) {
370 if (!m_vertex_connectivity[i].m_is_removed) cnt++;
371 }
372 return cnt;
373 }
378 size_t tet_size() const
379 {
380 int cnt = 0;
381 for (auto i = 0; i < tet_capacity(); i++) {
382 if (!m_tet_connectivity[i].m_is_removed) cnt++;
383 }
384 return cnt;
385 }
395 void init(size_t n_vertices, const std::vector<std::array<size_t, 4>>& tets);
396 void init_with_isolated_vertices(
397 size_t n_vertices,
398 const std::vector<std::array<size_t, 4>>& tets);
399
405 void init(const MatrixXi& T);
406
414 bool split_edge(const Tuple& t, std::vector<Tuple>& new_tets);
422 virtual bool collapse_edge(const Tuple& t, std::vector<Tuple>& new_tets);
423
424 bool link_condition(const Tuple& t);
425
444 const Tuple& loc0,
445 std::vector<Tuple>& new_edges,
446 size_t& v1_id,
447 Tuple& new_loc,
448 std::map<size_t, wmtk::TetMesh::VertexConnectivity>& rollback_vert_conn,
449 std::vector<size_t>& n1_t_ids_copy,
450 std::vector<size_t>& new_tet_id,
451 std::vector<TetrahedronConnectivity>& old_tets);
452
461 bool collapse_edge_check_topology(const std::vector<size_t>& new_tet_id);
462
476 size_t& v1_id,
477 std::map<size_t, wmtk::TetMesh::VertexConnectivity>& rollback_vert_conn,
478 std::vector<size_t>& n1_t_ids,
479 std::vector<size_t>& new_tet_id,
480 std::vector<TetrahedronConnectivity>& old_tets);
481
490 bool swap_edge_56(const Tuple& t, std::vector<Tuple>& new_tets);
499 bool swap_edge_44(const Tuple& t, std::vector<Tuple>& new_tets);
508 bool swap_edge(const Tuple& t, std::vector<Tuple>& new_tets);
515 bool swap_face(const Tuple& t, std::vector<Tuple>& new_tets);
523 bool smooth_vertex(const Tuple& t);
524
533 bool split_tet(const Tuple& t, std::vector<Tuple>& new_tets);
534
545 bool split_face(const Tuple& t, std::vector<Tuple>& new_tets);
546
555 const std::vector<Tuple>& intersected_tets,
556 const std::vector<Tuple>& intersected_edges,
557 std::vector<size_t>& new_edge_vids,
558 std::vector<size_t>& new_center_vids,
559 std::vector<std::array<size_t, 4>>& center_split_tets);
560
570 bool insert_point(const Tuple& t, std::vector<Tuple>& new_tets);
571 virtual bool insert_point_before(const Tuple& t) { return true; };
572 virtual bool insert_point_after(std::vector<Tuple>& new_tets) { return true; };
578 void consolidate_mesh();
579
585 std::vector<Tuple> get_edges() const;
591 std::vector<Tuple> get_faces() const;
597 std::vector<Tuple> get_vertices() const;
603 std::vector<Tuple> get_tets() const;
608 // virtual void for_each_edge(const std::function<void(const TetMesh::Tuple&)>&);
609
610 // TODO: make this concurrent
615 virtual void for_each_face(const std::function<void(const TetMesh::Tuple&)>&);
616 // /**
617 // * @brief looping through all the unique vertices and perform the given function
618 // *
619 // */
620 // virtual void for_each_vertex(const std::function<void(const TetMesh::Tuple&)>&);
621 // /**
622 // * @brief looping through all the unique tet and perform the given function
623 // *
624 // */
625 // virtual void for_each_tetra(const std::function<void(const TetMesh::Tuple&)>&);
626
627public:
628 template <typename T>
629 using vector = tbb::concurrent_vector<T>;
630
631public:
632 AbstractAttributeContainer* p_vertex_attrs = nullptr;
633 AbstractAttributeContainer* p_edge_attrs = nullptr;
634 AbstractAttributeContainer* p_face_attrs = nullptr;
635 AbstractAttributeContainer* p_tet_attrs = nullptr;
636 // AbstractAttributeContainer vertex_attrs, edge_attrs, face_attrs, tet_attrs;
637
638
639private:
640 // Stores the connectivity of the mesh
641 vector<VertexConnectivity> m_vertex_connectivity;
642 vector<TetrahedronConnectivity> m_tet_connectivity;
643 std::atomic_long current_vert_size;
644 std::atomic_long current_tet_size;
645 tbb::spin_mutex vertex_connectivity_lock;
646 tbb::spin_mutex tet_connectivity_lock;
647 bool vertex_connectivity_synchronizing_flag = false;
648 bool tet_connectivity_synchronizing_flag = false;
649 int MAX_THREADS = 128;
650
651 int m_t_empty_slot = 0;
652 int m_v_empty_slot = 0;
653 int get_next_empty_slot_t();
654 int get_next_empty_slot_v();
655
656 // TODO: subdivide_tets function should not be in the TetMesh API.
657 void subdivide_tets(
658 const std::vector<size_t> t_ids,
659 const std::vector<bool>& mark_surface,
660 const std::map<std::array<size_t, 2>, size_t>& map_edge2vid,
661 std::map<std::array<size_t, 3>, std::vector<std::array<size_t, 5>>>& new_face_vids,
662 const std::vector<size_t>& new_vids,
663 std::vector<size_t>& new_tids,
664 std::vector<size_t>& new_center_vids,
665 std::vector<std::array<size_t, 4>>& center_split_tets);
666 void subdivide_a_tet(
667 size_t t_id,
668 const std::array<int, 6>& new_v_ids,
669 bool mark_surface,
670 std::map<std::array<size_t, 3>, std::vector<std::array<size_t, 5>>>& new_face_vids,
671 std::vector<size_t>& new_tids,
672 std::vector<size_t>& new_center_vids,
673 std::vector<std::array<size_t, 4>>& center_split_tets);
674
675public:
676 virtual bool invariants(const std::vector<Tuple>&) { return true; }
677
678protected:
679 virtual bool triangle_insertion_before(const std::vector<Tuple>& faces) { return true; }
680 virtual bool triangle_insertion_after(const std::vector<std::vector<Tuple>>&) { return true; }
681
683 // Checks if the split should be performed or not (user controlled)
690 virtual bool split_edge_before(const Tuple& t) { return true; } // check edge condition
691 // This function computes the attributes for the added simplices
692 // if it returns false then the operation is undone
699 virtual bool split_edge_after(const Tuple& t) { return true; } // check tet condition
700
702 // Checks if the collapse should be performed or not (user controlled)
710 virtual bool collapse_edge_before(const Tuple& t) { return true; }
711 // If it returns false then the operation is undone (the tuple indexes a vertex and tet that
712 // survived)
719 virtual bool collapse_edge_after(const Tuple& t) { return true; }
727 virtual bool swap_edge_44_before(const Tuple& t) { return true; }
738 virtual double swap_edge_44_energy(
739 const std::vector<std::array<size_t, 4>>& tets,
740 const int op_case)
741 {
742 return -op_case;
743 }
750 virtual bool swap_edge_44_after(const Tuple& t) { return true; }
758 virtual bool swap_edge_56_before(const Tuple& t) { return true; }
769 virtual double swap_edge_56_energy(
770 const std::vector<std::array<size_t, 4>>& tets,
771 const int op_case)
772 {
773 return -op_case;
774 }
781 virtual bool swap_edge_56_after(const Tuple& t) { return true; }
789 virtual bool swap_edge_before(const Tuple& t) { return true; }
796 virtual bool swap_edge_after(const Tuple& t) { return true; }
804 virtual bool swap_face_before(const Tuple& t) { return true; }
811 virtual bool swap_face_after(const Tuple& t) { return true; }
818 virtual bool smooth_before(const Tuple& t) { return true; }
825 virtual bool smooth_after(const Tuple& t) { return true; }
826
833 virtual bool split_face_before(const Tuple& t) { return true; }
834
842 virtual bool split_face_after(const Tuple& t) { return true; }
843
850 virtual bool split_tet_before(const Tuple& t) { return true; }
851
859 virtual bool split_tet_after(const Tuple& t) { return true; }
860
861 // virtual void resize_vertex_mutex(size_t v) {}
862
863public:
870 Tuple tuple_from_edge(size_t tid, int local_eid) const;
876 Tuple tuple_from_edge(const std::array<size_t, 2>& vids) const;
877
884 Tuple tuple_from_face(size_t tid, int local_fid) const;
885
891 std::tuple<Tuple, size_t> tuple_from_face(const std::array<size_t, 3>& vids) const;
892 std::tuple<Tuple, size_t> tuple_from_face(const simplex::Face& f) const;
893
899 Tuple tuple_from_vertex(size_t vid) const;
900
906 Tuple tuple_from_tet(size_t tid) const;
907
912 Tuple tuple_from_vids(size_t vid0, size_t vid1, size_t vid2, size_t vid3) const;
913
914 simplex::Tet simplex_from_tet(const Tuple& t) const;
915 simplex::Tet simplex_from_tet(const size_t tid) const;
916
920 Tuple switch_vertex(const Tuple& t) const
921 {
922 auto loc = t.switch_vertex(*this);
924 return loc;
925 }
929 Tuple switch_edge(const Tuple& t) const
930 {
931 auto loc = t.switch_edge(*this);
933 return loc;
934 }
938 Tuple switch_face(const Tuple& t) const
939 {
940 auto loc = t.switch_face(*this);
942 return loc;
943 }
947 std::optional<Tuple> switch_tetrahedron(const Tuple& t) const
948 {
949 auto loc = t.switch_tetrahedron(*this);
950 if (loc.has_value()) check_tuple_validity(loc.value());
951 return loc;
952 }
953
960 std::vector<Tuple> get_one_ring_tets_for_vertex(const Tuple& t) const;
967 std::vector<size_t> get_one_ring_tids_for_vertex(const Tuple& t) const;
968 std::vector<size_t> get_one_ring_tids_for_vertex(const size_t vid) const;
969
976 std::vector<Tuple> get_one_ring_vertices_for_vertex(const Tuple& t) const;
984 std::vector<size_t> get_one_ring_vids_for_vertex(size_t vid, std::vector<size_t>& cache);
991 std::vector<size_t> get_one_ring_vids_for_vertex(size_t vid) const;
996 std::vector<size_t> get_one_ring_vids_for_vertex_adj(size_t vid) const;
1001 std::vector<size_t> get_one_ring_vids_for_vertex_adj(size_t vid, std::vector<size_t>& cache);
1002
1009 std::vector<Tuple> get_incident_tets_for_edge(const Tuple& t) const;
1010 std::vector<Tuple> get_incident_tets_for_edge(const size_t vid0, const size_t vid1) const;
1011
1012 std::vector<size_t> get_incident_tids_for_edge(const Tuple& t) const;
1013 std::vector<size_t> get_incident_tids_for_edge(const size_t vid0, const size_t vid1) const;
1014
1021 std::vector<Tuple> get_one_ring_tets_for_edge(const Tuple& t) const;
1022
1029 std::vector<std::array<size_t, 3>> vertex_adjacent_boundary_faces(const Tuple& t) const;
1034 std::array<Tuple, 4> oriented_tet_vertices(const Tuple& t) const;
1039 std::array<size_t, 4> oriented_tet_vids(const Tuple& t) const;
1040 std::array<size_t, 4> oriented_tet_vids(const size_t tid) const;
1047 std::array<Tuple, 3> get_face_vertices(const Tuple& t) const;
1048 std::array<size_t, 3> get_face_vids(const Tuple& t) const;
1049
1057 std::array<Tuple, 6> tet_edges(const Tuple& t) const;
1061 void check_tuple_validity(const Tuple& t) const { t.check_validity(*this); }
1074 void remove_tets_by_ids(const std::vector<size_t>& tids)
1075 {
1076 for (size_t tid : tids) {
1077 m_tet_connectivity[tid].m_is_removed = true;
1078 for (int j = 0; j < 4; j++)
1079 vector_erase(m_vertex_connectivity[m_tet_connectivity[tid][j]].m_conn_tets, tid);
1080 }
1081 for (auto& v : m_vertex_connectivity) {
1082 if (v.m_is_removed) continue;
1083 if (v.m_conn_tets.empty()) v.m_is_removed = true;
1084 }
1085 }
1086 bool m_collapse_check_link_condition = true; // classical link condition
1087 bool m_collapse_check_topology = false; // sanity check
1088 bool m_collapse_check_manifold = true; // manifoldness check after collapse
1089
1090private:
1091 std::map<size_t, VertexConnectivity> operation_update_connectivity_impl(
1092 std::vector<size_t>& affected_tid,
1093 const std::vector<std::array<size_t, 4>>& new_tet_conn);
1094 void operation_failure_rollback_imp(
1095 std::map<size_t, VertexConnectivity>& rollback_vert_conn,
1096 const std::vector<size_t>& affected,
1097 const std::vector<size_t>& new_tet_id,
1098 const std::vector<TetrahedronConnectivity>& old_tets);
1099 std::map<size_t, VertexConnectivity> operation_update_connectivity_impl(
1100 const std::vector<size_t>& remove_id,
1101 const std::vector<std::array<size_t, 4>>& new_tet_conn,
1102 std::vector<size_t>& allocate_id);
1103 static std::vector<TetrahedronConnectivity> record_old_tet_connectivity(
1104 const TetMesh::vector<TetrahedronConnectivity>& conn,
1105 const std::vector<size_t>& tets)
1106 {
1107 std::vector<TetrahedronConnectivity> tet_conn;
1108 for (size_t i : tets) {
1109 tet_conn.push_back(conn[i]);
1110 }
1111 return tet_conn;
1112 }
1113
1114public:
1115 void start_protect_attributes()
1116 {
1117 if (p_vertex_attrs) {
1118 p_vertex_attrs->begin_protect();
1119 }
1120 if (p_edge_attrs) {
1121 p_edge_attrs->begin_protect();
1122 }
1123 if (p_face_attrs) {
1124 p_face_attrs->begin_protect();
1125 }
1126 if (p_tet_attrs) {
1127 p_tet_attrs->begin_protect();
1128 }
1129 }
1130
1131 void release_protect_attributes()
1132 {
1133 if (p_vertex_attrs) {
1134 p_vertex_attrs->end_protect();
1135 }
1136 if (p_edge_attrs) {
1137 p_edge_attrs->end_protect();
1138 }
1139 if (p_face_attrs) {
1140 p_face_attrs->end_protect();
1141 }
1142 if (p_tet_attrs) {
1143 p_tet_attrs->end_protect();
1144 }
1145 }
1146
1147 void rollback_protected_attributes()
1148 {
1149 if (p_vertex_attrs) {
1150 p_vertex_attrs->rollback();
1151 }
1152 if (p_edge_attrs) {
1153 p_edge_attrs->rollback();
1154 }
1155 if (p_face_attrs) {
1156 p_face_attrs->rollback();
1157 }
1158 if (p_tet_attrs) {
1159 p_tet_attrs->rollback();
1160 }
1161 }
1162
1163public:
1165 {
1166 tbb::spin_mutex mutex;
1167 int owner = std::numeric_limits<int>::max();
1168
1169 public:
1170 bool trylock() { return mutex.try_lock(); }
1171
1172 void unlock()
1173 {
1174 mutex.unlock();
1175 reset_owner();
1176 }
1177
1178 int get_owner() { return owner; }
1179
1180 void set_owner(int n) { owner = n; }
1181
1182 void reset_owner() { owner = INT_MAX; }
1183 };
1184
1185private:
1186 tbb::concurrent_vector<VertexMutex> m_vertex_mutex;
1187
1188 bool try_set_vertex_mutex(const Tuple& v, int threadid)
1189 {
1190 bool got = m_vertex_mutex[v.vid(*this)].trylock();
1191 if (got) m_vertex_mutex[v.vid(*this)].set_owner(threadid);
1192 return got;
1193 }
1194 bool try_set_vertex_mutex(size_t vid, int threadid)
1195 {
1196 bool got = m_vertex_mutex[vid].trylock();
1197 if (got) m_vertex_mutex[vid].set_owner(threadid);
1198 return got;
1199 }
1200
1201 void unlock_vertex_mutex(const Tuple& v) { m_vertex_mutex[v.vid(*this)].unlock(); }
1202 void unlock_vertex_mutex(size_t vid) { m_vertex_mutex[vid].unlock(); }
1203
1204protected:
1205 void resize_vertex_mutex(size_t v) { m_vertex_mutex.grow_to_at_least(v); }
1206
1207public:
1208 tbb::enumerable_thread_specific<std::vector<size_t>> mutex_release_stack;
1209 tbb::enumerable_thread_specific<std::vector<size_t>> get_one_ring_cache;
1210
1211 // void init(size_t n_vertices, const std::vector<std::array<size_t, 4>>& tets);
1212 int release_vertex_mutex_in_stack();
1213
1214 // helpers
1222 bool try_set_vertex_mutex_two_ring(const Tuple& v, int threadid);
1230 bool try_set_vertex_mutex_two_ring_vid(const Tuple& v, int threadid);
1239 bool try_set_vertex_mutex_two_ring_vid(size_t v, int threadid);
1240
1241 // can be called
1250 bool try_set_edge_mutex_two_ring(const Tuple& e, int threadid = 0);
1259 bool try_set_face_mutex_two_ring(const Tuple& f, int threadid = 0);
1271 const Tuple& v1,
1272 const Tuple& v2,
1273 const Tuple& v3,
1274 int threadid = 0);
1285 bool try_set_face_mutex_two_ring(size_t v1, size_t v2, size_t v3, int threadid = 0);
1293 bool try_set_vertex_mutex_one_ring(const Tuple& v, int threadid = 0);
1294
1295public:
1300 void for_each_edge(const std::function<void(const TetMesh::Tuple&)>&);
1305 void for_each_vertex(const std::function<void(const TetMesh::Tuple&)>&);
1310 void for_each_tetra(const std::function<void(const TetMesh::Tuple&)>&);
1311 int NUM_THREADS = 0;
1312
1313public:
1314 // substructure functionality
1315
1321 virtual bool vertex_is_on_surface(const size_t vid) const { return false; }
1322
1328 virtual bool face_is_on_surface(const size_t fid) const { return false; }
1329
1336
1342 simplex::SimplexCollection get_surface_faces_for_edge(const std::array<size_t, 2>& vids) const;
1348 size_t get_num_surface_faces_for_edge(const std::array<size_t, 2>& vids) const;
1349
1350
1359 size_t compute_vertex_order(const size_t vid) const;
1360
1375 virtual size_t get_order_of_vertex(const size_t vid) const { return compute_vertex_order(vid); }
1376
1387 size_t get_order_of_edge(const std::array<size_t, 2>& vids) const;
1388
1402 bool substructure_link_condition(const Tuple& e_tuple) const;
1403};
1404
1405
1406} // namespace wmtk
Definition TetMesh.h:200
a Tuple refers to a global vid and a global tet id, and a local edge id and local face id
Definition TetMesh.h:48
Tuple switch_face(const TetMesh &m) const
Definition TetMeshTuple.cpp:253
bool is_valid(const TetMesh &m) const
Definition TetMeshTuple.cpp:57
bool is_boundary_face(const TetMesh &m) const
Definition TetMeshTuple.cpp:17
void print_info() const
prints the tuple
Definition TetMeshTuple.cpp:68
std::optional< Tuple > switch_tetrahedron(const TetMesh &m) const
Definition TetMeshTuple.cpp:273
size_t eid(const TetMesh &m) const
Definition TetMeshTuple.cpp:111
Tuple switch_edge(const TetMesh &m) const
Definition TetMeshTuple.cpp:238
Tuple switch_vertex(const TetMesh &m) const
Definition TetMeshTuple.cpp:224
size_t tid(const TetMesh &m) const
Definition TetMeshTuple.cpp:219
size_t vid(const TetMesh &m) const
Definition TetMeshTuple.cpp:106
size_t fid(const TetMesh &m) const
Definition TetMeshTuple.cpp:131
bool is_boundary_edge(const TetMesh &m) const
Definition TetMeshTuple.cpp:34
void check_validity(const TetMesh &m) const
check Tuple validity and connectivity validity
Definition TetMeshTuple.cpp:358
Definition TetMesh.h:246
Definition TetMesh.h:1165
Definition TetMesh.h:23
size_t compute_vertex_order(const size_t vid) const
Compute the vertex order for a single vertex.
Definition TetMeshSubstructure.cpp:117
virtual bool swap_edge_44_after(const Tuple &t)
User specified modifications and desideratas for after a 4-4 edge swap.
Definition TetMesh.h:750
std::vector< Tuple > get_one_ring_vertices_for_vertex(const Tuple &t) const
Get the one ring vertices for a vertex.
Definition TetMesh.cpp:712
virtual bool swap_edge_44_before(const Tuple &t)
User specified preparations and desideratas for an 4-4 edge swap before changing the connectivity.
Definition TetMesh.h:727
virtual bool split_tet_before(const Tuple &t)
User specified preparations and desideratas for a tet split before changing the connectivity.
Definition TetMesh.h:850
size_t tet_size() const
get the number of unremoved tets
Definition TetMesh.h:378
virtual size_t get_order_of_vertex(const size_t vid) const
Get the order of a vertex.
Definition TetMesh.h:1375
std::vector< Tuple > get_faces() const
Definition TetMesh.cpp:219
std::array< Tuple, 6 > tet_edges(const Tuple &t) const
get the 6 edges of a tet represented by Tuples
Definition TetMesh.cpp:677
virtual bool smooth_after(const Tuple &t)
User specified modifications and desideratas for after smoothing a vertex.
Definition TetMesh.h:825
void consolidate_mesh()
cleans up the deleted vertices or tetrahedra, fixes the corresponding indices, and reset the version ...
Definition TetMesh.cpp:836
size_t vert_capacity() const
get the current largest global vid
Definition TetMesh.h:354
virtual bool collapse_edge_after(const Tuple &t)
User specified modifications and desideratas for after an edge collapse.
Definition TetMesh.h:719
virtual bool swap_edge_after(const Tuple &t)
User specified modifications and desideratas for after a 3-2 edge swap.
Definition TetMesh.h:796
size_t get_num_surface_faces_for_edge(const std::array< size_t, 2 > &vids) const
Get the number of surface faces incident to the edge.
Definition TetMeshSubstructure.cpp:82
bool smooth_vertex(const Tuple &t)
Definition TetMesh.cpp:339
virtual bool face_is_on_surface(const size_t fid) const
Is a face part of the substructure.
Definition TetMesh.h:1328
bool insert_point(const Tuple &t, std::vector< Tuple > &new_tets)
Insert a point into a tetmesh inside a tet. In general position, this split a tet into 4....
Definition TetMeshTriangleInsertionConn.cpp:412
bool split_edge(const Tuple &t, std::vector< Tuple > &new_tets)
Definition TetMeshEdgeSplittingConn.cpp:6
Tuple switch_face(const Tuple &t) const
wrapper function from Tuple::switch_face
Definition TetMesh.h:938
std::array< Tuple, 4 > oriented_tet_vertices(const Tuple &t) const
Definition TetMesh.cpp:637
void for_each_vertex(const std::function< void(const TetMesh::Tuple &)> &)
perform the given function for each vertex
Definition TetMesh.cpp:1355
bool try_set_vertex_mutex_one_ring(const Tuple &v, int threadid=0)
try lock the one-ring neighboring traingles' incident vertices
Definition TetMesh.cpp:1269
std::array< size_t, 4 > oriented_tet_vids(const Tuple &t) const
Definition TetMesh.cpp:649
bool collapse_edge_check_topology(const std::vector< size_t > &new_tet_id)
Check topology after collapse connectivity change. This is a sanity check and should not be necessary...
Definition TetMeshEdgeCollapsingConn.cpp:419
bool try_set_vertex_mutex_two_ring_vid(const Tuple &v, int threadid)
try lock the two-ring neighboring traingles' incident vertices using vids
Definition TetMesh.cpp:974
Tuple tuple_from_tet(size_t tid) const
get a Tuple from global tetra index
Definition TetMesh.cpp:580
void subdivide_tets(const std::vector< size_t > t_ids, const std::vector< bool > &mark_surface, const std::map< std::array< size_t, 2 >, size_t > &map_edge2vid, std::map< std::array< size_t, 3 >, std::vector< std::array< size_t, 5 > > > &new_face_vids, const std::vector< size_t > &new_vids, std::vector< size_t > &new_tids, std::vector< size_t > &new_center_vids, std::vector< std::array< size_t, 4 > > &center_split_tets)
Definition TetMeshTriangleInsertionConn.cpp:141
void init(size_t n_vertices, const std::vector< std::array< size_t, 4 > > &tets)
Definition TetMesh.cpp:77
void subdivide_a_tet(size_t t_id, const std::array< int, 6 > &new_v_ids, bool mark_surface, std::map< std::array< size_t, 3 >, std::vector< std::array< size_t, 5 > > > &new_face_vids, std::vector< size_t > &new_tids, std::vector< size_t > &new_center_vids, std::vector< std::array< size_t, 4 > > &center_split_tets)
Definition TetMeshTriangleInsertionConn.cpp:234
virtual bool swap_edge_56_before(const Tuple &t)
User specified preparations and desideratas for a 5-6 edge swap before changing the connectivity.
Definition TetMesh.h:758
std::vector< Tuple > get_incident_tets_for_edge(const Tuple &t) const
Get the incident tets for edge.
Definition TetMesh.cpp:781
virtual bool split_face_after(const Tuple &t)
Compute the attributes for the added simplices.
Definition TetMesh.h:842
bool swap_edge_56(const Tuple &t, std::vector< Tuple > &new_tets)
Definition TetMeshSwapMeshConnectivity.cpp:690
bool split_face(const Tuple &t, std::vector< Tuple > &new_tets)
Split a face in 3 faces.
Definition TetMeshFaceSplittingConn.cpp:6
bool link_condition(const Tuple &t)
Definition TetMeshEdgeCollapsingConn.cpp:310
std::vector< Tuple > get_one_ring_tets_for_edge(const Tuple &t) const
Get the one ring tets for edge.
Definition TetMesh.cpp:816
virtual bool split_face_before(const Tuple &t)
User specified preparations and desideratas for a face split before changing the connectivity.
Definition TetMesh.h:833
virtual double swap_edge_44_energy(const std::vector< std::array< size_t, 4 > > &tets, const int op_case)
User specified energy to decide which of the 4 possible orientations should be chosen.
Definition TetMesh.h:738
Tuple tuple_from_vertex(size_t vid) const
get a Tuple from global vertex index
Definition TetMesh.cpp:567
simplex::SimplexCollection get_surface_faces_for_vertex(const size_t vid) const
Get all faces on the surface that are incident to vid.
Definition TetMeshSubstructure.cpp:7
virtual void for_each_face(const std::function< void(const TetMesh::Tuple &)> &)
looping through all the unique edges and perform the given function
Definition TetMesh.cpp:205
std::vector< size_t > get_one_ring_vids_for_vertex(size_t vid, std::vector< size_t > &cache)
Get the one ring vids for vertex.
Definition TetMesh.cpp:757
std::optional< Tuple > switch_tetrahedron(const Tuple &t) const
wrapper function from Tuple::switch_tetrahedron
Definition TetMesh.h:947
size_t get_order_of_edge(const std::array< size_t, 2 > &vids) const
Compute the order of an edge.
Definition TetMeshSubstructure.cpp:203
std::vector< Tuple > get_tets() const
Definition TetMesh.cpp:308
virtual bool smooth_before(const Tuple &t)
User specified preparations and desideratas for smoothing a vertex.
Definition TetMesh.h:818
virtual bool split_edge_before(const Tuple &t)
User specified preparations and desideratas for an edge split before changing the connectivity.
Definition TetMesh.h:690
std::vector< size_t > get_one_ring_vids_for_vertex_adj(size_t vid) const
Duplicate of the function TetMesh::get_one_ring_vids_for_vertex.
Definition TetMesh.cpp:743
virtual bool swap_edge_before(const Tuple &t)
User specified preparations and desideratas for an 3-2 edge swap before changing the conenctivity.
Definition TetMesh.h:789
void triangle_insertion(const std::vector< Tuple > &intersected_tets, const std::vector< Tuple > &intersected_edges, std::vector< size_t > &new_edge_vids, std::vector< size_t > &new_center_vids, std::vector< std::array< size_t, 4 > > &center_split_tets)
Insert a triangle into a tetmesh, with known intersection information.
Definition TetMeshTriangleInsertionConn.cpp:11
bool check_mesh_connectivity_validity() const
checks the validity of the connectivity of the mesh. Including the validity of each Tuple
Definition TetMesh.cpp:234
bool split_tet(const Tuple &t, std::vector< Tuple > &new_tets)
Split a tet in 4 tets.
Definition TetMeshTetSplittingConn.cpp:6
Tuple tuple_from_edge(size_t tid, int local_eid) const
get a Tuple from global tetra index and local edge index (from 0-5).
Definition TetMesh.cpp:353
size_t vertex_size() const
get the number of unremoved verticies
Definition TetMesh.h:366
Tuple switch_vertex(const Tuple &t) const
wrapper function from Tuple::switch_vertex
Definition TetMesh.h:920
simplex::SimplexCollection get_surface_faces_for_edge(const std::array< size_t, 2 > &vids) const
Get all faces on the surface that are incident to the edge.
Definition TetMeshSubstructure.cpp:42
bool substructure_link_condition(const Tuple &e_tuple) const
Link condition that also considers substructures.
Definition TetMeshSubstructure.cpp:218
virtual bool swap_face_before(const Tuple &t)
User specified preparations and desideratas for an 2-3 face swap befroe changing the geometry.
Definition TetMesh.h:804
bool try_set_edge_mutex_two_ring(const Tuple &e, int threadid=0)
try lock the two-ring neighboring triangles' incident vertices for the two ends of an edge
Definition TetMesh.cpp:1023
virtual bool vertex_is_on_surface(const size_t vid) const
Is a vertex part of the substructure.
Definition TetMesh.h:1321
bool swap_edge(const Tuple &t, std::vector< Tuple > &new_tets)
3-2 edge swap
Definition TetMeshSwapMeshConnectivity.cpp:120
Tuple switch_edge(const Tuple &t) const
wrapper function from Tuple::switch_edge
Definition TetMesh.h:929
std::vector< Tuple > get_edges() const
Definition TetMesh.cpp:172
std::vector< size_t > get_one_ring_tids_for_vertex(const Tuple &t) const
Get the one ring tids for vertex.
Definition TetMesh.cpp:690
virtual bool split_tet_after(const Tuple &t)
Compute the attributes for the added simplices.
Definition TetMesh.h:859
void for_each_edge(const std::function< void(const TetMesh::Tuple &)> &)
perform the given function for each edge
Definition TetMesh.cpp:1294
bool collapse_edge_conn(const Tuple &loc0, std::vector< Tuple > &new_edges, size_t &v1_id, Tuple &new_loc, std::map< size_t, wmtk::TetMesh::VertexConnectivity > &rollback_vert_conn, std::vector< size_t > &n1_t_ids_copy, std::vector< size_t > &new_tet_id, std::vector< TetrahedronConnectivity > &old_tets)
Definition TetMeshEdgeCollapsingConn.cpp:449
void check_tuple_validity(const Tuple &t) const
Definition TetMesh.h:1061
void collapse_edge_rollback(size_t &v1_id, std::map< size_t, wmtk::TetMesh::VertexConnectivity > &rollback_vert_conn, std::vector< size_t > &n1_t_ids, std::vector< size_t > &new_tet_id, std::vector< TetrahedronConnectivity > &old_tets)
Definition TetMeshEdgeCollapsingConn.cpp:438
bool try_set_vertex_mutex_two_ring(const Tuple &v, int threadid)
try lock the two-ring neighboring traingles' incident vertices
Definition TetMesh.cpp:952
virtual bool collapse_edge(const Tuple &t, std::vector< Tuple > &new_tets)
Definition TetMeshEdgeCollapsingConn.cpp:263
bool try_set_face_mutex_two_ring(const Tuple &f, int threadid=0)
try lock the two-ring neighboring triangles' incident vertices for the 3 vertices of a face
Definition TetMesh.cpp:1069
Tuple tuple_from_face(size_t tid, int local_fid) const
get a Tuple from global tetra index and local face index (from 0-3).
Definition TetMesh.cpp:363
virtual bool split_edge_after(const Tuple &t)
This function computes the attributes for the added simplices. User specified modifications and desid...
Definition TetMesh.h:699
static constexpr std::array< std::array< int, 2 >, 6 > m_local_edges
local edges within a tet
Definition TetMesh.h:29
std::map< size_t, VertexConnectivity > operation_update_connectivity_impl(std::vector< size_t > &affected_tid, const std::vector< std::array< size_t, 4 > > &new_tet_conn)
Definition TetMeshSwapMeshConnectivity.cpp:43
std::array< Tuple, 3 > get_face_vertices(const Tuple &t) const
Get the 3 vertices of a face represented by Tuple.
Definition TetMesh.cpp:659
virtual bool swap_edge_56_after(const Tuple &t)
User specified modifications and desideratas for after a 5-6 edge swap.
Definition TetMesh.h:781
virtual bool collapse_edge_before(const Tuple &t)
User specified preparations and desideratas for an edge collapse before changing the connectivity.
Definition TetMesh.h:710
std::vector< Tuple > get_vertices() const
Definition TetMesh.cpp:323
size_t tet_capacity() const
get the current largest global tid
Definition TetMesh.h:360
std::vector< Tuple > get_one_ring_tets_for_vertex(const Tuple &t) const
Get the one ring tets for a vertex.
Definition TetMesh.cpp:701
void for_each_tetra(const std::function< void(const TetMesh::Tuple &)> &)
perform the given function for each tet
Definition TetMesh.cpp:1327
bool swap_edge_44(const Tuple &t, std::vector< Tuple > &new_tets)
Definition TetMeshSwapMeshConnectivity.cpp:472
virtual double swap_edge_56_energy(const std::vector< std::array< size_t, 4 > > &tets, const int op_case)
User specified energy to decide which of the 5 possible orientations should be chosen.
Definition TetMesh.h:769
bool swap_face(const Tuple &t, std::vector< Tuple > &new_tets)
2-3 face swap
Definition TetMeshSwapMeshConnectivity.cpp:231
void remove_tets_by_ids(const std::vector< size_t > &tids)
remove the tetrahedrons in the mesh that have given tet ids
Definition TetMesh.h:1074
Tuple tuple_from_vids(size_t vid0, size_t vid1, size_t vid2, size_t vid3) const
Get a Tuple from global vertex IDs.
Definition TetMesh.cpp:591
std::vector< std::array< size_t, 3 > > vertex_adjacent_boundary_faces(const Tuple &t) const
Definition TetMesh.cpp:915
virtual bool swap_face_after(const Tuple &t)
User specified modifications and desideratas for after a 2-3 face swap.
Definition TetMesh.h:811
Definition Simplex.hpp:57
Definition SimplexCollection.hpp:9
Definition Simplex.hpp:71