Wildmeshing Toolkit
MultiMeshMapValidInvariant.cpp
Go to the documentation of this file.
2 
3 #include <stdexcept>
4 #include <wmtk/EdgeMesh.hpp>
5 #include <wmtk/Mesh.hpp>
6 #include <wmtk/PointMesh.hpp>
7 #include <wmtk/TetMesh.hpp>
8 #include <wmtk/TriMesh.hpp>
13 
14 namespace wmtk {
15 namespace {
16 
17 // checks if two simplices both are mappable
18 bool both_map_to_child(
19  const Mesh& parent,
20  const Mesh& child,
21  const simplex::Simplex& left,
22  const simplex::Simplex& right)
23 {
24  return parent.can_map(child, left) && parent.can_map(child, right);
25 }
26 
27 
28 // computes teh two ears in a K+1 simplex over the input edge to see if their facets will be mapped
29 // into one another
30 bool both_map_to_child(const Mesh& parent, const Mesh& child, const Tuple& input)
31 {
32  const PrimitiveType child_type = child.top_simplex_type();
33  const PrimitiveType parent_type = parent.top_simplex_type();
34  assert(parent_type > child_type);
35  const PrimitiveType collapsed_simplex_type = std::min(child_type + 1, parent_type);
36  auto opposite = [&parent, collapsed_simplex_type](Tuple t) {
37  //switch(collapsed_simplex_type) {
38  // case PrimitiveType::Tetrahedron:
39  // t = parent.switch_tuples(t, {PrimitiveType::Vertex, PrimitiveType::Edge, PrimitiveType::Triangle});
40  // case PrimitiveType::Triangle:
41  // t = parent.switch_tuples(t, {PrimitiveType::Vertex, PrimitiveType::Edge});
42  // case PrimitiveType::Edge:
43  // t = parent.switch_tuple(t, PrimitiveType::Vertex);
44 
45  // default:
46  // case PrimitiveType::Vertex:
47  // break;
48  //}
49  for (PrimitiveType pt = PrimitiveType::Vertex; pt < collapsed_simplex_type; pt = pt + 1) {
50  assert(pt < parent.top_simplex_type());
51  t = parent.switch_tuple(t, pt);
52  }
53  return t;
54  };
55  const simplex::Simplex left(child_type, opposite(input));
56  const simplex::Simplex right(
57  child_type,
58  opposite(parent.switch_tuple(input, PrimitiveType::Vertex)));
59  return both_map_to_child(parent, child, left, right);
60 }
61 
62 
63 // two child K-facets will merge into one another if they are the ears of a K+1 simplex whose
64 // "input edge" is the input edge. This function iterates through those K+1 simplices and lets
65 // both_map_to_child check for if both ears are mapped
66 bool any_pairs_both_map_to_child(
67  const Mesh& parent,
68  const Mesh& child,
69  const simplex::Simplex& edge)
70 {
71  assert(edge.primitive_type() == PrimitiveType::Edge);
72  const PrimitiveType parent_type = parent.top_simplex_type();
73  const PrimitiveType child_type = child.top_simplex_type();
74  assert(parent_type > child_type);
75  if (parent_type == child_type) {
76  // if the meshes are the same dimension then there isn't a pair, so this function returns
77  // false
78  return false;
79  } else if (parent_type == child_type + 1) {
80  return both_map_to_child(parent, child, edge.tuple());
81  }
82  for (const Tuple& tuple :
83  simplex::cofaces_single_dimension_iterable(parent, edge, child.top_simplex_type() + 1)) {
84  if (both_map_to_child(parent, child, tuple)) {
85  return true;
86  }
87  }
88  return false;
89 }
90 
91 
92 struct MultiMeshMapValidFunctor
93 {
94  template <typename T>
95  bool operator()(const T& m, const simplex::Simplex& s, int64_t)
96  {
97  return this->operator()(m, s);
98  }
99  bool operator()(const Mesh& m, const simplex::Simplex& s) const
100  {
101  for (auto child_ptr : m.get_child_meshes()) {
102  if (any_pairs_both_map_to_child(m, *child_ptr, s)) {
103  return false;
104  }
105  }
106  return true;
107  }
108 };
109 } // namespace
110 
112  : Invariant(m, true, false, false)
113 {}
115 {
116  assert(t.primitive_type() == PrimitiveType::Edge);
118  std::integral_constant<int64_t, 1>{}, // specify that this runs on edges
119  MultiMeshMapValidFunctor{});
120  // TODO: fix visitor to work for const data
121  visitor.execute_from_root(const_cast<Mesh&>(mesh()), simplex::NavigatableSimplex(mesh(), t));
122  const auto& data = visitor.cache();
123 
124  for (const auto& [key, value_var] : data) {
125  const bool valid = std::get<bool>(value_var);
126  if (!valid) {
127  return false;
128  }
129  }
130  return true;
131 }
132 } // namespace wmtk
bool before(const simplex::Simplex &t) const override
const Mesh & mesh() const
Definition: Invariant.cpp:35
void execute_from_root(Mesh &mesh, const simplex::NavigatableSimplex &simplex)
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
CofacesSingleDimensionIterable cofaces_single_dimension_iterable(const Mesh &mesh, const Simplex &simplex, const PrimitiveType cofaces_type)
Definition: Accessor.hpp:6