#include #include "debugging.hpp" namespace netgen { unique_ptr GetOpenElements( const Mesh & m, int dom, bool only_quads ) { static Timer t("GetOpenElements"); RegionTimer rt(t); auto mesh = make_unique(); *mesh = m; Array interesting_points(mesh->GetNP()); interesting_points = false; mesh->FindOpenElements(dom); NgArray openelements; openelements = mesh->OpenElements(); for (auto & el : openelements) for (auto i : el.PNums()) interesting_points[i] = true; for (auto & el : mesh->VolumeElements()) { int num_interesting_points = 0; for (auto pi : el.PNums()) if(interesting_points[pi]) num_interesting_points++; if(num_interesting_points==0) el.Delete(); el.SetIndex(num_interesting_points); } mesh->SetMaterial(1, "1_point"); mesh->SetMaterial(2, "2_points"); mesh->SetMaterial(3, "3_points"); mesh->SetMaterial(4, "4_points"); mesh->ClearSurfaceElements(); for (auto & el : openelements) if(!only_quads || el.GetNP() == 4) mesh->AddSurfaceElement( el ); mesh->Compress(); return mesh; } unique_ptr FilterMesh( const Mesh & m, FlatArray points, FlatArray sels, FlatArray els ) { static Timer t("GetOpenElements"); RegionTimer rt(t); auto mesh_ptr = make_unique(); auto & mesh = *mesh_ptr; mesh = m; Array keep_point(mesh.GetNP()); Array keep_sel(mesh.GetNSE()); Array keep_el(mesh.GetNE()); mesh.LineSegments().DeleteAll(); keep_point = false; for(auto pi : points) keep_point[pi] = true; auto set_keep = [&] (auto & input, auto & keep_array, auto & els) { keep_array = false; for(auto ind : input) keep_array[ind] = true; for(auto ind : Range(els)) { bool & keep = keep_array[ind]; if(keep) continue; for(auto pi : mesh[ind].PNums()) keep |= keep_point[pi]; if(!keep) mesh[ind].Delete(); } for(auto i = 0; i> edges; auto elementsonnode = mesh.CreatePoint2ElementTable(); BuildEdgeList(mesh, elementsonnode, edges); mesh.BoundaryEdge(1, 2); // trigger build of boundary edges ArrayMem hasbothpoints; for (auto [pi0, pi1] : edges) { if (mesh.BoundaryEdge(pi0, pi1)) continue; hasbothpoints.SetSize(0); for (ElementIndex ei : elementsonnode[pi0]) if (mesh[ei].PNums().Contains(pi1)) hasbothpoints.Append(ei); bool skip = false; for (ElementIndex ei : hasbothpoints) { if (mesh[ei].GetType() != TET) { skip = true; break; } } if (skip) continue; int nsuround = hasbothpoints.Size(); ArrayMem suroundpts(nsuround + 1); suroundpts = PointIndex::INVALID; ArrayMem tetused(nsuround); tetused = false; tetused[0] = true; auto el = mesh[hasbothpoints[0]]; PointIndex pi2 = PointIndex::INVALID; PointIndex pi3 = PointIndex::INVALID; for (auto pi : el.PNums()) if (pi != pi0 && pi != pi1) { pi3 = pi2; pi2 = pi; } suroundpts[0] = pi2; suroundpts[1] = pi3; for (auto i : Range(2, nsuround + 1)) { PointIndex oldpi = suroundpts[i - 1]; PointIndex newpi = PointIndex::INVALID; for (int k = 0; k < nsuround && !newpi.IsValid(); k++) if (!tetused[k]) { const Element& nel = mesh[hasbothpoints[k]]; for (int k2 = 0; k2 < 4 && !newpi.IsValid(); k2++) if (nel[k2] == oldpi) { newpi = nel[0] - pi0 + nel[1] - pi1 + nel[2] - oldpi + nel[3]; tetused[k] = true; suroundpts[i] = newpi; ArrayMem nelpts{nel[0], nel[1], nel[2], nel[3]}; ArrayMem check_points{pi0, pi1, oldpi, newpi}; QuickSort(check_points); QuickSort(nelpts); if (check_points != nelpts) { cout << __FILE__ << ":" << __LINE__ << "\tFound error" << endl; cout << "i = " << i << endl; cout << "oldpi = " << oldpi << endl; cout << "newpi = " << newpi << endl; cout << "Elements: " << endl; cout << "nel " << nel << endl; for (auto ei : hasbothpoints) cout << mesh[ei] << endl; cout << endl; cout << "check_points: " << check_points << endl; cout << "nelpts: " << nelpts << endl; cout << "hasbothpoints: " << hasbothpoints << endl; cout << "suroundpts: " << suroundpts << endl; throw Exception("Found error"); } } } } if (suroundpts.Last() != suroundpts[0]) { cout << __FILE__ << ":" << __LINE__ << "\tFound error" << endl; cout << "hasbothpoints: " << hasbothpoints << endl; cout << "suroundpts: " << suroundpts << endl; for (auto ei : hasbothpoints) cout << mesh[ei] << endl; throw Exception("Found error"); } } } } // namespace netgen