Wildmeshing Toolkit
Loading...
Searching...
No Matches
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
14namespace wmtk {
15namespace {
16
17// checks if two simplices both are mappable
18bool 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
30bool 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
66bool 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
92struct 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
CofacesSingleDimensionIterable cofaces_single_dimension_iterable(const Mesh &mesh, const Simplex &simplex, const PrimitiveType cofaces_type)