Wildmeshing Toolkit
TetMesh.cpp
Go to the documentation of this file.
1 #include "TetMesh.hpp"
2 
3 
5 #include <numeric>
11 #include <wmtk/utils/Logger.hpp>
12 
13 namespace wmtk {
14 
15 using namespace autogen;
16 TetMesh::~TetMesh() = default;
17 
19  : MeshCRTP<TetMesh>(3)
20  , m_vt_handle(register_attribute_typed<int64_t>("m_vt", PrimitiveType::Vertex, 1, false, -1))
21  , m_et_handle(register_attribute_typed<int64_t>("m_et", PrimitiveType::Edge, 1, false, -1))
22  , m_ft_handle(register_attribute_typed<int64_t>("m_ft", PrimitiveType::Triangle, 1, false, -1))
23  , m_tv_handle(
24  register_attribute_typed<int64_t>("m_tv", PrimitiveType::Tetrahedron, 4, false, -1))
25  , m_te_handle(
26  register_attribute_typed<int64_t>("m_te", PrimitiveType::Tetrahedron, 6, false, -1))
27  , m_tf_handle(
28  register_attribute_typed<int64_t>("m_tf", PrimitiveType::Tetrahedron, 4, false, -1))
29  , m_tt_handle(
30  register_attribute_typed<int64_t>("m_tt", PrimitiveType::Tetrahedron, 4, false, -1))
31 {
33 }
34 
35 
37  : MeshCRTP<TetMesh>(std::move(o))
38 {
39  m_vt_handle = o.m_vt_handle;
40  m_et_handle = o.m_et_handle;
41  m_ft_handle = o.m_ft_handle;
42  m_tv_handle = o.m_tv_handle;
43  m_te_handle = o.m_te_handle;
44  m_tf_handle = o.m_tf_handle;
45  m_tt_handle = o.m_tt_handle;
46 
48 }
50 {
51  Mesh::operator=(std::move(o));
52  m_vt_handle = o.m_vt_handle;
53  m_et_handle = o.m_et_handle;
54  m_ft_handle = o.m_ft_handle;
55  m_tv_handle = o.m_tv_handle;
56  m_te_handle = o.m_te_handle;
57  m_tf_handle = o.m_tf_handle;
58  m_tt_handle = o.m_tt_handle;
59 
61  return *this;
62 }
63 
64 
66 {
67  m_vt_accessor = std::make_unique<attribute::Accessor<int64_t, TetMesh>>(*this, m_vt_handle);
68  m_et_accessor = std::make_unique<attribute::Accessor<int64_t, TetMesh>>(*this, m_et_handle);
69  m_ft_accessor = std::make_unique<attribute::Accessor<int64_t, TetMesh>>(*this, m_ft_handle);
70 
71  m_tv_accessor = std::make_unique<attribute::Accessor<int64_t, TetMesh>>(*this, m_tv_handle);
72  m_te_accessor = std::make_unique<attribute::Accessor<int64_t, TetMesh>>(*this, m_te_handle);
73  m_tf_accessor = std::make_unique<attribute::Accessor<int64_t, TetMesh>>(*this, m_tf_handle);
74  m_tt_accessor = std::make_unique<attribute::Accessor<int64_t, TetMesh>>(*this, m_tt_handle);
75 }
76 
77 
79  Eigen::Ref<const RowVectors4l> TV,
80  Eigen::Ref<const RowVectors6l> TE,
81  Eigen::Ref<const RowVectors4l> TF,
82  Eigen::Ref<const RowVectors4l> TT,
83  Eigen::Ref<const VectorXl> VT,
84  Eigen::Ref<const VectorXl> ET,
85  Eigen::Ref<const VectorXl> FT)
86 
87 {
88  // reserve memory for attributes
89 
90  std::vector<int64_t> cap{
91  static_cast<int64_t>(VT.rows()),
92  static_cast<int64_t>(ET.rows()),
93  static_cast<int64_t>(FT.rows()),
94  static_cast<int64_t>(TT.rows())};
95  set_capacities(cap);
96 
97  // get Accessors for topology
98  auto vt_accessor = create_accessor<int64_t>(m_vt_handle);
99  auto et_accessor = create_accessor<int64_t>(m_et_handle);
100  auto ft_accessor = create_accessor<int64_t>(m_ft_handle);
101  auto tv_accessor = create_accessor<int64_t>(m_tv_handle);
102  auto te_accessor = create_accessor<int64_t>(m_te_handle);
103  auto tf_accessor = create_accessor<int64_t>(m_tf_handle);
104  auto tt_accessor = create_accessor<int64_t>(m_tt_handle);
109 
110  // iterate over the matrices and fill attributes
111  for (int64_t i = 0; i < capacity(PrimitiveType::Tetrahedron); ++i) {
112  tv_accessor.index_access().vector_attribute<4>(i) = TV.row(i).transpose();
113  te_accessor.index_access().vector_attribute<6>(i) = TE.row(i).transpose();
114  tf_accessor.index_access().vector_attribute<4>(i) = TF.row(i).transpose();
115  tt_accessor.index_access().vector_attribute<4>(i) = TT.row(i).transpose();
116  t_flag_accessor.index_access().scalar_attribute(i) |= 0x1;
117  }
118  // m_vt
119  for (int64_t i = 0; i < capacity(PrimitiveType::Vertex); ++i) {
120  vt_accessor.index_access().scalar_attribute(i) = VT(i);
121  v_flag_accessor.index_access().scalar_attribute(i) |= 0x1;
122  }
123  // m_et
124  for (int64_t i = 0; i < capacity(PrimitiveType::Edge); ++i) {
125  et_accessor.index_access().scalar_attribute(i) = ET(i);
126  e_flag_accessor.index_access().scalar_attribute(i) |= 0x1;
127  }
128  // m_ft
129  for (int64_t i = 0; i < capacity(PrimitiveType::Triangle); ++i) {
130  ft_accessor.index_access().scalar_attribute(i) = FT(i);
131  f_flag_accessor.index_access().scalar_attribute(i) |= 0x1;
132  }
133 }
134 
135 
136 void TetMesh::initialize(Eigen::Ref<const RowVectors4l> T, bool is_free)
137 {
138  this->m_is_free = is_free;
139  auto [TE, TF, TT, VT, ET, FT] = tetmesh_topology_initialization(T);
140  if (is_free) {
141  TT.setConstant(-1);
142  }
143  initialize(T, TE, TF, TT, VT, ET, FT);
144 }
145 void TetMesh::initialize_free(int64_t count)
146 {
147  RowVectors4l S(count, 4);
148  std::iota(S.data(), S.data() + S.size(), int64_t(0));
149  initialize(S, true);
150 }
151 
153 {
154  int64_t t = m_vt_accessor->index_access().const_scalar_attribute(id);
155  auto tv = m_tv_accessor->index_access().const_vector_attribute<4>(t);
156  int64_t lvid = -1;
157 
158  for (int64_t i = 0; i < 4; ++i) {
159  if (tv(i) == id) {
160  lvid = i;
161  break;
162  }
163  }
164 
165  const auto [nlvid, leid, lfid] = autogen::tet_mesh::auto_3d_table_complete_vertex[lvid];
166  assert(lvid == nlvid);
167 
168  if (lvid < 0 || leid < 0 || lfid < 0) throw std::runtime_error("vertex_tuple_from_id failed");
169 
170  Tuple v_tuple = Tuple(lvid, leid, lfid, t);
171  assert(is_ccw(v_tuple));
172  assert(is_valid(v_tuple));
173  return v_tuple;
174 }
175 
177 {
178  int64_t t = m_et_accessor->index_access().const_scalar_attribute(id);
179  auto te = m_te_accessor->index_access().const_vector_attribute<6>(t);
180 
181  int64_t leid = -1;
182 
183  for (int64_t i = 0; i < 6; ++i) {
184  if (te(i) == id) {
185  leid = i;
186  break;
187  }
188  }
189  const auto [lvid, nleid, lfid] = autogen::tet_mesh::auto_3d_table_complete_edge[leid];
190  assert(leid == nleid);
191 
192 
193  if (lvid < 0 || leid < 0 || lfid < 0) throw std::runtime_error("edge_tuple_from_id failed");
194 
195  Tuple e_tuple = Tuple(lvid, leid, lfid, t);
196  assert(is_ccw(e_tuple));
197  assert(is_valid(e_tuple));
198  return e_tuple;
199 }
200 
202 {
203  int64_t t = m_ft_accessor->index_access().const_scalar_attribute(id);
204  auto tf = m_tf_accessor->index_access().const_vector_attribute<4>(t);
205 
206  int64_t lfid = -1;
207 
208  for (int64_t i = 0; i < 4; ++i) {
209  if (tf(i) == id) {
210  lfid = i;
211  break;
212  }
213  }
214 
215  const auto [lvid, leid, nlfid] = autogen::tet_mesh::auto_3d_table_complete_face[lfid];
216  assert(lfid == nlfid);
217 
218  if (lvid < 0 || leid < 0 || lfid < 0) throw std::runtime_error("face_tuple_from_id failed");
219 
220  Tuple f_tuple = Tuple(lvid, leid, lfid, t);
221  assert(is_ccw(f_tuple));
222  assert(is_valid(f_tuple));
223  return f_tuple;
224 }
225 
227 {
228  const int64_t lvid = 0;
229  const auto [nlvid, leid, lfid] = autogen::tet_mesh::auto_3d_table_complete_vertex[lvid];
230  assert(lvid == nlvid);
231 
232  Tuple t_tuple = Tuple(lvid, leid, lfid, id);
233  assert(is_ccw(t_tuple));
234  assert(is_valid(t_tuple));
235  return t_tuple;
236 }
237 
238 Tuple TetMesh::tuple_from_id(const PrimitiveType type, const int64_t gid) const
239 {
240  switch (type) {
241  case PrimitiveType::Vertex: {
242  return vertex_tuple_from_id(gid);
243  break;
244  }
245  case PrimitiveType::Edge: {
246  return edge_tuple_from_id(gid);
247  break;
248  }
250  return face_tuple_from_id(gid);
251  break;
252  }
254  return tet_tuple_from_id(gid);
255  break;
256  }
257  default: assert(false); // "Invalid primitive type"
258  }
259 
260  return Tuple();
261 }
262 
263 
265 {
266  assert(is_valid(tuple));
267  switch (type) {
268  // bool ccw = is_ccw(tuple);
270  assert(!is_boundary_face(tuple));
271  // need test
272  const int64_t gvid = id(tuple, PrimitiveType::Vertex);
273  const int64_t geid = id(tuple, PrimitiveType::Edge);
274  const int64_t gfid = id(tuple, PrimitiveType::Triangle);
275 
276  auto tt = m_tt_accessor->const_vector_attribute<4>(tuple);
277 
278  int64_t gcid_new = tt(tuple.m_local_fid);
279 
280  /*handle exception here*/
281  assert(gcid_new != -1);
282  // check if is_boundary allows removing this exception in 3d cases
283  // if (gcid_new == -1) {
284  // return Tuple(-1, -1, -1, -1, -1);
285  // }
286  /*handle exception end*/
287 
288  int64_t lvid_new = -1, leid_new = -1, lfid_new = -1;
289 
290  auto tv = m_tv_accessor->index_access().const_vector_attribute<4>(gcid_new);
291 
292  auto te = m_te_accessor->index_access().const_vector_attribute<6>(gcid_new);
293 
294  auto tf = m_tf_accessor->index_access().const_vector_attribute<4>(gcid_new);
295 
296  for (int64_t i = 0; i < 4; ++i) {
297  if (tv(i) == gvid) {
298  lvid_new = i;
299  }
300  if (tf(i) == gfid) {
301  lfid_new = i;
302  }
303  }
304 
305  for (int64_t i = 0; i < 6; ++i) {
306  if (te(i) == geid) {
307  leid_new = i;
308  break; // check if the break is correct
309  }
310  }
311 
312 
313  assert(lvid_new != -1);
314  assert(leid_new != -1);
315  assert(lfid_new != -1);
316 
317  const Tuple res(lvid_new, leid_new, lfid_new, gcid_new);
318  assert(is_valid(res));
319  return res;
320  }
322  case PrimitiveType::Edge:
324  default: return autogen::tet_mesh::local_switch_tuple(tuple, type);
325  }
326 }
327 
328 bool TetMesh::is_ccw(const Tuple& tuple) const
329 {
330  assert(is_valid(tuple));
331  return autogen::tet_mesh::is_ccw(tuple);
332 }
333 
334 bool TetMesh::is_valid(const Tuple& tuple) const
335 {
336  if (!Mesh::is_valid(tuple)) {
337  return false;
338  }
339  const bool is_connectivity_valid = tuple.m_local_vid >= 0 && tuple.m_local_eid >= 0 &&
340  tuple.m_local_fid >= 0 && tuple.m_global_cid >= 0 &&
342 
343  if (!is_connectivity_valid) {
344 #if !defined(NDEBUG)
345  logger().debug(
346  "tuple.m_local_vid={} >= 0 && tuple.m_local_eid={} >= 0 &&"
347  "tuple.m_local_fid={} >= 0 &&"
348  " tuple.m_global_cid={} >= 0 &&"
349  " autogen::tet_mesh::tuple_is_valid_for_ccw(tuple)={}",
350  tuple.m_local_vid,
351  tuple.m_local_eid,
352  tuple.m_local_fid,
353  tuple.m_global_cid,
355  assert(tuple.m_local_vid >= 0);
356  assert(tuple.m_local_eid >= 0);
357  assert(tuple.m_local_fid >= 0);
358  assert(tuple.m_global_cid >= 0);
360 #endif
361  return false;
362  }
363 
364  return true;
365 }
366 
367 bool TetMesh::is_boundary(PrimitiveType pt, const Tuple& tuple) const
368 {
369  switch (pt) {
370  case PrimitiveType::Vertex: return is_boundary_vertex(tuple);
371  case PrimitiveType::Edge: return is_boundary_edge(tuple);
372  case PrimitiveType::Triangle: return is_boundary_face(tuple);
374  default: break;
375  }
376  assert(
377  false); // "tried to compute the boundary of an tet mesh for an invalid simplex dimension"
378  return false;
379 }
380 
381 
382 bool TetMesh::is_boundary_face(const Tuple& tuple) const
383 {
384  const attribute::Accessor<int64_t> tt_accessor = create_const_accessor<int64_t>(m_tt_handle);
385  return tt_accessor.const_vector_attribute<4>(tuple)(tuple.m_local_fid) < 0;
386 }
387 
388 bool TetMesh::is_boundary_edge(const Tuple& edge) const
389 {
391  *this,
392  simplex::Simplex::edge(*this, edge),
394  if (is_boundary_face(f)) {
395  return true;
396  }
397  }
398  return false;
399 }
400 bool TetMesh::is_boundary_vertex(const Tuple& vertex) const
401 {
402  // go through all faces and check if they are boundary
403  const simplex::SimplexCollection neigh =
404  wmtk::simplex::open_star(*this, simplex::Simplex::vertex(*this, vertex));
406  if (is_boundary(s)) {
407  return true;
408  }
409  }
410 
411  return false;
412 }
413 
415 {
416  // get Accessors for topology
417  const attribute::Accessor<int64_t> tv_accessor = create_const_accessor<int64_t>(m_tv_handle);
418  const attribute::Accessor<int64_t> te_accessor = create_const_accessor<int64_t>(m_te_handle);
419  const attribute::Accessor<int64_t> tf_accessor = create_const_accessor<int64_t>(m_tf_handle);
420  const attribute::Accessor<int64_t> tt_accessor = create_const_accessor<int64_t>(m_tt_handle);
421  const attribute::Accessor<int64_t> vt_accessor = create_const_accessor<int64_t>(m_vt_handle);
422  const attribute::Accessor<int64_t> et_accessor = create_const_accessor<int64_t>(m_et_handle);
423  const attribute::Accessor<int64_t> ft_accessor = create_const_accessor<int64_t>(m_ft_handle);
428 
429  // VT and TV
430  for (int64_t i = 0; i < capacity(PrimitiveType::Vertex); ++i) {
431  if (v_flag_accessor.index_access().const_scalar_attribute(i) == 0) {
432  wmtk::logger().debug("Vertex {} is deleted", i);
433  continue;
434  }
435  int cnt = 0;
436  for (int j = 0; j < 4; ++j) {
437  if (tv_accessor.index_access().const_vector_attribute<4>(
438  vt_accessor.index_access().const_scalar_attribute(i))[j] == i) {
439  cnt++;
440  }
441  }
442  if (cnt != 1) {
443  wmtk::logger().info("fail VT and TV");
444  return false;
445  }
446  }
447 
448  // ET and TE
449  for (int64_t i = 0; i < capacity(PrimitiveType::Edge); ++i) {
450  if (e_flag_accessor.index_access().const_scalar_attribute(i) == 0) {
451  wmtk::logger().debug("Edge {} is deleted", i);
452  continue;
453  }
454  int cnt = 0;
455  for (int j = 0; j < 6; ++j) {
456  if (te_accessor.index_access().const_vector_attribute<6>(
457  et_accessor.index_access().const_scalar_attribute(i))[j] == i) {
458  cnt++;
459  }
460  }
461  if (cnt != 1) {
462  wmtk::logger().info("fail ET and TE");
463  return false;
464  }
465  }
466 
467  // FT and TF
468  for (int64_t i = 0; i < capacity(PrimitiveType::Triangle); ++i) {
469  if (f_flag_accessor.index_access().const_scalar_attribute(i) == 0) {
470  wmtk::logger().debug("Face {} is deleted", i);
471  continue;
472  }
473  int cnt = 0;
474  for (int j = 0; j < 4; ++j) {
475  if (tf_accessor.index_access().const_vector_attribute<4>(
476  ft_accessor.index_access().const_scalar_attribute(i))[j] == i) {
477  cnt++;
478  }
479  }
480  if (cnt != 1) {
481  wmtk::logger().info("fail FT and TF");
482  return false;
483  }
484  }
485 
486  // TF and TT
487  for (int64_t i = 0; i < capacity(PrimitiveType::Tetrahedron); ++i) {
488  if (t_flag_accessor.index_access().const_scalar_attribute(i) == 0) {
489  wmtk::logger().debug("Tet {} is deleted", i);
490  continue;
491  }
492 
493  for (int j = 0; j < 4; ++j) {
494  int64_t nb = tt_accessor.index_access().const_vector_attribute<4>(i)(j);
495  if (nb == -1) {
496  if (ft_accessor.index_access().const_scalar_attribute(
497  tf_accessor.index_access().const_vector_attribute<4>(i)(j)) != i) {
498  wmtk::logger().info("fail TF and TT 1");
499  return false;
500  }
501  continue;
502  }
503 
504  int cnt = 0;
505  int id_in_nb;
506  for (int k = 0; k < 4; ++k) {
507  if (tt_accessor.index_access().const_vector_attribute<4>(nb)(k) == i) {
508  cnt++;
509  id_in_nb = k;
510  }
511  }
512  if (cnt != 1) {
513  wmtk::logger().info("fail TF and TT 2");
514  return false;
515  }
516 
517  if (tf_accessor.index_access().const_vector_attribute<4>(i)(j) !=
518  tf_accessor.index_access().const_vector_attribute<4>(nb)(id_in_nb)) {
519  wmtk::logger().info("fail TF and TT 3");
520  return false;
521  }
522  }
523  }
524 
525  return true;
526 }
527 
528 std::vector<std::vector<TypedAttributeHandle<int64_t>>> TetMesh::connectivity_attributes() const
529 {
530  std::vector<std::vector<TypedAttributeHandle<int64_t>>> handles(4);
531 
532  handles[0].push_back(m_tv_handle);
533  handles[1].push_back(m_te_handle);
534  handles[2].push_back(m_tf_handle);
535 
536  handles[3].push_back(m_tt_handle);
537  handles[3].push_back(m_vt_handle);
538  handles[3].push_back(m_et_handle);
539  handles[3].push_back(m_ft_handle);
540 
541  return handles;
542 }
543 
544 Tuple TetMesh::tuple_from_global_ids(int64_t tid, int64_t fid, int64_t eid, int64_t vid) const
545 {
546  auto tv = m_tv_accessor->index_access().const_vector_attribute<4>(tid);
547  auto te = m_te_accessor->index_access().const_vector_attribute<6>(tid);
548  auto tf = m_tf_accessor->index_access().const_vector_attribute<4>(tid);
549 
550  int64_t lvid = -1, leid = -1, lfid = -1;
551 
552  for (int j = 0; j < 4; ++j) {
553  if (tv(j) == vid) {
554  lvid = j;
555  }
556  if (tf(j) == fid) {
557  lfid = j;
558  }
559  }
560 
561  for (int j = 0; j < 6; ++j) {
562  if (te(j) == eid) {
563  leid = j;
564  break;
565  }
566  }
567 
568  assert(lvid != -1);
569  assert(leid != -1);
570  assert(lfid != -1);
571 
572  return Tuple(lvid, leid, lfid, tid);
573 }
574 
575 std::vector<Tuple> TetMesh::orient_vertices(const Tuple& tuple) const
576 {
577  int64_t cid = tuple.m_global_cid;
578  return {Tuple(0, 0, 2, cid), Tuple(1, 0, 3, cid), Tuple(2, 1, 1, cid), Tuple(3, 2, 2, cid)};
579 }
580 
581 
582 } // namespace wmtk
A Curiously Recurring Template Pattern shim to enable generic specialization of functions.
Definition: MeshCRTP.hpp:24
int64_t id(const Tuple &tuple, PrimitiveType type) const
return the global id of the Tuple of the given dimension
Definition: Mesh.hpp:1020
bool m_is_free
Definition: Mesh.hpp:846
void set_capacities(std::vector< int64_t > capacities)
int64_t capacity(PrimitiveType type) const
read in the m_capacities return the upper bound for the number of entities of the given dimension
bool is_free() const
Definition: Mesh.hpp:987
virtual bool is_valid(const Tuple &tuple) const
check validity of tuple including its hash
Definition: Mesh.cpp:112
Mesh & operator=(const Mesh &other)=delete
const attribute::Accessor< char > get_flag_accessor(PrimitiveType type) const
Definition: Mesh.cpp:158
TypedAttributeHandle< int64_t > m_tt_handle
Definition: TetMesh.hpp:95
std::unique_ptr< attribute::Accessor< int64_t, TetMesh > > m_tv_accessor
Definition: TetMesh.hpp:101
TetMesh & operator=(const TetMesh &o)=delete
TypedAttributeHandle< int64_t > m_vt_handle
Definition: TetMesh.hpp:87
Tuple tuple_from_id(const PrimitiveType type, const int64_t gid) const final override
internal function that returns the tuple of requested type, and has the global index cid
Definition: TetMesh.cpp:238
bool is_boundary_vertex(const Tuple &tuple) const
Definition: TetMesh.cpp:400
std::unique_ptr< attribute::Accessor< int64_t, TetMesh > > m_et_accessor
Definition: TetMesh.hpp:98
void make_cached_accessors()
Definition: TetMesh.cpp:65
std::vector< std::vector< TypedAttributeHandle< int64_t > > > connectivity_attributes() const final override
Returns a vector of vectors of attribute handles.
Definition: TetMesh.cpp:528
std::unique_ptr< attribute::Accessor< int64_t, TetMesh > > m_tt_accessor
Definition: TetMesh.hpp:104
Tuple switch_tuple(const Tuple &tuple, PrimitiveType type) const final override
switch the orientation of the Tuple of the given dimension
Definition: TetMesh.cpp:264
Tuple tuple_from_global_ids(int64_t tid, int64_t fid, int64_t eid, int64_t vid) const
Definition: TetMesh.cpp:544
bool is_boundary(const simplex::Simplex &tuple) const
check if a simplex lies on a boundary or not
Definition: Mesh.cpp:106
TypedAttributeHandle< int64_t > m_tv_handle
Definition: TetMesh.hpp:92
bool is_boundary_edge(const Tuple &tuple) const
Definition: TetMesh.cpp:388
Tuple edge_tuple_from_id(int64_t id) const
Definition: TetMesh.cpp:176
Tuple face_tuple_from_id(int64_t id) const
Definition: TetMesh.cpp:201
void initialize_free(int64_t count)
Definition: TetMesh.cpp:145
Tuple tet_tuple_from_id(int64_t id) const
Definition: TetMesh.cpp:226
std::unique_ptr< attribute::Accessor< int64_t, TetMesh > > m_tf_accessor
Definition: TetMesh.hpp:103
TypedAttributeHandle< int64_t > m_tf_handle
Definition: TetMesh.hpp:94
bool is_ccw(const Tuple &tuple) const final override
TODO this needs dimension?
Definition: TetMesh.cpp:328
Tuple vertex_tuple_from_id(int64_t id) const
Definition: TetMesh.cpp:152
void initialize(Eigen::Ref< const RowVectors4l > TV, Eigen::Ref< const RowVectors6l > TE, Eigen::Ref< const RowVectors4l > TF, Eigen::Ref< const RowVectors4l > TT, Eigen::Ref< const VectorXl > VT, Eigen::Ref< const VectorXl > ET, Eigen::Ref< const VectorXl > FT)
Definition: TetMesh.cpp:78
TypedAttributeHandle< int64_t > m_te_handle
Definition: TetMesh.hpp:93
bool is_connectivity_valid() const final override
Definition: TetMesh.cpp:414
TypedAttributeHandle< int64_t > m_et_handle
Definition: TetMesh.hpp:89
std::unique_ptr< attribute::Accessor< int64_t, TetMesh > > m_ft_accessor
Definition: TetMesh.hpp:99
TypedAttributeHandle< int64_t > m_ft_handle
Definition: TetMesh.hpp:90
~TetMesh() override
std::unique_ptr< attribute::Accessor< int64_t, TetMesh > > m_vt_accessor
Definition: TetMesh.hpp:97
std::unique_ptr< attribute::Accessor< int64_t, TetMesh > > m_te_accessor
Definition: TetMesh.hpp:102
bool is_valid(const Tuple &tuple) const final override
check validity of tuple including its hash
Definition: TetMesh.cpp:334
bool is_boundary_face(const Tuple &tuple) const
Definition: TetMesh.cpp:382
std::vector< Tuple > orient_vertices(const Tuple &t) const override
Definition: TetMesh.cpp:575
int8_t m_local_vid
Definition: Tuple.hpp:47
int8_t m_local_eid
Definition: Tuple.hpp:48
int64_t m_global_cid
Definition: Tuple.hpp:46
int8_t m_local_fid
Definition: Tuple.hpp:49
A CachingAccessor that uses tuples for accessing attributes instead of indices.
Definition: Accessor.hpp:25
CachingBaseType & index_access()
Definition: Accessor.hpp:95
ConstMapResult< D > const_vector_attribute(const ArgType &t) const
T const_scalar_attribute(const int64_t index) const
T & scalar_attribute(const int64_t index)
ConstMapResult< D > const_vector_attribute(const int64_t index) const
const std::vector< Simplex > & simplex_vector() const
Return const reference to the simplex vector.
static Simplex edge(const Mesh &m, const Tuple &t)
Definition: Simplex.hpp:61
static Simplex vertex(const Mesh &m, const Tuple &t)
Definition: Simplex.hpp:56
Definition: autodiff.h:995
bool tuple_is_valid_for_ccw(const Tuple &t)
Definition: is_ccw.hxx:17
Tuple local_switch_tuple(const Tuple &t, PrimitiveType pt)
bool is_ccw(const Tuple &t)
Definition: is_ccw.hxx:10
const int64_t auto_3d_table_complete_vertex[4][3]
const int64_t auto_3d_table_complete_face[4][3]
const int64_t auto_3d_table_complete_edge[6][3]
SimplexCollection open_star(const Mesh &mesh, const Simplex &simplex, const bool sort_and_clean)
Definition: open_star.cpp:12
CofacesSingleDimensionIterable cofaces_single_dimension_iterable(const Mesh &mesh, const Simplex &simplex, const PrimitiveType cofaces_type)
Definition: Accessor.hpp:6
RowVectors< int64_t, 4 > RowVectors4l
Definition: Types.hpp:48
spdlog::logger & logger()
Retrieves the current logger.
Definition: Logger.cpp:58
std::tuple< RowVectors6l, RowVectors4l, RowVectors4l, VectorXl, VectorXl, VectorXl > tetmesh_topology_initialization(Eigen::Ref< const RowVectors4l > T)
Given the mesh connectivity in matrix format, finds unique edges and faces and their relations.