Wildmeshing Toolkit
LinkIterable.cpp
Go to the documentation of this file.
1 #include "LinkIterable.hpp"
2 
7 #include <wmtk/utils/Logger.hpp>
9 
10 namespace wmtk::simplex {
11 
12 
13 LinkIterable::LinkIterable(const Mesh& mesh, const Simplex& simplex)
14  : m_mesh(mesh)
15  , m_simplex(simplex)
16  , m_tdc_itrbl(mesh, simplex, true)
17  , m_it_end(m_tdc_itrbl.end())
18 {}
19 
21  : m_container(container)
22  , m_it(container.m_tdc_itrbl, t)
23  , m_t(t)
24 {
25  if (m_t.is_null()) {
26  return;
27  }
28 
29  // check if link exists
30  {
31  const int8_t m = m_container.m_mesh.top_cell_dimension();
33  if (m <= s) {
34  logger().warn("Trying to retrieve link that cannot exist!");
35  m_t = Tuple();
36  return;
37  }
38  }
39 
40  init();
41 }
42 
44 {
45  if (depth() == 3) {
46  return step_depth_3();
47  }
48 
49  const Mesh& mesh = m_container.m_mesh;
50  const simplex::Simplex& simplex = m_container.m_simplex;
51  const int8_t m = mesh.top_cell_dimension();
52  const int8_t s = get_primitive_type_id(simplex.primitive_type());
53 
54  if (m_pt < m - s - 1 && !m_it.is_intermediate()) {
55  // go to next primitive type
56  ++m_pt;
57  } else {
58  m_pt = 0;
59  // change tuple
60  ++m_it;
61  m_t = navigate_to_link(*m_it);
62  }
63 
64  return *this;
65 }
66 
68 {
69  return (m_t != other.m_t) || (m_pt != other.m_pt);
70 }
71 
73 {
74  return m_container.m_mesh.get_id_simplex(m_t, get_primitive_type_from_id(m_pt));
75 }
76 
78 {
79  return m_container.m_mesh.get_id_simplex(m_t, get_primitive_type_from_id(m_pt));
80 }
81 
83 {
84  const Mesh& mesh = m_container.m_mesh;
85  const simplex::Simplex& simplex = m_container.m_simplex;
86  assert(mesh.top_cell_dimension() >= get_primitive_type_id(simplex.primitive_type()));
87  assert(mesh.top_cell_dimension() - get_primitive_type_id(simplex.primitive_type()) < 4);
88 
89  return mesh.top_cell_dimension() - get_primitive_type_id(simplex.primitive_type());
90 }
91 
93 {
94  m_t = navigate_to_link(*m_it);
95 
96  if (depth() == 3) {
97  const Mesh& mesh = m_container.m_mesh;
98 
99  m_container.m_visited_link[m_pt].is_visited(
100  mesh.get_id_simplex(m_t, get_primitive_type_from_id(m_pt)));
101  }
102 }
103 
105 {
106  const Mesh& mesh = m_container.m_mesh;
107  const simplex::Simplex& simplex = m_container.m_simplex;
108  auto& visited = m_container.m_visited_link;
109 
110  ++m_pt;
111 
112  if (m_pt == 3) {
113  // go to next cell
114  m_pt = 0;
115  m_edge_counter = 0;
116  ++m_it;
117  m_t = navigate_to_link(*m_it);
118  if (m_t.is_null()) {
119  return *this;
120  }
121  }
122 
123  for (; m_edge_counter < 3; ++m_edge_counter) {
124  for (; m_pt < 2; ++m_pt) {
125  if (!visited[m_pt].is_visited(
126  mesh.get_id_simplex(m_t, get_primitive_type_from_id(m_pt)))) {
127  return *this;
128  }
129  }
131  m_pt = 0;
132  }
133 
134  // return face
135  m_pt = 2;
136  return *this;
137 }
138 
140 {
141  if (t.is_null()) {
142  return t;
143  }
144  // invert the simplex using SimplexDart
145  const Mesh& mesh = m_container.m_mesh;
146  // const PrimitiveType& mesh_pt = mesh.top_simplex_type();
147  // autogen::SimplexDart sd(mesh_pt);
148 
149  // switch (mesh.top_simplex_type()) {
150  // case PrimitiveType::Triangle: {
151  // const int8_t index_switch = sd.product(
152  // sd.primitive_as_index(PrimitiveType::Edge),
153  // sd.primitive_as_index(PrimitiveType::Vertex));
154  // m_t = autogen::local_switch_tuple(mesh_pt, m_t, index_switch);
155  // break;
156  // }
157  // default: log_and_throw_error("missing mesh navigation in link"); break;
158  // }
159 
160  {
161  /*
162  * Assume a tuple that contains the vertices (a,b,c,d) and the simplex is an edge, i.e.,
163  * (a,b). The link contains all the vertices that are not in the simplex. To get a tuple
164  * that represents all simplices of the link, we need to move (a,b) to the end of that
165  * tuple.
166  * (a,b,c,d) becomes (c,d,a,b) with the following permutations
167  * (a,b,c,d)
168  * switch edge: (a,c,b,d)
169  * switch face: (a,c,d,b)
170  * switch vert: (c,a,d,b)
171  * switch edge: (c,d,a,b)
172  *
173  * The following code implements these permutations.
174  */
175  const simplex::Simplex& simplex = m_container.m_simplex;
176  const int8_t m = mesh.top_cell_dimension();
177  const int8_t s = get_primitive_type_id(simplex.primitive_type());
178 
179  for (int8_t j = s; j > -1; --j) {
180  for (int8_t i = 0; i < m - s; ++i) {
181  t = mesh.switch_tuple(t, get_primitive_type_from_id(j + i));
182  }
183  }
184  }
185 
186  return t;
187 }
188 
189 } // namespace wmtk::simplex
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
simplex::IdSimplex get_id_simplex(const Tuple &tuple, PrimitiveType pt) const
Retrieve the IdSimplex that is represented by the tuple and primitive type.
Definition: Mesh.cpp:28
bool is_null() const
Checks if a tuple is "null". This merely implies the global index is -1.
Definition: Tuple.hxx:40
PrimitiveType primitive_type() const
Definition: Simplex.hpp:51
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.
spdlog::logger & logger()
Retrieves the current logger.
Definition: Logger.cpp:58