Wildmeshing Toolkit
Loading...
Searching...
No Matches
UpdateEdgeOperationMultiMeshMapFunctor.cpp
Go to the documentation of this file.
2
3#include <wmtk/EdgeMesh.hpp>
4#include <wmtk/Mesh.hpp>
5#include <wmtk/PointMesh.hpp>
6#include <wmtk/TetMesh.hpp>
7#include <wmtk/TriMesh.hpp>
10
11#include <wmtk/utils/Logger.hpp>
12
13
15
16namespace {
17constexpr static PrimitiveType PV = PrimitiveType::Vertex;
18constexpr static PrimitiveType PE = PrimitiveType::Edge;
21} // namespace
23 Mesh& m,
24 const std::vector<std::vector<std::tuple<int64_t, std::vector<Tuple>>>>& simplices_to_update,
25 const std::vector<std::tuple<int64_t, std::array<int64_t, 2>>>& split_cell_maps) const
26{
27 // assert(m.top_cell_dimension() + 1 == simplices_to_update.size());
28 constexpr static PrimitiveType PTs[] = {PV, PE, PF, PT};
29 // logger().trace("{} {}", m.top_cell_dimension(), simplices_to_update.size());
30 for (size_t j = 0; j < simplices_to_update.size(); ++j) {
32 .update_map_tuple_hashes(m, PTs[j], simplices_to_update[j], split_cell_maps);
33 }
34}
35
36
38 TriMesh& m,
39 const tri_mesh::EdgeOperationData& fmoe) const
40{
41 const auto& parent_incident_datas = fmoe.incident_face_datas();
42 auto& parent_mmmanager = m.m_multi_mesh_manager;
43 const auto& parent_incident_vids = fmoe.incident_vids();
44
45 for (const auto& parent_data : parent_incident_datas) {
46 // std::cout << parent_data.fid << " has been processed" << std::endl;
47
48 for (auto child_ptr : m.get_child_meshes()) {
49 // no ear replcaement required for free child meshes
50 if (child_ptr->is_free()) {
51 continue;
52 }
53 if (child_ptr->top_cell_dimension() != 1) {
54 continue; // only deal with child edgemeshes
55 }
56
57 const auto& child_mmmanager = child_ptr->m_multi_mesh_manager;
58 int64_t child_id = child_mmmanager.child_id();
59 auto child_to_parent_handle = child_mmmanager.map_to_parent_handle;
60 auto parent_to_child_handle = parent_mmmanager.children().at(child_id).map_handle;
61 auto child_to_parent_accessor = child_ptr->create_accessor(child_to_parent_handle);
62 auto parent_to_child_accessor = m.create_accessor(parent_to_child_handle);
63 auto child_cell_flag_accessor = child_ptr->get_const_flag_accessor(PrimitiveType::Edge);
64
65 std::vector<std::pair<Tuple, Tuple>> update_pairs;
66
67 for (int ear_index = 0; ear_index < 2; ++ear_index) {
68 const int64_t parent_ear_eid_old = parent_data.ears[ear_index].eid;
69 const int64_t parent_merged_eid = parent_data.new_edge_id;
70 const int64_t parent_new_fid = parent_data.merged_edge_fid;
71
72
73 assert(parent_merged_eid != -1);
74 assert(parent_new_fid != -1);
75
76 auto parent_to_child_data = Mesh::get_index_access(parent_to_child_accessor)
77 .const_vector_attribute(parent_ear_eid_old);
78
79 Tuple parent_tuple, child_tuple;
80 std::tie(parent_tuple, child_tuple) =
82
83 if (child_tuple.is_null()) {
84 // not child_tuple on this parent edge
85 continue;
86 }
87
88
89 // check also the flag accessor of child mesh
90 const bool child_tuple_exists = child_cell_flag_accessor.is_active(child_tuple);
91 if (!child_tuple_exists) {
92 continue;
93 }
94
95 const int64_t parent_old_vid =
96 m.parent_scope([&]() { return m.id_vertex(parent_tuple); });
97
98
99 int64_t parent_new_vid = -1;
100
101 if (parent_ear_eid_old != parent_merged_eid) {
102 // other side
103 if (parent_old_vid == parent_incident_vids[0]) {
104 parent_new_vid = parent_incident_vids[1];
105 } else {
106 parent_new_vid = parent_old_vid;
107 }
108 } else {
109 // same side
110 parent_new_vid = parent_old_vid;
111 }
112
113 assert(parent_new_vid != -1);
114
115 Tuple new_parent_tuple =
116 m.tuple_from_global_ids(parent_new_fid, parent_merged_eid, parent_new_vid);
117
118 update_pairs.push_back(std::make_pair(new_parent_tuple, child_tuple));
119 }
120
121 for (const auto& pair : update_pairs) {
123 parent_to_child_accessor,
124 child_to_parent_accessor,
125 pair.first,
126 pair.second);
127 }
128 }
129 }
130}
131
133 TetMesh& m,
134 const tet_mesh::EdgeOperationData& tmoe) const
135{
136 const auto& parent_incident_tet_datas = tmoe.incident_tet_datas();
137 const auto& parent_incident_face_datas = tmoe.incident_face_datas();
138 auto parent_mmmanager = m.m_multi_mesh_manager;
139
140 for (const auto& parent_data : parent_incident_tet_datas) {
141 for (auto child_ptr : m.get_child_meshes()) {
142 // no ear replcaement required for free child meshes
143 if (child_ptr->is_free()) {
144 continue;
145 }
146 if (child_ptr->top_cell_dimension() == 2) {
147 // handle with child tri mesh
148 // update merge faces here
149 const auto& child_mmmanager = child_ptr->m_multi_mesh_manager;
150 const int64_t child_id = child_mmmanager.child_id();
151 const auto child_to_parent_handle = child_mmmanager.map_to_parent_handle;
152 const auto parent_to_child_handle =
153 parent_mmmanager.children().at(child_id).map_handle;
154 auto child_to_parent_accessor = child_ptr->create_accessor(child_to_parent_handle);
155 auto parent_to_child_accessor = m.create_accessor(parent_to_child_handle);
156 auto child_cell_flag_accessor =
157 child_ptr->get_const_flag_accessor(PrimitiveType::Triangle);
158
159 std::vector<std::pair<Tuple, Tuple>> update_pairs;
160
161 for (int ear_index = 0; ear_index < 2; ++ear_index) {
162 const int64_t parent_ear_fid_old = parent_data.ears[ear_index].fid;
163 const int64_t parent_merged_fid = parent_data.new_face_id;
164 const int64_t parent_new_tid =
165 parent_data.merged_face_tid; // can be move to outer loop
166
167 assert(parent_merged_fid != -1);
168 assert(parent_new_tid != -1);
169
170 auto parent_to_child_data = Mesh::get_index_access(parent_to_child_accessor)
171 .const_vector_attribute(parent_ear_fid_old);
172
173 // TUPLE_SIZE is the number of tuples in terms of lon
174 Tuple parent_tuple, child_tuple;
175 std::tie(parent_tuple, child_tuple) =
176 wmtk::multimesh::utils::vectors_to_tuples(parent_to_child_data);
177
178 if (child_tuple.is_null()) {
179 // not child_tuple on this parent face
180 continue;
181 }
182
183
184 bool child_tuple_exists = child_cell_flag_accessor.is_active(child_tuple);
185 if (!child_tuple_exists) {
186 continue;
187 }
188
189 const int64_t parent_old_eid =
190 m.parent_scope([&]() { return m.id_edge(parent_tuple); });
191 const int64_t parent_old_vid =
192 m.parent_scope([&]() { return m.id_vertex(parent_tuple); });
193
194
195 // get the corresponding new eid and vid of parent
196 int64_t parent_new_eid = -1;
197 int64_t parent_new_vid = -1;
198
199 if (parent_ear_fid_old != parent_merged_fid) {
200 // other side
201 if (parent_old_eid == parent_data.e02) {
202 parent_new_eid = parent_data.e12;
203 } else if (parent_old_eid == parent_data.e03) {
204 parent_new_eid = parent_data.e13;
205 } else if (parent_old_eid == parent_data.e23) {
206 parent_new_eid = parent_data.e23;
207 }
208
209 if (parent_old_vid == parent_data.v0) {
210 parent_new_vid = parent_data.v1;
211 } else if (parent_old_vid == parent_data.v2) {
212 parent_new_vid = parent_data.v2;
213 } else if (parent_old_vid == parent_data.v3) {
214 parent_new_vid = parent_data.v3;
215 }
216 } else {
217 // same side
218 parent_new_eid = parent_old_eid;
219 parent_new_vid = parent_old_vid;
220 }
221
222 assert(parent_new_eid != -1);
223 assert(parent_new_vid != -1);
224
225 Tuple new_parent_tuple = m.tuple_from_global_ids(
226 parent_new_tid,
227 parent_merged_fid,
228 parent_new_eid,
229 parent_new_vid);
230
231 update_pairs.push_back(std::make_pair(new_parent_tuple, child_tuple));
232 }
233
234 for (const auto& pair : update_pairs) {
236 parent_to_child_accessor,
237 child_to_parent_accessor,
238 pair.first,
239 pair.second);
240 }
241
242 } else if (child_ptr->top_cell_dimension() == 1) {
243 // handle with child edge mesh
244 // update merge edges here
245 // there are three ear edges per side
246 const auto& child_mmmanager = child_ptr->m_multi_mesh_manager;
247 int64_t child_id = child_mmmanager.child_id();
248 auto child_to_parent_handle = child_mmmanager.map_to_parent_handle;
249 auto parent_to_child_handle = parent_mmmanager.children().at(child_id).map_handle;
250 auto child_to_parent_accessor = child_ptr->create_accessor(child_to_parent_handle);
251 auto parent_to_child_accessor = m.create_accessor(parent_to_child_handle);
252 auto child_cell_flag_accessor =
253 child_ptr->get_const_flag_accessor(PrimitiveType::Edge);
254
255 std::vector<std::pair<Tuple, Tuple>> update_pairs;
256
257 for (int ear_index = 0; ear_index < 2; ++ear_index) {
258 const int64_t parent_ear_fid_old = parent_data.ears[ear_index].fid;
259 const int64_t parent_merged_fid = parent_data.new_face_id;
260 const int64_t parent_new_tid = parent_data.merged_face_tid;
261
262
263 std::array<int64_t, 3> parent_old_eids;
264 std::array<int64_t, 3> parent_new_eids = {
265 {parent_data.e12, parent_data.e13, parent_data.e23}};
266
267 if (parent_ear_fid_old != parent_merged_fid) {
268 parent_old_eids = {{parent_data.e02, parent_data.e03, parent_data.e23}};
269 } else {
270 parent_old_eids = {{parent_data.e12, parent_data.e13, parent_data.e23}};
271 }
272
273
274 assert(parent_merged_fid != -1);
275 assert(parent_new_tid != -1);
276
277 for (int i = 0; i < 3; ++i) {
278 auto parent_to_child_data = Mesh::get_index_access(parent_to_child_accessor)
279 .const_vector_attribute(parent_old_eids[i]);
280
281
282 Tuple parent_tuple, child_tuple;
283 std::tie(parent_tuple, child_tuple) =
284 wmtk::multimesh::utils::vectors_to_tuples(parent_to_child_data);
285
286 if (child_tuple.is_null()) {
287 // not child_tuple on this parent edge
288 continue;
289 }
290
291
292 bool child_tuple_exists = child_cell_flag_accessor.is_active(child_tuple);
293 if (!child_tuple_exists) {
294 continue;
295 }
296
297 const int64_t parent_old_vid =
298 m.parent_scope([&]() { return m.id_vertex(parent_tuple); });
299
300 int64_t parent_new_vid = -1;
301 if (parent_ear_fid_old != parent_merged_fid) {
302 // other side
303 if (parent_old_vid == parent_data.v0) {
304 parent_new_vid = parent_data.v1;
305 } else if (parent_old_vid == parent_data.v2) {
306 parent_new_vid = parent_data.v2;
307 } else if (parent_old_vid == parent_data.v3) {
308 parent_new_vid = parent_data.v3;
309 }
310 } else {
311 // same side
312 parent_new_vid = parent_old_vid;
313 }
314
315 assert(parent_new_vid != -1);
316
317 Tuple new_parent_tuple = m.tuple_from_global_ids(
318 parent_new_tid,
319 parent_merged_fid,
320 parent_new_eids[i],
321 parent_new_vid);
322
323 update_pairs.push_back(std::make_pair(new_parent_tuple, child_tuple));
324 }
325
326 for (const auto& pair : update_pairs) {
328 parent_to_child_accessor,
329 child_to_parent_accessor,
330 pair.first,
331 pair.second);
332 }
333 }
334 }
335 }
336 }
337}
338
339
340// edge -> edge
342 EdgeMesh&,
343 const simplex::Simplex&,
344 const edge_mesh::EdgeOperationData& parent_tmoe,
345 EdgeMesh&,
346 const simplex::Simplex&,
347 const edge_mesh::EdgeOperationData&) const
348{
349 throw std::runtime_error("not implemented");
350}
351
352// tri -> edge
354 TriMesh& parent_mesh,
355 const simplex::Simplex&,
356 const tri_mesh::EdgeOperationData& parent_tmoe,
357 EdgeMesh& child_mesh,
358 const simplex::Simplex&,
359 const edge_mesh::EdgeOperationData& child_emoe) const
360{
361 const auto& parent_incident_datas = parent_tmoe.incident_face_datas();
362 const auto& parent_spine_v = parent_tmoe.incident_vids();
363
364 auto& parent_mmmanager = parent_mesh.m_multi_mesh_manager;
365 auto& child_mmmanager = child_mesh.m_multi_mesh_manager;
366 auto child_to_parent_handle = child_mmmanager.map_to_parent_handle;
367 int64_t child_id = child_mmmanager.child_id();
368 auto parent_to_child_handle = parent_mmmanager.children().at(child_id).map_handle;
369 auto child_to_parent_accessor = child_mesh.create_accessor(child_to_parent_handle);
370 auto parent_to_child_accessor = parent_mesh.create_accessor(parent_to_child_handle);
371
372
373 // update the new edges added by split
374 for (int64_t index = 0; index < 2; ++index) {
375 // we can choose f_parent on either side, here we choose 0
376 int64_t f_parent = parent_incident_datas[0].split_f[index];
377
378 const int64_t e_child = child_emoe.m_split_e[index];
379 const int64_t e_parent = parent_tmoe.split_spine_eids[index];
380
381 if (f_parent == -1 || e_child == -1 || e_parent == -1) {
382 continue;
383 }
384
385 const int64_t v_child = child_emoe.m_spine_vids[index];
386 const int64_t v_parent = parent_spine_v[index];
387
388 const Tuple parent_tuple = parent_mesh.tuple_from_global_ids(f_parent, e_parent, v_parent);
389 const Tuple child_tuple = child_mesh.tuple_from_global_ids(e_child, v_child);
390
391 assert(parent_mesh.is_valid(parent_tuple));
392 assert(child_mesh.is_valid(child_tuple));
393
395 parent_to_child_accessor,
396 child_to_parent_accessor,
397 parent_tuple,
398 child_tuple);
399 }
400}
401// tri -> tri
403 TriMesh& parent_mesh,
404 const simplex::Simplex&,
405 const tri_mesh::EdgeOperationData& parent_tmoe,
406 TriMesh& child_mesh,
407 const simplex::Simplex&,
408 const tri_mesh::EdgeOperationData& child_tmoe) const
409{
410 const auto& parent_incident_datas = parent_tmoe.incident_face_datas();
411 const auto& child_incident_datas = child_tmoe.incident_face_datas();
412
413 const auto& child_spine_v = child_tmoe.incident_vids();
414 const auto& parent_spine_v = parent_tmoe.incident_vids();
415
416
417 auto& parent_mmmanager = parent_mesh.m_multi_mesh_manager;
418 auto& child_mmmanager = child_mesh.m_multi_mesh_manager;
419
420 auto child_to_parent_handle = child_mmmanager.map_to_parent_handle;
421
422 int64_t child_id = child_mmmanager.child_id();
423 auto parent_to_child_handle = parent_mmmanager.children().at(child_id).map_handle;
424 auto child_to_parent_accessor = child_mesh.create_accessor(child_to_parent_handle);
425 auto parent_to_child_accessor = parent_mesh.create_accessor(parent_to_child_handle);
426
427 // logger().trace(
428 // "Child had {} datas, parent had {} datas",
429 // child_incident_datas.size(),
430 // child_incident_datas.size());
431
432 for (const auto& child_data : child_incident_datas) {
433 int64_t target_parent_fid = parent_global_cid(child_to_parent_accessor, child_data.fid);
434 // logger().trace(
435 // "[{}=>{}] child data started with gid {}->{} and parent had {}",
436 // fmt::join(parent_mesh.absolute_multi_mesh_id(), ","),
437 // fmt::join(child_mesh.absolute_multi_mesh_id(), ","),
438 // child_data.fid,
439 // fmt::join(child_data.split_f, ","),
440 // target_parent_fid);
441
442 for (const auto& parent_data : parent_incident_datas) {
443 // logger().trace(
444 // "Check for parent fid {} to be {} ({})",
445 // parent_data.fid,
446 // target_parent_fid,
447 // parent_data.fid == target_parent_fid);
448 if (parent_data.fid == target_parent_fid) {
449 // if there was a parent mapping we definitely need to update the edges
450 const auto& child_split_f = child_data.split_f;
451 const auto& parent_split_f = parent_data.split_f;
452
453
454 for (int64_t index = 0; index < 2; ++index) {
455 int64_t f_child = child_split_f[index];
456 int64_t f_parent = parent_split_f[index];
457 if (f_child == -1 || f_parent == -1) {
458 continue;
459 }
460
461 int64_t e_child = child_data.ears[index].eid;
462 int64_t e_parent = parent_data.ears[index].eid;
463
464 int64_t v_child = child_spine_v[index];
465 int64_t v_parent = parent_spine_v[index];
466
467 const Tuple parent_tuple =
468 parent_mesh.tuple_from_global_ids(f_parent, e_parent, v_parent);
469 const Tuple child_tuple =
470 child_mesh.tuple_from_global_ids(f_child, e_child, v_child);
471
472 assert(parent_mesh.is_valid(parent_tuple));
473 assert(child_mesh.is_valid(child_tuple));
474
476 parent_to_child_accessor,
477 child_to_parent_accessor,
478 parent_tuple,
479 child_tuple);
480 }
481 }
482 }
483 }
484
485 // update_hash on neighboring cells. use only 2 to get the cell types on either case
486 // constexpr static PrimitiveType PV = PrimitiveType::Vertex;
487 // constexpr static PrimitiveType PE = PrimitiveType::Edge;
488 // constexpr static PrimitiveType PF = PrimitiveType::Triangle;
489
490 // NOTE: this is purpuosely verbose to show a point
491 // We have to select with PrimitiveTypes are supported as children for each type of mesh
492 //
493 // logger().trace(
494 // "[{0}=>{1}] updating hashes for {0}",
495 // fmt::join(parent_mesh.absolute_multi_mesh_id(), ","),
496 // fmt::join(child_mesh.absolute_multi_mesh_id(), ","));
497 // logger().trace(
498 // "[{0}=>{1}] updating hashes for {1}",
499 // fmt::join(parent_mesh.absolute_multi_mesh_id(), ","),
500 // fmt::join(child_mesh.absolute_multi_mesh_id(), ","));
501
502 // update_all_hashes(child_mesh,
503 // child_tmoe.global_ids_to_potential_tuples);
504}
505
506// tet -> edge
508 TetMesh& parent_mesh,
509 const simplex::Simplex&,
510 const tet_mesh::EdgeOperationData& parent_tmoe,
511 EdgeMesh& child_mesh,
512 const simplex::Simplex&,
513 const edge_mesh::EdgeOperationData& child_emoe) const
514{
515 const auto& parent_incident_tet_datas = parent_tmoe.incident_tet_datas();
516 const auto& parent_incident_face_datas = parent_tmoe.incident_face_datas();
517
518 auto& parent_mmmanager = parent_mesh.m_multi_mesh_manager;
519 auto& child_mmmanager = child_mesh.m_multi_mesh_manager;
520
521 auto child_to_parent_handle = child_mmmanager.map_to_parent_handle;
522
523 int64_t child_id = child_mmmanager.child_id();
524 auto parent_to_child_handle = parent_mmmanager.children().at(child_id).map_handle;
525 auto child_to_parent_accessor = child_mesh.create_accessor(child_to_parent_handle);
526 auto parent_to_child_accessor = parent_mesh.create_accessor(parent_to_child_handle);
527
528 int64_t target_parent_tid =
529 parent_global_cid(child_to_parent_accessor, child_emoe.m_operating_edge_id);
530 int64_t target_parent_local_fid =
531 parent_local_fid(child_to_parent_accessor, child_emoe.m_operating_edge_id);
532 for (const auto& parent_data : parent_incident_tet_datas) {
533 if (parent_data.tid != target_parent_tid) continue;
534
535 int64_t face_index = -1; // shoule be 0 or 1 after if
536 for (int i = 0; i < 2; ++i) {
537 if (parent_data.incident_face_local_fid[i] == target_parent_local_fid) {
538 // target_parent_global_fid =
539 // parent_incident_face_datas[parent_data.incident_face_data_idx[i]].fid;
540 face_index = i;
541 }
542 }
543 assert(face_index != -1);
544
545 for (int index = 0; index < 2; ++index) {
546 const int64_t t_parent = parent_data.split_t[index];
547 const int64_t f_parent =
548 parent_incident_face_datas[parent_data.incident_face_data_idx[face_index]]
549 .split_f[index];
550
551 const int64_t e_parent = parent_tmoe.new_spine_eids()[index];
552 const int64_t e_child = child_emoe.m_split_e[index];
553
554 if (t_parent == -1 || f_parent == -1 || e_child == -1 || e_parent == -1) {
555 continue; // why?
556 }
557
558 const int64_t v_parent = parent_tmoe.incident_vids()[index];
559 const int64_t v_child =
560 child_emoe.m_spine_vids[index]; // these two tuples are in inversed direction, also
561 // for tet->tri and tri->edge, shall we change?
562
563 const Tuple parent_tuple =
564 parent_mesh.tuple_from_global_ids(t_parent, f_parent, e_parent, v_parent);
565 const Tuple child_tuple = child_mesh.tuple_from_global_ids(e_child, v_child);
566
567 assert(parent_mesh.is_valid(parent_tuple));
568 assert(child_mesh.is_valid(child_tuple));
569
571 parent_to_child_accessor,
572 child_to_parent_accessor,
573 parent_tuple,
574 child_tuple);
575 }
576 }
577}
578
579// tet -> tri
581 TetMesh& parent_mesh,
582 const simplex::Simplex&,
583 const tet_mesh::EdgeOperationData& parent_tmoe,
584 TriMesh& child_mesh,
585 const simplex::Simplex&,
586 const tri_mesh::EdgeOperationData& child_fmoe) const
587{
588 const auto& parent_incident_tet_datas = parent_tmoe.incident_tet_datas();
589 const auto& parent_incident_face_datas = parent_tmoe.incident_face_datas();
590
591 const auto& child_incident_face_datas = child_fmoe.incident_face_datas();
592
593 const auto& parent_spine_v = parent_tmoe.incident_vids();
594 const auto& child_spine_v = child_fmoe.incident_vids();
595
596 auto& parent_mmmanager = parent_mesh.m_multi_mesh_manager;
597 auto& child_mmmanager = child_mesh.m_multi_mesh_manager;
598
599 auto child_to_parent_handle = child_mmmanager.map_to_parent_handle;
600
601 int64_t child_id = child_mmmanager.child_id();
602 auto parent_to_child_handle = parent_mmmanager.children().at(child_id).map_handle;
603 auto child_to_parent_accessor = child_mesh.create_accessor(child_to_parent_handle);
604 auto parent_to_child_accessor = parent_mesh.create_accessor(parent_to_child_handle);
605
606 for (const auto& child_data : child_incident_face_datas) {
607 int64_t target_parent_tid = parent_global_cid(child_to_parent_accessor, child_data.fid);
608 // get parent local fid or global fid?
609 // try local here
610 int64_t target_parent_local_fid =
611 parent_local_fid(child_to_parent_accessor, child_data.fid);
612
613 for (const auto& parent_data : parent_incident_tet_datas) {
614 if (parent_data.tid != target_parent_tid) continue;
615 int64_t face_index = -1; // shoule be 0 or 1 after if
616 for (int i = 0; i < 2; ++i) {
617 if (parent_data.incident_face_local_fid[i] == target_parent_local_fid) {
618 // target_parent_global_fid =
619 // parent_incident_face_datas[parent_data.incident_face_data_idx[i]].fid;
620 face_index = i;
621 }
622 }
623 assert(face_index != -1);
624
625 for (int index = 0; index < 2; ++index) {
626 // should check if parent child tuples are in the same orientation
627 int64_t t_parent = parent_data.split_t[index];
628
629 int64_t f_child = child_data.split_f[index];
630 int64_t f_parent =
631 parent_incident_face_datas[parent_data.incident_face_data_idx[face_index]]
632 .split_f[index];
633
634 if (t_parent == -1 || f_child == -1 || f_parent == -1) {
635 continue;
636 }
637
638 int64_t e_child = child_data.ears[index].eid;
639 int64_t e_parent =
640 parent_incident_face_datas[parent_data.incident_face_data_idx[face_index]]
641 .ear_eids[index];
642
643 int64_t v_child = child_spine_v[index];
644 int64_t v_parent = parent_spine_v[index];
645
646 const Tuple parent_tuple =
647 parent_mesh.tuple_from_global_ids(t_parent, f_parent, e_parent, v_parent);
648 const Tuple child_tuple =
649 child_mesh.tuple_from_global_ids(f_child, e_child, v_child);
650
651 assert(parent_mesh.is_valid(parent_tuple));
652 assert(child_mesh.is_valid(child_tuple));
653
655 parent_to_child_accessor,
656 child_to_parent_accessor,
657 parent_tuple,
658 child_tuple);
659 }
660 }
661 }
662}
663
664// tet -> tet
666 TetMesh& parent_mesh,
667 const simplex::Simplex&,
668 const tet_mesh::EdgeOperationData& parent_tmoe,
669 TetMesh& child_mesh,
670 const simplex::Simplex&,
671 const tet_mesh::EdgeOperationData& child_tmoe) const
672{
673 const auto& parent_incident_tet_datas = parent_tmoe.incident_tet_datas();
674 const auto& child_incident_tet_datas = child_tmoe.incident_tet_datas();
675
676 const auto& parent_incident_face_datas = parent_tmoe.incident_face_datas();
677 const auto& child_incident_face_datas = child_tmoe.incident_face_datas();
678
679 const auto& parent_spine_v = parent_tmoe.incident_vids();
680 const auto& child_spine_v = child_tmoe.incident_vids();
681
682 auto& parent_mmmanager = parent_mesh.m_multi_mesh_manager;
683 auto& child_mmmanager = child_mesh.m_multi_mesh_manager;
684
685 auto child_to_parent_handle = child_mmmanager.map_to_parent_handle;
686
687 int64_t child_id = child_mmmanager.child_id();
688 auto parent_to_child_handle = parent_mmmanager.children().at(child_id).map_handle;
689 auto child_to_parent_accessor = child_mesh.create_accessor(child_to_parent_handle);
690 auto parent_to_child_accessor = parent_mesh.create_accessor(parent_to_child_handle);
691
692 for (const auto& child_data : child_incident_tet_datas) {
693 int64_t target_parent_tid = parent_global_cid(child_to_parent_accessor, child_data.tid);
694
695 for (const auto& parent_data : parent_incident_tet_datas) {
696 if (parent_data.tid != target_parent_tid) continue;
697 const auto& child_split_t = child_data.split_t;
698 const auto& parent_split_t = parent_data.split_t;
699
700 for (int64_t index = 0; index < 2; ++index) {
701 int64_t t_child = child_split_t[index];
702 int64_t t_parent = parent_split_t[index];
703
704 if (t_child == -1 || t_parent == -1) {
705 continue; // TODO: why need this check?
706 }
707
708 int64_t f_child = child_data.ears[index].fid;
709 int64_t f_parent = parent_data.ears[index].fid;
710
711 int64_t e_child =
712 child_incident_face_datas[child_data.incident_face_data_idx[1]].ear_eids[index];
713 int64_t e_parent = parent_incident_face_datas[parent_data.incident_face_data_idx[1]]
714 .ear_eids[index];
715
716 int64_t v_child = child_spine_v[index];
717 int64_t v_parent = parent_spine_v[index];
718
719 // TODO: why is this tuple selected? why not others?
720 const Tuple parent_tuple =
721 parent_mesh.tuple_from_global_ids(t_parent, f_parent, e_parent, v_parent);
722 const Tuple child_tuple =
723 child_mesh.tuple_from_global_ids(t_child, f_child, e_child, v_child);
724
725 assert(parent_mesh.is_valid(parent_tuple));
726 assert(child_mesh.is_valid(child_tuple));
727
729 parent_to_child_accessor,
730 child_to_parent_accessor,
731 parent_tuple,
732 child_tuple);
733 }
734 }
735 }
736}
737
738
739// edge
741 EdgeMesh& parent_mesh,
742 const simplex::Simplex&,
743 const edge_mesh::EdgeOperationData& parent_emoe)
744{
745 return;
746 // if there's a child mesh then lets disallow this
747#if !defined(NDEBUG)
748 if (parent_mesh.get_child_meshes().size() > 0) {
749 throw std::runtime_error("not implemented");
750 }
751#endif
752 logger().error("EdgeMesh update Not implemented!");
753}
754
755// tri
757 TriMesh& parent_mesh,
758 const simplex::Simplex&,
759 const tri_mesh::EdgeOperationData& parent_fmoe)
760{
761 std::vector<std::tuple<int64_t, std::array<int64_t, 2>>> parent_split_cell_maps;
762 const auto& parent_incident_datas = parent_fmoe.incident_face_datas();
763 for (const auto& parent_data : parent_incident_datas) {
764 if (parent_data.split_f[0] == -1) break;
765 parent_split_cell_maps.emplace_back(parent_data.fid, parent_data.split_f);
766 }
767 // TODO: update the ear edges here?
768
769 if (parent_fmoe.is_collapse) {
770 update_ear_replacement(parent_mesh, parent_fmoe);
771 }
773 parent_mesh,
775 parent_split_cell_maps);
776}
777
778// tet
780 TetMesh& parent_mesh,
781 const simplex::Simplex&,
782 const tet_mesh::EdgeOperationData& parent_tmoe)
783{
784 std::vector<std::tuple<int64_t, std::array<int64_t, 2>>> parent_split_cell_maps;
785 const auto& parent_incident_tet_datas = parent_tmoe.incident_tet_datas();
786 for (const auto& parent_data : parent_incident_tet_datas) {
787 if (parent_data.split_t[0] == -1) break; // no split datas, not a split function
788 parent_split_cell_maps.emplace_back(parent_data.tid, parent_data.split_t);
789 }
790
791 if (parent_tmoe.is_collapse) {
792 update_ear_replacement(parent_mesh, parent_tmoe);
793 }
795 parent_mesh,
797 parent_split_cell_maps);
798}
799
802 int64_t parent_gid) const
803{
804 return MultiMeshManager::child_global_cid(parent_to_child, parent_gid);
805}
808 int64_t child_gid) const
809{
810 return MultiMeshManager::parent_global_cid(child_to_parent, child_gid);
811}
812
815 int64_t child_gid) const
816{
817 return MultiMeshManager::parent_local_fid(child_to_parent, child_gid);
818}
819
820
821/*
822template <typename MeshType>
823void UpdateEdgeOperationMultiMeshMapFunctor::update_maps(
824 MeshType& mesh,
825 const simplex::Simplex&,
826 const EdgeOperationData&)
827{
828 // on split:
829 // for each dimension
830 // for each boundary simplex
831 // update boundary facets using availalbe simplices (in split we have 2 choices,
832 // collapse we have to look at opposing ears each simplex that refers to an existing
833 // simplex must be replaced
834 //
835 // on collapse:
836 // for each dimension
837 // for each boundary simplex
838 // if the face used an ear simplex
839 // update boundary facets using availalbe simplices (in split we have 2 choices,
840 // collapse we have to look at opposing ears each simplex that refers to an existing
841 // simplex must be replaced
842 //
843 //
844
845
846 for (size_t j = 0; j < simplices_to_update.size(); ++j) {
847 mesh.m_multi_mesh_manager
848 .update_map_tuple_hashes(m, PTs[j], simplices_to_update[j], split_cell_maps);
849 }
850}
851*/
852
853} // namespace wmtk::operations::utils
Tuple tuple_from_global_ids(int64_t eid, int64_t vid) const
Definition EdgeMesh.cpp:196
bool is_valid(const Tuple &tuple) const final override
check validity of tuple including its hash
Definition EdgeMesh.cpp:214
attribute::Accessor< T, Derived, Dim > create_accessor(const TypedAttributeHandle< T > &handle)
constructs an accessor that is aware of the derived mesh's type
Definition MeshCRTP.hpp:67
static auto & get_index_access(attribute::Accessor< T, MeshType > &attr)
Definition Mesh.hpp:809
multimesh::MultiMeshManager m_multi_mesh_manager
Definition Mesh.hpp:827
decltype(auto) parent_scope(Functor &&f, Args &&... args) const
Evaluate the passed in function inside the parent scope.
Definition Mesh.hpp:941
std::vector< std::shared_ptr< Mesh > > get_child_meshes() const
returns the direct multimesh child meshes for the current mesh
Tuple tuple_from_global_ids(int64_t tid, int64_t fid, int64_t eid, int64_t vid) const
Definition TetMesh.cpp:583
int64_t id_vertex(const Tuple &tuple) const
Definition TetMesh.hpp:68
int64_t id_edge(const Tuple &tuple) const
Definition TetMesh.hpp:69
bool is_valid(const Tuple &tuple) const final override
check validity of tuple including its hash
Definition TetMesh.cpp:320
int64_t id_vertex(const Tuple &tuple) const
Definition TriMesh.hpp:73
bool is_valid(const Tuple &tuple) const final override
check validity of tuple including its hash
Definition TriMesh.cpp:329
Tuple tuple_from_global_ids(int64_t fid, int64_t eid, int64_t vid) const
Definition TriMesh.cpp:245
The Tuple is the basic navigation tool in our mesh data structure.
Definition Tuple.hpp:19
bool is_null() const
Checks if a tuple is "null". This merely implies the global index is -1.
Definition Tuple.hxx:41
A CachingAccessor that uses tuples for accessing attributes instead of indices.
Definition Accessor.hpp:28
int64_t child_id() const
Specifies the child id of this mesh if it a child mesh in a mult-mesh tree.
static int64_t child_global_cid(const wmtk::attribute::Accessor< int64_t > &parent_to_child, int64_t parent_gid)
static int64_t parent_local_fid(const wmtk::attribute::Accessor< int64_t > &child_to_parent, int64_t child_gid)
static int64_t parent_global_cid(const wmtk::attribute::Accessor< int64_t > &child_to_parent, int64_t child_gid)
void update_map_tuple_hashes(Mesh &my_mesh, PrimitiveType primitive_type, const std::vector< std::tuple< int64_t, std::vector< Tuple > > > &simplices_to_update, const std::vector< std::tuple< int64_t, std::array< int64_t, 2 > > > &split_cell_maps={})
TypedAttributeHandle< int64_t > map_to_parent_handle
std::vector< std::vector< std::tuple< int64_t, std::vector< Tuple > > > > global_ids_to_potential_tuples
std::array< int64_t, 2 > new_spine_eids() const
std::vector< IncidentFaceData > incident_face_datas() const
std::vector< IncidentTetData > incident_tet_datas() const
const std::array< int64_t, 2 > & incident_vids() const
const std::array< int64_t, 2 > & incident_vids() const
const std::vector< IncidentFaceData > & incident_face_datas() const
void update_all_hashes(Mesh &m, const std::vector< std::vector< std::tuple< int64_t, std::vector< Tuple > > > > &simplices_to_update, const std::vector< std::tuple< int64_t, std::array< int64_t, 2 > > > &split_cell_maps={}) const
void update_ear_replacement(TriMesh &m, const tri_mesh::EdgeOperationData &fmoe) const
int64_t parent_global_cid(const attribute::Accessor< int64_t, Mesh, Eigen::Dynamic > &parent_to_child, int64_t parent_gid) const
int64_t parent_local_fid(const attribute::Accessor< int64_t, Mesh, Eigen::Dynamic > &parent_to_child, int64_t parent_gid) const
void operator()(EdgeMesh &, const simplex::Simplex &, const edge_mesh::EdgeOperationData &parent_tmoe, EdgeMesh &, const simplex::Simplex &, const edge_mesh::EdgeOperationData &) const
int64_t child_global_cid(const attribute::Accessor< int64_t, Mesh, Eigen::Dynamic > &parent_to_child, int64_t parent_gid) const
constexpr wmtk::PrimitiveType PT
constexpr wmtk::PrimitiveType PF
std::tuple< Tuple, Tuple > vectors_to_tuples(const Eigen::Ref< const TwoTupleVector > &v)
void symmetric_write_tuple_map_attributes(wmtk::attribute::Accessor< int64_t, MeshA > &a_to_b, wmtk::attribute::Accessor< int64_t, MeshB > &b_to_a, const Tuple &a_tuple, const Tuple &b_tuple)
constexpr PrimitiveType PE
spdlog::logger & logger()
Retrieves the current logger.
Definition Logger.cpp:58
constexpr PrimitiveType PV