131 if (!Super::split_edge_after(t))
137 if constexpr (std::is_same_v<WMTKMesh, wmtk::TriMesh>)
138 new_vertex = t.switch_vertex(*
this);
142 std::vector<Tuple> local_mesh_tuples = this->local_mesh_tuples(new_vertex);
145 if (!local_relaxation(local_mesh_tuples, args[
"split"][
"acceptance_tolerance"]))
150 this->extend_local_patch(local_mesh_tuples);
151 for (
Tuple &t : local_mesh_tuples)
153 assert(t.is_valid(*
this));
154 if constexpr (std::is_same_v<wmtk::TriMesh, WMTKMesh>)
155 this->m_tri_connectivity[t.fid(*
this)].hash++;
157 this->m_tet_connectivity[t.tid(*
this)].hash++;
158 assert(!t.is_valid(*
this));
159 t.update_hash(*
this);
160 assert(t.is_valid(*
this));
171 std::vector<Tuple> included_edges;
173 const std::vector<Tuple> edges = WMTKMesh::get_edges();
174 std::copy_if(edges.begin(), edges.end(), std::back_inserter(included_edges), [
this](
const Tuple &e) {
175 return this->edge_attr(e.eid(*this)).energy_rank == Super::EdgeAttributes::EnergyRank::TOP;
179 if (included_edges.empty())
183 splits.reserve(included_edges.size());
184 for (
const Tuple &e : included_edges)
185 splits.emplace_back(
"edge_split", e);
188 return this->edge_elastic_energy(t);
191 executor(*
this, splits);
303 void WildTetRemesher::map_edge_split_boundary_attributes(
const Tuple &new_vertex)
305 const auto &[old_v0_id, old_v0] = op_cache->v0();
306 const auto &[old_v1_id, old_v1] = op_cache->v1();
307 const auto &old_faces = op_cache->faces();
309 const size_t new_vid = new_vertex.vid(*
this);
310 for (
const auto &t : get_one_ring_tets_for_vertex(new_vertex))
312 for (
int i = 0; i < 4; i++)
314 const Tuple f = tuple_from_face(t.tid(*
this), i);
316 std::array<size_t, 3> vids = facet_vids(f);
318 auto new_v_itr = std::find(vids.begin(), vids.end(), new_vid);
320 if (new_v_itr != vids.end())
322 const bool contains_old_v0 = contains(vids, old_v0_id);
323 const bool contains_old_v1 = contains(vids, old_v1_id);
324 assert(!(contains_old_v0 && contains_old_v1));
327 if (!contains_old_v0 && !contains_old_v1)
329 assert(!is_boundary_facet(f));
330 boundary_attrs[facet_id(f)].boundary_id = -1;
334 *new_v_itr = contains_old_v0 ? old_v1_id : old_v0_id;
338 boundary_attrs[
f.fid(*
this)] = old_faces.at(vids);
341 if (is_boundary_facet(f))
342 assert(boundary_attrs[facet_id(f)].boundary_id >= 0);
344 assert(boundary_attrs[facet_id(f)].boundary_id == -1);
353 void WildTriRemesher::map_edge_split_element_attributes(
const Tuple &t)
355 const auto &old_faces = op_cache->faces();
357 Tuple nav = t.switch_vertex(*
this);
358 element_attrs[nav.fid(*
this)] = old_faces[0];
359 nav = nav.switch_edge(*this).switch_face(*this).value();
360 element_attrs[nav.fid(*
this)] = old_faces[0];
361 nav = nav.switch_edge(*
this);
362 if (nav.switch_face(*
this))
364 nav = nav.switch_face(*this).value();
365 element_attrs[nav.fid(*
this)] = old_faces[1];
366 nav = nav.switch_edge(*this).switch_face(*this).value();
367 element_attrs[nav.fid(*
this)] = old_faces[1];
372 void WildTetRemesher::map_edge_split_element_attributes(
const Tuple &new_vertex)
374 const auto &[old_v0_id, old_v0] = op_cache->v0();
375 const auto &[old_v1_id, old_v1] = op_cache->v1();
376 const auto &old_tets = op_cache->tets();
378 const size_t new_vid = new_vertex.vid(*
this);
379 const std::vector<Tuple> new_tets = get_one_ring_tets_for_vertex(new_vertex);
381 for (
const auto &t : new_tets)
383 std::array<size_t, 4> vids = oriented_tet_vids(t);
384 auto new_v_itr = std::find(vids.begin(), vids.end(), new_vid);
385 assert(new_v_itr != vids.end());
387 const bool contains_old_v0 = contains(vids, old_v0_id);
388 assert(contains_old_v0 ^ contains(vids, old_v1_id));
389 *new_v_itr = contains_old_v0 ? old_v1_id : old_v0_id;
391 element_attrs[t.tid(*
this)] = old_tets.at(vids);
398 template class WildRemesher<wmtk::TriMesh>;
399 template class WildRemesher<wmtk::TetMesh>;
400 template class PhysicsRemesher<wmtk::TriMesh>;
401 template class PhysicsRemesher<wmtk::TetMesh>;