From d95e9afb9236d7a488ef3fe3a69ec3a7b50fad86 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Tue, 10 Sep 2019 16:18:12 +0200 Subject: [PATCH 1/6] Utility function MeshOptimize3d::BuildEdgeList() --- libsrc/meshing/improve3.cpp | 107 ++++++++++++++++++------------------ libsrc/meshing/improve3.hpp | 3 + 2 files changed, 57 insertions(+), 53 deletions(-) diff --git a/libsrc/meshing/improve3.cpp b/libsrc/meshing/improve3.cpp index c517f228..a4ec7c0c 100644 --- a/libsrc/meshing/improve3.cpp +++ b/libsrc/meshing/improve3.cpp @@ -411,13 +411,64 @@ void MeshOptimize3d :: CombineImproveSequential (Mesh & mesh, multithread.task = savetask; } +void MeshOptimize3d :: BuildEdgeList( const Mesh & mesh, const TABLE & elementsonnode, Array> & edges ) +{ + static Timer tbuild_edges("Build edges"); RegionTimer reg(tbuild_edges); + + static constexpr int tetedges[6][2] = + { { 0, 1 }, { 0, 2 }, { 0, 3 }, + { 1, 2 }, { 1, 3 }, { 2, 3 } }; + + Array>> thread_edges(ngcore::TaskManager::GetMaxThreads()); + + ParallelForRange(mesh.Points().Range(), [&] (auto myrange) + { + ArrayMem, 100> local_edges; + for (auto pi : myrange) + { + local_edges.SetSize(0); + + for(auto ei : elementsonnode[pi]) + { + const Element & elem = mesh[ei]; + if (elem.IsDeleted()) continue; + + for (int j = 0; j < 6; j++) + { + PointIndex pi0 = elem[tetedges[j][0]]; + PointIndex pi1 = elem[tetedges[j][1]]; + if (pi1 < pi0) Swap(pi0, pi1); + if(pi0==pi) + local_edges.Append(std::make_tuple(pi0, pi1)); + } + } + QuickSort(local_edges); + + auto edge_prev = std::make_tuple(-1,-1); + + for(auto edge : local_edges) + if(edge != edge_prev) + { + thread_edges[ngcore::TaskManager::GetThreadId()].Append(edge); + edge_prev = edge; + } + } + }, 4*ngcore::TaskManager::GetNumThreads()); + + int num_edges = 0; + for (auto & edg : thread_edges) + num_edges += edg.Size(); + edges.SetAllocSize(num_edges); + for (auto & edg : thread_edges) + edges.Append(edg); +} + void MeshOptimize3d :: CombineImprove (Mesh & mesh, OPTIMIZEGOAL goal) { static Timer t("MeshOptimize3d::CombineImprove"); RegionTimer reg(t); static Timer topt("Optimize"); static Timer tsearch("Search"); - static Timer tbuild_edges("Build edges"); static Timer tbuild_elements_table("Build elements table"); static Timer tbad("CalcBad"); @@ -474,58 +525,8 @@ void MeshOptimize3d :: CombineImprove (Mesh & mesh, tbuild_elements_table.Stop(); - // Build list of all edges - Array> edges; - Array>> thread_edges(ngcore::TaskManager::GetMaxThreads()); - - static constexpr int tetedges[6][2] = - { { 0, 1 }, { 0, 2 }, { 0, 3 }, - { 1, 2 }, { 1, 3 }, { 2, 3 } }; - - tbuild_edges.Start(); - ParallelForRange(mesh.Points().Range(), [&] (auto myrange) - { - ArrayMem, 100> local_edges; - for (auto pi : myrange) - { - local_edges.SetSize(0); - - for(auto ei : elementsonnode[pi]) - { - Element & elem = mesh[ei]; - if (elem.IsDeleted()) continue; - - for (int j = 0; j < 6; j++) - { - PointIndex pi0 = elem[tetedges[j][0]]; - PointIndex pi1 = elem[tetedges[j][1]]; - if (pi1 < pi0) Swap(pi0, pi1); - if(pi0==pi) - local_edges.Append(std::make_tuple(pi0, pi1)); - } - } - QuickSort(local_edges); - - auto edge_prev = std::make_tuple(-1,-1); - - for(auto edge : local_edges) - if(edge != edge_prev) - { - // TODO: Check for CombineEdge improvement already here and only append edges with improvement - thread_edges[ngcore::TaskManager::GetThreadId()].Append(edge); - edge_prev = edge; - } - } - }, ntasks); - - int num_edges = 0; - for (auto & edg : thread_edges) - num_edges += edg.Size(); - edges.SetAllocSize(num_edges); - for (auto & edg : thread_edges) - edges.Append(edg); - - tbuild_edges.Stop(); + Array> edges; + BuildEdgeList(mesh, elementsonnode, edges); // Find edges with improvement Array> combine_candidate_edges(edges.Size()); diff --git a/libsrc/meshing/improve3.hpp b/libsrc/meshing/improve3.hpp index 1256a08b..9c4934fc 100644 --- a/libsrc/meshing/improve3.hpp +++ b/libsrc/meshing/improve3.hpp @@ -11,6 +11,9 @@ extern double CalcTotalBad (const Mesh::T_POINTS & points, class MeshOptimize3d { const MeshingParameters & mp; + + void BuildEdgeList( const Mesh & mesh, const TABLE & elementsonnode, Array> & edges ); + public: MeshOptimize3d (const MeshingParameters & amp) : mp(amp) { ; } From c22f44617bec695965a024f8e63c76a0b3a87a2d Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Tue, 10 Sep 2019 16:45:48 +0200 Subject: [PATCH 2/6] Separate function SwapImproveEdge(), iterate over list of edges instead of elements and edges per element --- libsrc/meshing/improve3.cpp | 234 +++++++++++++++--------------------- libsrc/meshing/improve3.hpp | 2 + 2 files changed, 101 insertions(+), 135 deletions(-) diff --git a/libsrc/meshing/improve3.cpp b/libsrc/meshing/improve3.cpp index a4ec7c0c..c841081d 100644 --- a/libsrc/meshing/improve3.cpp +++ b/libsrc/meshing/improve3.cpp @@ -891,127 +891,29 @@ void MeshOptimize3d :: SplitImprove (Mesh & mesh, - - -void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal, - const NgBitArray * working_elements) +bool MeshOptimize3d :: SwapImproveEdge (Mesh & mesh, OPTIMIZEGOAL goal, + const NgBitArray * working_elements, + TABLE & elementsonnode, + INDEX_3_HASHTABLE & faces, + PointIndex pi1, PointIndex pi2 + ) { - static Timer t("MeshOptimize3d::SwapImprove"); RegionTimer reg(t); - static Timer tloop("MeshOptimize3d::SwapImprove loop"); - PointIndex pi3(PointIndex::INVALID), pi4(PointIndex::INVALID), pi5(PointIndex::INVALID), pi6(PointIndex::INVALID); - int cnt = 0; + + double bad1, bad2, bad3; Element el21(TET), el22(TET), el31(TET), el32(TET), el33(TET); Element el1(TET), el2(TET), el3(TET), el4(TET); Element el1b(TET), el2b(TET), el3b(TET), el4b(TET); - - double bad1, bad2, bad3; - - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - - // contains at least all elements at node - TABLE elementsonnode(np); - - NgArray hasbothpoints; - - PrintMessage (3, "SwapImprove "); - (*testout) << "\n" << "Start SwapImprove" << endl; - - const char * savetask = multithread.task; - multithread.task = "Swap Improve"; - - // mesh.CalcSurfacesOfNode (); - - INDEX_3_HASHTABLE faces(mesh.GetNOpenElements()/3 + 2); - if (goal == OPT_CONFORM) - { - for (int i = 1; i <= mesh.GetNOpenElements(); i++) - { - const Element2d & hel = mesh.OpenElement(i); - INDEX_3 face(hel[0], hel[1], hel[2]); - face.Sort(); - faces.Set (face, 1); - } - } - - // Calculate total badness - if (goal == OPT_QUALITY) - { - bad1 = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); - (*testout) << "Total badness = " << bad1 << endl; - } - - // find elements on node - for (ElementIndex ei = 0; ei < ne; ei++) - for (PointIndex pi : mesh[ei].PNums()) - elementsonnode.Add (pi, ei); - /* - for (int j = 0; j < mesh[ei].GetNP(); j++) - elementsonnode.Add (mesh[ei][j], ei); - */ - - - // INDEX_2_HASHTABLE edgeused(2 * ne + 5); - INDEX_2_CLOSED_HASHTABLE edgeused(12 * ne + 5); - - tloop.Start(); - for (ElementIndex ei = 0; ei < ne; ei++) - { - if (multithread.terminate) - break; - - if (mp.only3D_domain_nr && mp.only3D_domain_nr != mesh.VolumeElement(ei).GetIndex()) - continue; - - multithread.percent = 100.0 * (ei+1) / ne; - - if ((mesh.ElementType(ei)) == FIXEDELEMENT) - continue; - - if(working_elements && - ei < working_elements->Size() && - !working_elements->Test(ei)) - continue; - - if (mesh[ei].IsDeleted()) - continue; - - if ((goal == OPT_LEGAL) && - mesh.LegalTet (mesh[ei]) && - CalcBad (mesh.Points(), mesh[ei], 0) < 1e3) - continue; - - // int onlybedges = 1; - - for (int j = 0; j < 6; j++) - { - // loop over edges - - const Element & elemi = mesh[ei]; - if (elemi.IsDeleted()) continue; - - int mattyp = elemi.GetIndex(); - - static const int tetedges[6][2] = - { { 0, 1 }, { 0, 2 }, { 0, 3 }, - { 1, 2 }, { 1, 3 }, { 2, 3 } }; - - PointIndex pi1 = elemi[tetedges[j][0]]; - PointIndex pi2 = elemi[tetedges[j][1]]; + ArrayMem hasbothpoints; + bool do_swap = false; if (pi2 < pi1) Swap (pi1, pi2); - if (mesh.BoundaryEdge (pi1, pi2)) continue; + if (mesh.BoundaryEdge (pi1, pi2)) return false; - INDEX_2 i2 (pi1, pi2); - i2.Sort(); - if (edgeused.Used(i2)) continue; - edgeused.Set (i2, 1); - hasbothpoints.SetSize (0); for (int k = 0; k < elementsonnode[pi1].Size(); k++) { @@ -1019,7 +921,7 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal, ElementIndex elnr = elementsonnode[pi1][k]; const Element & elem = mesh[elnr]; - if (elem.IsDeleted()) continue; + if (elem.IsDeleted()) return false; for (int l = 0; l < elem.GetNP(); l++) { @@ -1039,14 +941,34 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal, } } - bool puretet = true; for (ElementIndex ei : hasbothpoints) - if (mesh[ei].GetType () != TET) - puretet = false; - - if (!puretet) continue; + { + if (mesh[ei].GetType () != TET) + return false; + + if (mp.only3D_domain_nr && mp.only3D_domain_nr != mesh.VolumeElement(ei).GetIndex()) + return false; + + + if ((mesh.ElementType(ei)) == FIXEDELEMENT) + return false; + + if(working_elements && + ei < working_elements->Size() && + !working_elements->Test(ei)) + return false; + + if (mesh[ei].IsDeleted()) + return false; + + if ((goal == OPT_LEGAL) && + mesh.LegalTet (mesh[ei]) && + CalcBad (mesh.Points(), mesh[ei], 0) < 1e3) + return false; + } int nsuround = hasbothpoints.Size(); + int mattyp = mesh[hasbothpoints[0]].GetIndex(); if ( nsuround == 3 ) { @@ -1175,7 +1097,7 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal, { // (*mycout) << "3->2 " << flush; // (*testout) << "3->2 conversion" << endl; - cnt++; + do_swap = true; /* @@ -1403,7 +1325,7 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal, if (swap2 || swap3) { // (*mycout) << "4->4 " << flush; - cnt++; + do_swap = true; // (*testout) << "4->4 conversion" << "\n"; /* (*testout) << "bad1 = " << bad1 @@ -1665,7 +1587,7 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal, if (bestl != -1) { // (*mycout) << nsuround << "->" << 2 * (nsuround-2) << " " << flush; - cnt++; + do_swap = true; for (int k = bestl+1; k <= nsuround + bestl - 2; k++) { @@ -1715,28 +1637,70 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal, } } } - } + return do_swap; +} - /* - if (onlybedges) +void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal, + const NgBitArray * working_elements) +{ + static Timer t("MeshOptimize3d::SwapImprove"); RegionTimer reg(t); + static Timer tloop("MeshOptimize3d::SwapImprove loop"); + + int cnt = 0; + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + + // contains at least all elements at node + TABLE elementsonnode(np); + + NgArray hasbothpoints; + + PrintMessage (3, "SwapImprove "); + (*testout) << "\n" << "Start SwapImprove" << endl; + + const char * savetask = multithread.task; + multithread.task = "Swap Improve"; + + // mesh.CalcSurfacesOfNode (); + + INDEX_3_HASHTABLE faces(mesh.GetNOpenElements()/3 + 2); + if (goal == OPT_CONFORM) + { + for (int i = 1; i <= mesh.GetNOpenElements(); i++) { - (*testout) << "bad tet: " - << volelements.Get(i)[0] - << volelements.Get(i)[1] - << volelements.Get(i)[2] - << volelements.Get(i)[3] << "\n"; - - if (!mesh.LegalTet (volelements.Get(i))) - cerr << "Illegal tet" << "\n"; + const Element2d & hel = mesh.OpenElement(i); + INDEX_3 face(hel[0], hel[1], hel[2]); + face.Sort(); + faces.Set (face, 1); } - */ } - // (*mycout) << endl; + + // Calculate total badness + if (goal == OPT_QUALITY) + { + double bad1 = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); + (*testout) << "Total badness = " << bad1 << endl; + } + + // find elements on node + for (ElementIndex ei = 0; ei < ne; ei++) + for (PointIndex pi : mesh[ei].PNums()) + elementsonnode.Add (pi, ei); + + Array> edges; + BuildEdgeList(mesh, elementsonnode, edges); + + tloop.Start(); + + for (auto [pi1, pi2] : edges) + { + if (multithread.terminate) + break; + cnt += SwapImproveEdge (mesh, goal, working_elements, elementsonnode, faces, pi1, pi2); + } tloop.Stop(); - /* - cout << "edgeused: "; - edgeused.PrintMemInfo(cout); - */ + PrintMessage (5, cnt, " swaps performed"); diff --git a/libsrc/meshing/improve3.hpp b/libsrc/meshing/improve3.hpp index 9c4934fc..798db3d8 100644 --- a/libsrc/meshing/improve3.hpp +++ b/libsrc/meshing/improve3.hpp @@ -26,6 +26,8 @@ public: void CombineImproveSequential (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY); void SplitImprove (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY); + + bool SwapImproveEdge (Mesh & mesh, OPTIMIZEGOAL goal, const NgBitArray * working_elements, TABLE & elementsonnode, INDEX_3_HASHTABLE & faces, PointIndex pi1, PointIndex pi2); void SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY, const NgBitArray * working_elements = NULL); void SwapImproveSurface (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY, From a70803eecb9b6f534c6cc74748556328524cd50c Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Tue, 10 Sep 2019 16:59:31 +0200 Subject: [PATCH 3/6] Fix BuildEdgeList() - create sorted list --- libsrc/meshing/improve3.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libsrc/meshing/improve3.cpp b/libsrc/meshing/improve3.cpp index c841081d..0c48b38f 100644 --- a/libsrc/meshing/improve3.cpp +++ b/libsrc/meshing/improve3.cpp @@ -419,10 +419,12 @@ void MeshOptimize3d :: BuildEdgeList( const Mesh & mesh, const TABLE>> thread_edges(ngcore::TaskManager::GetMaxThreads()); + int ntasks = 2*ngcore::TaskManager::GetMaxThreads(); + Array>> task_edges(ntasks); - ParallelForRange(mesh.Points().Range(), [&] (auto myrange) + ParallelFor(IntRange(ntasks), [&] (int ti) { + auto myrange = mesh.Points().Range().Split(ti, ntasks); ArrayMem, 100> local_edges; for (auto pi : myrange) { @@ -449,17 +451,17 @@ void MeshOptimize3d :: BuildEdgeList( const Mesh & mesh, const TABLE Date: Tue, 10 Sep 2019 17:52:24 +0200 Subject: [PATCH 4/6] Parallelize SwapImprove() --- libsrc/meshing/improve3.cpp | 67 ++++++++++++++++++++++--------------- libsrc/meshing/improve3.hpp | 2 +- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/libsrc/meshing/improve3.cpp b/libsrc/meshing/improve3.cpp index 0c48b38f..7fbd04ab 100644 --- a/libsrc/meshing/improve3.cpp +++ b/libsrc/meshing/improve3.cpp @@ -897,7 +897,7 @@ bool MeshOptimize3d :: SwapImproveEdge (Mesh & mesh, OPTIMIZEGOAL goal, const NgBitArray * working_elements, TABLE & elementsonnode, INDEX_3_HASHTABLE & faces, - PointIndex pi1, PointIndex pi2 + PointIndex pi1, PointIndex pi2, bool check_only ) { PointIndex pi3(PointIndex::INVALID), pi4(PointIndex::INVALID), @@ -1100,6 +1100,7 @@ bool MeshOptimize3d :: SwapImproveEdge (Mesh & mesh, OPTIMIZEGOAL goal, // (*mycout) << "3->2 " << flush; // (*testout) << "3->2 conversion" << endl; do_swap = true; + if(check_only) return do_swap; /* @@ -1328,6 +1329,7 @@ bool MeshOptimize3d :: SwapImproveEdge (Mesh & mesh, OPTIMIZEGOAL goal, { // (*mycout) << "4->4 " << flush; do_swap = true; + if(check_only) return do_swap; // (*testout) << "4->4 conversion" << "\n"; /* (*testout) << "bad1 = " << bad1 @@ -1590,6 +1592,7 @@ bool MeshOptimize3d :: SwapImproveEdge (Mesh & mesh, OPTIMIZEGOAL goal, { // (*mycout) << nsuround << "->" << 2 * (nsuround-2) << " " << flush; do_swap = true; + if(check_only) return do_swap; for (int k = bestl+1; k <= nsuround + bestl - 2; k++) { @@ -1653,6 +1656,8 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal, int np = mesh.GetNP(); int ne = mesh.GetNE(); + mesh.BoundaryEdge (1,2); // ensure the boundary-elements table is built + // contains at least all elements at node TABLE elementsonnode(np); @@ -1664,8 +1669,6 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal, const char * savetask = multithread.task; multithread.task = "Swap Improve"; - // mesh.CalcSurfacesOfNode (); - INDEX_3_HASHTABLE faces(mesh.GetNOpenElements()/3 + 2); if (goal == OPT_CONFORM) { @@ -1693,42 +1696,52 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal, Array> edges; BuildEdgeList(mesh, elementsonnode, edges); + Array candidate_edges(edges.Size()); + std::atomic improvement_counter(0); + tloop.Start(); - for (auto [pi1, pi2] : edges) + ParallelForRange(Range(edges), [&] (auto myrange) + { + for(auto i : myrange) + { + if (multithread.terminate) + break; + + auto [pi0, pi1] = edges[i]; + if(SwapImproveEdge (mesh, goal, working_elements, elementsonnode, faces, pi0, pi1, true)) + candidate_edges[improvement_counter++] = i; + } + }); + // Sequential version: + /* + for(auto i : edges.Range()) { if (multithread.terminate) break; - cnt += SwapImproveEdge (mesh, goal, working_elements, elementsonnode, faces, pi1, pi2); + + auto [pi0, pi1] = edges[i]; + if(SwapImproveEdge (mesh, goal, working_elements, elementsonnode, faces, pi0, pi1, true)) + candidate_edges[improvement_counter++] = i; } + */ + + auto edges_with_improvement = candidate_edges.Part(0, improvement_counter.load()); + QuickSort(edges_with_improvement); + + for(auto ei : edges_with_improvement) + { + auto [pi0,pi1] = edges[ei]; + if(SwapImproveEdge (mesh, goal, working_elements, elementsonnode, faces, pi0, pi1, false)) + cnt++; + } + tloop.Stop(); PrintMessage (5, cnt, " swaps performed"); - - - - mesh.Compress (); - /* - if (goal == OPT_QUALITY) - { - bad1 = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); - // (*testout) << "Total badness = " << bad1 << endl; - } - */ - - /* - for (i = 1; i <= GetNE(); i++) - if (volelements.Get(i)[0]) - if (!mesh.LegalTet (volelements.Get(i))) - { - cout << "detected illegal tet, 2" << endl; - (*testout) << "detected illegal tet1: " << i << endl; - } - */ - multithread.task = savetask; } diff --git a/libsrc/meshing/improve3.hpp b/libsrc/meshing/improve3.hpp index 798db3d8..36500d00 100644 --- a/libsrc/meshing/improve3.hpp +++ b/libsrc/meshing/improve3.hpp @@ -27,7 +27,7 @@ public: void SplitImprove (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY); - bool SwapImproveEdge (Mesh & mesh, OPTIMIZEGOAL goal, const NgBitArray * working_elements, TABLE & elementsonnode, INDEX_3_HASHTABLE & faces, PointIndex pi1, PointIndex pi2); + bool SwapImproveEdge (Mesh & mesh, OPTIMIZEGOAL goal, const NgBitArray * working_elements, TABLE & elementsonnode, INDEX_3_HASHTABLE & faces, PointIndex pi1, PointIndex pi2, bool check_only=false); void SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY, const NgBitArray * working_elements = NULL); void SwapImproveSurface (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY, From 1d016f22046aae732da56a4d06fd5d2edef4fe69 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Wed, 11 Sep 2019 13:02:15 +0200 Subject: [PATCH 5/6] Use PointIndex instead of int --- libsrc/meshing/improve3.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/meshing/improve3.cpp b/libsrc/meshing/improve3.cpp index 7fbd04ab..beb3cd5a 100644 --- a/libsrc/meshing/improve3.cpp +++ b/libsrc/meshing/improve3.cpp @@ -425,7 +425,7 @@ void MeshOptimize3d :: BuildEdgeList( const Mesh & mesh, const TABLE, 100> local_edges; + ArrayMem, 100> local_edges; for (auto pi : myrange) { local_edges.SetSize(0); @@ -446,7 +446,7 @@ void MeshOptimize3d :: BuildEdgeList( const Mesh & mesh, const TABLE(-1,-1); for(auto edge : local_edges) if(edge != edge_prev) From 6c0171f2c0067a8785e2df25696208754cc1c20f Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Wed, 11 Sep 2019 13:06:07 +0200 Subject: [PATCH 6/6] Change elementsonnode only when applying optimization --- libsrc/meshing/improve3.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libsrc/meshing/improve3.cpp b/libsrc/meshing/improve3.cpp index beb3cd5a..263bad57 100644 --- a/libsrc/meshing/improve3.cpp +++ b/libsrc/meshing/improve3.cpp @@ -1027,9 +1027,6 @@ bool MeshOptimize3d :: SwapImproveEdge (Mesh & mesh, OPTIMIZEGOAL goal, el33[3] = pi3; el33.SetIndex (mattyp); - elementsonnode.Add (pi4, hasbothpoints[1]); - elementsonnode.Add (pi3, hasbothpoints[2]); - bad1 = CalcBad (mesh.Points(), el31, 0) + CalcBad (mesh.Points(), el32, 0) + CalcBad (mesh.Points(), el33, 0); @@ -1121,6 +1118,9 @@ bool MeshOptimize3d :: SwapImproveEdge (Mesh & mesh, OPTIMIZEGOAL goal, mesh[hasbothpoints[2]][l].Invalidate(); mesh[hasbothpoints[2]].Delete(); + elementsonnode.Add (pi4, hasbothpoints[1]); + elementsonnode.Add (pi3, hasbothpoints[2]); + for (int k = 0; k < 2; k++) for (int l = 0; l < 4; l++) elementsonnode.Add (mesh[hasbothpoints[k]][l], hasbothpoints[k]);