Wildmeshing Toolkit
TopDimensionCofacesIterable.cpp
Go to the documentation of this file.
2 
3 #include <wmtk/utils/Logger.hpp>
5 
7 
8 namespace wmtk::simplex {
9 
10 
12  const Mesh& mesh,
13  const Simplex& simplex,
14  const bool retrieve_intermediate_tuple)
15  : m_mesh(mesh)
16  , m_simplex(simplex)
17  , m_retrieve_intermediate_tuple(retrieve_intermediate_tuple)
18 {}
19 
21  TopDimensionCofacesIterable& container,
22  const Tuple& t)
23  : m_container(container)
24  , m_t(t)
25  , m_phase(IteratorPhase::Forward)
26 {
27  if (m_t.is_null()) {
28  return;
29  }
30 
31  init(depth());
32 }
33 
35 {
36  switch (depth()) {
37  case 0: return step_depth_0();
38  case 1: return step_depth_1();
39  case 2: return step_depth_2();
40  case 3: return step_depth_3();
41  default: break;
42  }
43 
44  assert(false); // unknown simplex or mesh type
45  m_t = Tuple();
46  return *this;
47 }
48 
50 {
51  return m_t != other.m_t;
52 }
53 
55 {
56  return m_t;
57 }
58 
60 {
61  return m_t;
62 }
63 
65 {
66  return get_primitive_type_from_id(m_container.m_mesh.top_cell_dimension() - depth);
67 }
68 
70 {
71  const Mesh& mesh = m_container.m_mesh;
72  const simplex::Simplex& simplex = m_container.m_simplex;
73  assert(mesh.top_cell_dimension() >= get_primitive_type_id(simplex.primitive_type()));
74  assert(mesh.top_cell_dimension() - get_primitive_type_id(simplex.primitive_type()) < 4);
75 
76  return mesh.top_cell_dimension() - get_primitive_type_id(simplex.primitive_type());
77 }
78 
80 {
81  const Mesh& mesh = m_container.m_mesh;
82  const simplex::Simplex& simplex = m_container.m_simplex;
83  // No initialization necessary if simplex is d or d-1.
84 
85  if (depth == 2) {
86  // d - 2 --> iteration
87 
88  // check if forward or backward phase can be executed
89  if (mesh.is_boundary(pt(1), m_t)) {
90  m_phase = IteratorPhase::Intermediate;
91  }
92  } else if (depth == 3) {
93  // d - 3 --> BFS
94  m_container.m_visited.is_visited(wmtk::utils::TupleInspector::global_cid(m_t));
95 
96  add_neighbors_to_queue();
97  }
98 }
99 
101 {
102  m_t = Tuple();
103  return *this;
104 }
105 
107 {
108  const Mesh& mesh = m_container.m_mesh;
109  const simplex::Simplex& simplex = m_container.m_simplex;
110 
111  if (m_phase == IteratorPhase::End || mesh.is_boundary(pt(1), m_t)) {
112  m_t = Tuple();
113  return *this;
114  } else {
115  m_t = mesh.switch_tuple(m_t, pt(0));
116  m_phase = IteratorPhase::End;
117  return *this;
118  }
119 }
120 
122 {
123  const Mesh& mesh = m_container.m_mesh;
124  const simplex::Simplex& simplex = m_container.m_simplex;
125 
126  m_is_intermediate = false;
127 
128  if (m_phase == IteratorPhase::Intermediate) {
129  // go to opposite of input
130  m_t = mesh.switch_tuple(simplex.tuple(), pt(1));
131  if (mesh.is_boundary(pt(1), m_t)) {
132  m_phase = IteratorPhase::End;
133  } else {
134  // switch to backward phase
135  m_phase = IteratorPhase::Backward;
136  }
137  if (m_container.m_retrieve_intermediate_tuple) {
138  m_is_intermediate = true;
139  return *this;
140  }
141  }
142 
143  if (m_phase == IteratorPhase::End) {
144  m_t = Tuple();
145  return *this;
146  }
147 
148  m_t = mesh.switch_tuples(m_t, {pt(0), pt(1)});
149 
150  if (m_t == simplex.tuple()) {
151  m_t = Tuple();
152  return *this;
153  }
154 
155  if (mesh.is_boundary(pt(1), m_t)) {
156  if (m_phase == IteratorPhase::Forward) {
157  m_phase = IteratorPhase::Intermediate;
158  } else {
159  m_phase = IteratorPhase::End;
160  }
161  }
162 
163  return *this;
164 }
165 
167 {
168  const Mesh& mesh = m_container.m_mesh;
169  auto& q = m_container.m_q;
170  auto& q_front = m_container.m_q_front;
171 
172  if (q_front == q.size()) {
173  m_t = Tuple();
174  return *this;
175  }
176 
177  m_t = q[q_front++];
178 
179  add_neighbors_to_queue();
180 
181 
182  return *this;
183 }
184 
186 {
187  const Mesh& mesh = m_container.m_mesh;
188  const simplex::Simplex& simplex = m_container.m_simplex;
189 
191  assert(simplex.primitive_type() == PrimitiveType::Vertex);
192 
193  Tuple t = m_t;
194  for (size_t i = 0; i < 3; ++i) {
195  if (!mesh.is_boundary(PrimitiveType::Triangle, t)) {
196  const Tuple neigh = mesh.switch_tuple(t, PrimitiveType::Tetrahedron);
197  const int64_t neigh_id = wmtk::utils::TupleInspector::global_cid(neigh);
198 
199  if (!m_container.m_visited.is_visited(neigh_id)) {
200  m_container.m_q.emplace_back(neigh);
201  }
202  }
204  }
205 }
206 
208 {
209  return m_is_intermediate;
210 }
211 
212 } // namespace wmtk::simplex
bool is_boundary(const simplex::Simplex &tuple) const
check if a simplex lies on a boundary or not
Definition: Mesh.cpp:106
Tuple switch_tuples(const Tuple &tuple, const ContainerType &op_sequence) const
Definition: Mesh.hpp:967
int64_t top_cell_dimension() const
Definition: Mesh.hpp:992
virtual Tuple switch_tuple(const Tuple &tuple, PrimitiveType type) const =0
switch the orientation of the Tuple of the given dimension
PrimitiveType top_simplex_type() const
Definition: Mesh.hpp:996
bool is_null() const
Checks if a tuple is "null". This merely implies the global index is -1.
Definition: Tuple.hxx:40
const Tuple & tuple() const
Definition: Simplex.hpp:53
PrimitiveType primitive_type() const
Definition: Simplex.hpp:51
Iterator & step_depth_1()
There are at max two d-simplices.
PrimitiveType pt(int64_t depth) const
Get the d - depth primitive type.
Iterator & step_depth_0()
Just return the simplex and stop.
int64_t depth()
Compute the depth from the mesh and the simplex type.
Iterator(TopDimensionCofacesIterable &container, const Tuple &t=Tuple())
void init(int64_t depth)
Depending on the depth, the iterator must be initialized differently.
Iterator & step_depth_2()
Iterate around simplex to find all d-simplices.
Iterator & step_depth_3()
Use breadth first search to find all d-simplices.
Iterating through the d-simplices of a mesh can be done in different ways, depending on the simplex d...
IteratorPhase
The IteratorPhase is only used for depth 1 and 2.
TopDimensionCofacesIterable(const Mesh &mesh, const Simplex &simplex, const bool retrieve_intermediate_tuple=false)
static int64_t global_cid(const Tuple &t)
constexpr PrimitiveType get_primitive_type_from_id(int8_t id)
Get the primitive type corresponding to its unique integer id.
constexpr int8_t get_primitive_type_id(PrimitiveType t)
Get a unique integer id corresponding to each primitive type.