Wildmeshing Toolkit
TetMeshSubstructureTopologyPreservingInvariant.cpp
Go to the documentation of this file.
2 #include <wmtk/Mesh.hpp>
3 
7 #include <wmtk/simplex/link.hpp>
9 
10 namespace 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 
29  const auto edge_tag_acc = mesh().create_const_accessor(m_substructure_edge_tag_handle);
30  const auto face_tag_acc = mesh().create_const_accessor(m_substructure_face_tag_handle);
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 =
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 =
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 =
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 =
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 :
171  if (face_tag_acc.const_scalar_attribute(f_e.tuple()) == m_substructure_tag_value) {
172  std::vector<Tuple> vertices_dummy_tet =
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
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
SimplexCollection open_star(const Mesh &mesh, const Simplex &simplex, const bool sort_and_clean)
Definition: open_star.cpp:12
SimplexCollection link(const Mesh &mesh, const simplex::Simplex &simplex, const bool sort_and_clean)
Definition: link.cpp:84
std::vector< Simplex > cofaces_single_dimension_simplices(const Mesh &mesh, const Simplex &simplex, PrimitiveType cofaces_type)
std::vector< Tuple > faces_single_dimension_tuples(const Mesh &mesh, const Simplex &simplex, const PrimitiveType face_type)