Wildmeshing Toolkit
Loading...
Searching...
No Matches
TetMeshSubstructureTopologyPreservingInvariant.cpp
Go to the documentation of this file.
2#include <wmtk/Mesh.hpp>
3
9
10namespace wmtk::invariants {
12 const Mesh& m,
13 const TypedAttributeHandle<int64_t>& substructure_face_tag_handle,
14 const TypedAttributeHandle<int64_t>& substructure_edge_tag_handle,
15 const int64_t substructure_tag_value)
16 : Invariant(m, true, false, false)
17 , m_substructure_face_tag_handle(substructure_face_tag_handle)
18 , m_substructure_edge_tag_handle(substructure_edge_tag_handle)
19 , m_substructure_tag_value(substructure_tag_value)
20{}
21
23 const simplex::Simplex& input_simplex) const
24{
25 assert(input_simplex.primitive_type() == PrimitiveType::Edge);
26
27 using namespace simplex;
28
31
32 // edge e = (u,v)
33
34 const simplex::Simplex& edge_e = input_simplex;
35 const simplex::Simplex vertex_u(mesh(), PrimitiveType::Vertex, input_simplex.tuple());
36 const simplex::Simplex vertex_v(
37 mesh(),
39 mesh().switch_tuple(input_simplex.tuple(), PrimitiveType::Vertex));
40
41 RawSimplexCollection lk_u_0(link(mesh(), vertex_u));
42 RawSimplexCollection lk_u_1;
43 RawSimplexCollection lk_u_2;
44
45 simplex::SimplexCollection u_open_star = open_star(mesh(), vertex_u);
46
47 for (const simplex::Simplex& f_u : u_open_star.simplex_vector(PrimitiveType::Triangle)) {
48 if (face_tag_acc.const_scalar_attribute(f_u.tuple()) == m_substructure_tag_value) {
49 std::vector<Tuple> vertices_dummy_tet =
50 faces_single_dimension_tuples(mesh(), f_u, PrimitiveType::Vertex);
51 vertices_dummy_tet.emplace_back(Tuple()); // add dummy vertex
52
53 RawSimplex dummy_tet(mesh(), vertices_dummy_tet);
54
55 // add face opposite of dummy_tet and all its faces
56 RawSimplex opp_dummy_face = dummy_tet.opposite_face(mesh(), vertex_u.tuple());
57 lk_u_0.add(opp_dummy_face);
58 lk_u_0.add(opp_dummy_face.faces());
59
60 RawSimplex raw_f_u(mesh(), f_u);
61 // add edge of f_u opposite of vertex u and its 2 vertices
62 RawSimplex opp_dummy_edge = raw_f_u.opposite_face(mesh(), vertex_u.tuple());
63 lk_u_1.add(opp_dummy_edge);
64 lk_u_1.add(opp_dummy_edge.faces());
65 }
66 }
67
68 int64_t u_incident_subset_edges = 0;
69
70 for (const simplex::Simplex& e_u : u_open_star.simplex_vector(PrimitiveType::Edge)) {
71 if (edge_tag_acc.const_scalar_attribute(e_u.tuple()) == m_substructure_tag_value) {
72 ++u_incident_subset_edges;
73 std::vector<Tuple> vertices_dummy_tri =
74 faces_single_dimension_tuples(mesh(), e_u, PrimitiveType::Vertex);
75 vertices_dummy_tri.emplace_back(Tuple()); // add dummy vertex
76
77 RawSimplex dummy_tri(mesh(), vertices_dummy_tri);
78 RawSimplex opp_dummy_edge = dummy_tri.opposite_face(mesh(), vertex_u.tuple());
79 lk_u_0.add(opp_dummy_edge);
80 lk_u_0.add(opp_dummy_edge.faces());
81
82 lk_u_1.add(opp_dummy_edge);
83 lk_u_1.add(opp_dummy_edge.faces());
84
85 RawSimplex raw_e_u(mesh(), e_u);
86 lk_u_2.add(raw_e_u.opposite_face(mesh(), vertex_u.tuple()));
87 }
88 }
89
90 // if u is an order 3 vertex
91 if (u_incident_subset_edges != 0 && u_incident_subset_edges != 2) {
92 lk_u_2.add(RawSimplex({-1})); // add dummy vertex
93 }
94
95 lk_u_0.sort_and_clean();
96 lk_u_1.sort_and_clean();
97 lk_u_2.sort_and_clean();
98
99 // same code for vertex v
100
101 RawSimplexCollection lk_v_0(link(mesh(), vertex_v));
102 RawSimplexCollection lk_v_1;
103 RawSimplexCollection lk_v_2;
104
105 simplex::SimplexCollection v_open_star = open_star(mesh(), vertex_v);
106
107 for (const simplex::Simplex& f_v : v_open_star.simplex_vector(PrimitiveType::Triangle)) {
108 if (face_tag_acc.const_scalar_attribute(f_v.tuple()) == m_substructure_tag_value) {
109 std::vector<Tuple> vertices_dummy_tet =
110 faces_single_dimension_tuples(mesh(), f_v, PrimitiveType::Vertex);
111 vertices_dummy_tet.emplace_back(Tuple()); // add dummy vertex
112
113 RawSimplex dummy_tet(mesh(), vertices_dummy_tet);
114
115 // add face opposite of dummy_tet and all its faces
116 RawSimplex opp_dummy_face = dummy_tet.opposite_face(mesh(), vertex_v.tuple());
117 lk_v_0.add(opp_dummy_face);
118 lk_v_0.add(opp_dummy_face.faces());
119
120 RawSimplex raw_f_u(mesh(), f_v);
121 // add edge of f_u opposite of vertex u and its 2 vertices
122 RawSimplex opp_dummy_edge = raw_f_u.opposite_face(mesh(), vertex_v.tuple());
123 lk_v_1.add(opp_dummy_edge);
124 lk_v_1.add(opp_dummy_edge.faces());
125 }
126 }
127
128 int64_t v_incident_subset_edges = 0;
129
130 for (const simplex::Simplex& e_v : v_open_star.simplex_vector(PrimitiveType::Edge)) {
131 if (edge_tag_acc.const_scalar_attribute(e_v.tuple()) == m_substructure_tag_value) {
132 ++v_incident_subset_edges;
133 std::vector<Tuple> vertices_dummy_tri =
134 faces_single_dimension_tuples(mesh(), e_v, PrimitiveType::Vertex);
135 vertices_dummy_tri.emplace_back(Tuple()); // add dummy vertex
136
137 RawSimplex dummy_tri(mesh(), vertices_dummy_tri);
138 RawSimplex opp_dummy_edge = dummy_tri.opposite_face(mesh(), vertex_v.tuple());
139 lk_v_0.add(opp_dummy_edge);
140 lk_v_0.add(opp_dummy_edge.faces());
141
142 lk_v_1.add(opp_dummy_edge);
143 lk_v_1.add(opp_dummy_edge.faces());
144
145 RawSimplex raw_e_v(mesh(), e_v);
146 lk_v_2.add(raw_e_v.opposite_face(mesh(), vertex_v.tuple()));
147 }
148 }
149
150 // if v is an order 3 vertex
151 if (v_incident_subset_edges != 0 && v_incident_subset_edges != 2) {
152 lk_v_2.add(RawSimplex({-1})); // add dummy vertex
153 }
154
155 lk_v_0.sort_and_clean();
156 lk_v_1.sort_and_clean();
157 lk_v_2.sort_and_clean();
158
159 if (!RawSimplexCollection::get_intersection(lk_u_2, lk_v_2).simplex_vector().empty()) {
160 return false;
161 }
162
163 // lk_e
164 RawSimplexCollection lk_e_0(link(mesh(), edge_e));
165 RawSimplexCollection lk_e_1;
166
167 RawSimplex raw_edge_e(mesh(), edge_e);
168
169 for (const simplex::Simplex& f_e :
170 cofaces_single_dimension_simplices(mesh(), edge_e, PrimitiveType::Triangle)) {
171 if (face_tag_acc.const_scalar_attribute(f_e.tuple()) == m_substructure_tag_value) {
172 std::vector<Tuple> vertices_dummy_tet =
173 faces_single_dimension_tuples(mesh(), f_e, PrimitiveType::Vertex);
174 vertices_dummy_tet.emplace_back(Tuple()); // add dummy vertex
175
176 RawSimplex raw_f_e(mesh(), f_e);
177
178 RawSimplex dummy_tet(mesh(), vertices_dummy_tet);
179 RawSimplex dummy_edge = dummy_tet.opposite_face(raw_edge_e);
180
181 lk_e_0.add(dummy_edge);
182 lk_e_0.add(dummy_edge.faces());
183
184 lk_e_1.add(raw_f_e.opposite_face(raw_edge_e));
185 }
186 }
187
188 if (edge_tag_acc.const_scalar_attribute(edge_e.tuple()) == m_substructure_tag_value) {
189 RawSimplex dummy_vertex({-1});
190 lk_e_0.add(dummy_vertex);
191 lk_e_1.add(dummy_vertex);
192 }
193
194 lk_e_0.sort_and_clean();
195 lk_e_1.sort_and_clean();
196
197 RawSimplexCollection intersection_u_v_0 =
198 RawSimplexCollection::get_intersection(lk_u_0, lk_v_0);
199 if (!RawSimplexCollection::are_simplex_collections_equal(intersection_u_v_0, lk_e_0)) {
200 return false;
201 }
202 RawSimplexCollection intersection_u_v_1 =
203 RawSimplexCollection::get_intersection(lk_u_1, lk_v_1);
204 if (!RawSimplexCollection::are_simplex_collections_equal(intersection_u_v_1, lk_e_1)) {
205 return false;
206 }
207
208 return true;
209}
210
211} // namespace wmtk::invariants
const attribute::Accessor< T, Mesh, D > create_const_accessor(const attribute::MeshAttributeHandle &handle) const
The Tuple is the basic navigation tool in our mesh data structure.
Definition Tuple.hpp:19
Handle that represents attributes for some mesh.
const Mesh & mesh() const
Definition Invariant.cpp:35
TetMeshSubstructureTopologyPreservingInvariant(const Mesh &m, const TypedAttributeHandle< int64_t > &substructure_face_tag_handle, const TypedAttributeHandle< int64_t > &substructure_edge_tag_handle, const int64_t substructure_tag_value)
const std::vector< Simplex > & simplex_vector() const
Return const reference to the simplex vector.
const Tuple & tuple() const
Definition Simplex.hpp:53
PrimitiveType primitive_type() const
Definition Simplex.hpp:51