From 48198d232d767b6a2f7b5228dae331deb95c0b0c Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Mon, 19 Jul 2021 14:59:12 +0200 Subject: [PATCH] Revert "Revert "Merge branch 'parallel_meshing' into 'master'"" This reverts commit 65c5e2d244d75832e7193ca90643c70bef4788a8. --- libsrc/core/taskmanager.cpp | 15 +- libsrc/meshing/debugging.hpp | 51 ++ libsrc/meshing/delaunay.cpp | 34 +- libsrc/meshing/improve2.hpp | 59 +- libsrc/meshing/improve3.cpp | 46 +- libsrc/meshing/localh.cpp | 44 +- libsrc/meshing/localh.hpp | 2 + libsrc/meshing/meshclass.cpp | 10 + libsrc/meshing/meshclass.hpp | 7 + libsrc/meshing/meshfunc.cpp | 1302 +++++++++++++++++-------------- libsrc/meshing/meshing3.cpp | 135 +++- libsrc/meshing/meshing3.hpp | 2 + libsrc/meshing/meshtype.hpp | 23 +- libsrc/meshing/msghandler.cpp | 3 + tests/pytest/compare_results.py | 2 +- tests/pytest/results.json | 742 +++++++++--------- tests/pytest/test_pickling.py | 28 +- 17 files changed, 1430 insertions(+), 1075 deletions(-) create mode 100644 libsrc/meshing/debugging.hpp diff --git a/libsrc/core/taskmanager.cpp b/libsrc/core/taskmanager.cpp index 9274fb97..60f24761 100644 --- a/libsrc/core/taskmanager.cpp +++ b/libsrc/core/taskmanager.cpp @@ -235,13 +235,14 @@ namespace ngcore const function * func; int mynr; int total; + int producing_thread; atomic * endcnt; TNestedTask () { ; } TNestedTask (const function & _func, int _mynr, int _total, - atomic & _endcnt) - : func(&_func), mynr(_mynr), total(_total), endcnt(&_endcnt) + atomic & _endcnt, int prod_tid) + : func(&_func), mynr(_mynr), total(_total), endcnt(&_endcnt), producing_thread(prod_tid) { ; } @@ -260,12 +261,14 @@ namespace ngcore TPToken ptoken(taskqueue); int num = endcnt; + auto tid = TaskManager::GetThreadId(); for (int i = 0; i < num; i++) - taskqueue.enqueue (ptoken, { afunc, i, num, endcnt }); + taskqueue.enqueue (ptoken, { afunc, i, num, endcnt, tid }); } bool TaskManager :: ProcessTask() { + static Timer t("process task"); TNestedTask task; TCToken ctoken(taskqueue); @@ -282,8 +285,14 @@ namespace ngcore cout << "process nested, nr = " << ti.task_nr << "/" << ti.ntasks << endl; } */ + if(trace && task.producing_thread != ti.thread_nr) + trace->StartTask (ti.thread_nr, t, PajeTrace::Task::ID_TIMER, task.producing_thread); + (*task.func)(ti); --*task.endcnt; + + if(trace && task.producing_thread != ti.thread_nr) + trace->StopTask (ti.thread_nr, t); return true; } return false; diff --git a/libsrc/meshing/debugging.hpp b/libsrc/meshing/debugging.hpp new file mode 100644 index 00000000..941f4beb --- /dev/null +++ b/libsrc/meshing/debugging.hpp @@ -0,0 +1,51 @@ +#include + + +namespace netgen +{ + inline unique_ptr GetOpenElements( const Mesh & m, int dom = 0 ) + { + 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->Compress(); + + mesh->ClearSurfaceElements(); + + for (auto & el : openelements) + mesh->AddSurfaceElement( el ); + + return mesh; + } + + +} diff --git a/libsrc/meshing/delaunay.cpp b/libsrc/meshing/delaunay.cpp index 0bf229f9..b4827847 100644 --- a/libsrc/meshing/delaunay.cpp +++ b/libsrc/meshing/delaunay.cpp @@ -235,9 +235,11 @@ namespace netgen NgArray & freelist, SphereList & list, IndexSet & insphere, IndexSet & closesphere, Array & newels) { - static Timer t("Meshing3::AddDelaunayPoint");// RegionTimer reg(t); - // static Timer tsearch("addpoint, search"); - // static Timer tinsert("addpoint, insert"); + static Timer t("Meshing3::AddDelaunayPoint", NoTracing, NoTiming); RegionTimer reg(t); + static Timer tsearch("addpoint, search", NoTracing, NoTiming); + static Timer tfind("addpoint, find all tets", NoTracing, NoTiming); + static Timer tnewtets("addpoint, build new tets", NoTracing, NoTiming); + static Timer tinsert("addpoint, insert", NoTracing, NoTiming); /* find any sphere, such that newp is contained in @@ -277,7 +279,7 @@ namespace netgen } */ - // tsearch.Start(); + tsearch.Start(); double minquot{1e20}; tettree.GetFirstIntersecting (newp, newp, [&](const auto pi) @@ -300,7 +302,7 @@ namespace netgen } return false; } ); - // tsearch.Stop(); + tsearch.Stop(); if (cfelind == -1) { @@ -308,6 +310,7 @@ namespace netgen return; } + tfind.Start(); /* insphere: point is in sphere -> delete element closesphere: point is close to sphere -> considered for same center @@ -399,6 +402,8 @@ namespace netgen } } // while (changed) + tfind.Stop(); + tnewtets.Start(); newels.SetSize(0); Element2d face(TRIG); @@ -553,10 +558,11 @@ namespace netgen tpmax.SetToMax (*pp[k]); } tpmax = tpmax + 0.01 * (tpmax - tpmin); - // tinsert.Start(); + tinsert.Start(); tettree.Insert (tpmin, tpmax, nelind); - // tinsert.Stop(); + tinsert.Stop(); } + tnewtets.Stop(); } @@ -1627,20 +1633,20 @@ namespace netgen // tempmesh.Save ("tempmesh.vol"); { + MeshOptimize3d meshopt(mp); + tempmesh.Compress(); + tempmesh.FindOpenElements (); RegionTaskManager rtm(mp.parallel_meshing ? mp.nthreads : 0); - for (int i = 1; i <= 4; i++) + for (auto i : Range(10)) { - tempmesh.FindOpenElements (); - PrintMessage (5, "Num open: ", tempmesh.GetNOpenElements()); - tempmesh.CalcSurfacesOfNode (); - tempmesh.FreeOpenElementsEnvironment (1); + if(i%5==0) + tempmesh.FreeOpenElementsEnvironment (1); - MeshOptimize3d meshopt(mp); - // tempmesh.CalcSurfacesOfNode(); meshopt.SwapImprove(tempmesh, OPT_CONFORM); } + tempmesh.Compress(); } MeshQuality3d (tempmesh); diff --git a/libsrc/meshing/improve2.hpp b/libsrc/meshing/improve2.hpp index 23d53bfd..315127c6 100644 --- a/libsrc/meshing/improve2.hpp +++ b/libsrc/meshing/improve2.hpp @@ -1,15 +1,42 @@ #ifndef FILE_IMPROVE2 #define FILE_IMPROVE2 +inline void AppendEdges( const Element2d & elem, PointIndex pi, Array> & edges ) +{ + for (int j = 0; j < 3; j++) + { + PointIndex pi0 = elem[j]; + PointIndex pi1 = elem[(j+1)%3]; + if (pi1 < pi0) Swap(pi0, pi1); + if(pi0==pi) + edges.Append(std::make_tuple(pi0, pi1)); + } +} + +inline void AppendEdges( const Element & elem, PointIndex pi, Array> & edges ) +{ + static constexpr int tetedges[6][2] = + { { 0, 1 }, { 0, 2 }, { 0, 3 }, + { 1, 2 }, { 1, 3 }, { 2, 3 } }; + + if(elem.flags.fixed) + return; + 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) + edges.Append(std::make_tuple(pi0, pi1)); + } +} + template void BuildEdgeList( const Mesh & mesh, const Table & elementsonnode, Array> & edges ) { + static_assert(is_same_v||is_same_v, "Invalid type for TINDEX"); 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 } }; - int ntasks = 4*ngcore::TaskManager::GetMaxThreads(); Array>> task_edges(ntasks); @@ -26,29 +53,7 @@ void BuildEdgeList( const Mesh & mesh, const Table & element const auto & elem = mesh[ei]; if (elem.IsDeleted()) continue; - static_assert(is_same_v||is_same_v, "Invalid type for TINDEX"); - if constexpr(is_same_v) - { - for (int j = 0; j < 3; j++) - { - PointIndex pi0 = elem[j]; - PointIndex pi1 = elem[(j+1)%3]; - if (pi1 < pi0) Swap(pi0, pi1); - if(pi0==pi) - local_edges.Append(std::make_tuple(pi0, pi1)); - } - } - else if constexpr(is_same_v) - { - 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)); - } - } + AppendEdges(elem, pi, local_edges); } QuickSort(local_edges); diff --git a/libsrc/meshing/improve3.cpp b/libsrc/meshing/improve3.cpp index 6c7d7511..80e60545 100644 --- a/libsrc/meshing/improve3.cpp +++ b/libsrc/meshing/improve3.cpp @@ -2717,8 +2717,24 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal, int ne = mesh.GetNE(); mesh.BuildBoundaryEdges(false); + BitArray free_points(mesh.GetNP()+PointIndex::BASE); + free_points.Clear(); - auto elementsonnode = mesh.CreatePoint2ElementTable(); + ParallelForRange(mesh.VolumeElements().Range(), [&] (auto myrange) + { + for (ElementIndex eli : myrange) + { + const auto & el = mesh[eli]; + if(el.flags.fixed) + continue; + + for (auto pi : el.PNums()) + if(!free_points[pi]) + free_points.SetBitAtomic(pi); + } + }); + + auto elementsonnode = mesh.CreatePoint2ElementTable(free_points); NgArray hasbothpoints; @@ -2736,7 +2752,7 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal, const Element2d & hel = mesh.OpenElement(i); INDEX_3 face(hel[0], hel[1], hel[2]); face.Sort(); - faces.Set (face, 1); + faces.Set (face, i); } } @@ -2755,6 +2771,8 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal, tloop.Start(); + auto num_elements_before = mesh.VolumeElements().Range().Next(); + ParallelForRange(Range(edges), [&] (auto myrange) { for(auto i : myrange) @@ -2786,6 +2804,30 @@ void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal, PrintMessage (5, cnt, " swaps performed"); + if(goal == OPT_CONFORM) + { + // Remove open elements that were closed by new tets + auto & open_els = mesh.OpenElements(); + + for (auto & el : mesh.VolumeElements().Range( num_elements_before, mesh.VolumeElements().Range().Next() )) + { + for (auto i : Range(1,5)) + { + Element2d sel; + el.GetFace(i, sel); + INDEX_3 face(sel[0], sel[1], sel[2]); + face.Sort(); + if(faces.Used(face)) + open_els[faces.Get(face)-1].Delete(); + } + } + + for(int i=open_els.Size()-1; i>=0; i--) + if(open_els[i].IsDeleted()) + open_els.Delete(i); + + mesh.DeleteBoundaryEdges(); + } mesh.Compress (); multithread.task = savetask; diff --git a/libsrc/meshing/localh.cpp b/libsrc/meshing/localh.cpp index 27700630..ef1b945b 100644 --- a/libsrc/meshing/localh.cpp +++ b/libsrc/meshing/localh.cpp @@ -91,6 +91,45 @@ namespace netgen delete root; } + unique_ptr LocalH :: Copy () + { + static Timer t("LocalH::Copy"); RegionTimer rt(t); + auto lh = make_unique(boundingbox, grading, dimension); + std::map mapping; + lh->boxes.SetSize(boxes.Size()); + + for(auto i : boxes.Range()) + { + lh->boxes[i] = new GradingBox(); + auto & bnew = *lh->boxes[i]; + auto & b = *boxes[i]; + bnew.xmid[0] = b.xmid[0]; + bnew.xmid[1] = b.xmid[1]; + bnew.xmid[2] = b.xmid[2]; + bnew.h2 = b.h2; + bnew.hopt = b.hopt; + bnew.flags = b.flags; + mapping[&b] = &bnew; + } + + for(auto i : boxes.Range()) + { + auto & bnew = *lh->boxes[i]; + auto & b = *boxes[i]; + for(auto k : Range(8)) + { + if(b.childs[k]) + bnew.childs[k] = mapping[b.childs[k]]; + } + + if(b.father) + bnew.father = mapping[b.father]; + } + + lh->root = mapping[root]; + return lh; + } + void LocalH :: Delete () { root->DeleteChilds(); @@ -405,8 +444,8 @@ namespace netgen void LocalH :: FindInnerBoxes (AdFront3 * adfront, int (*testinner)(const Point3d & p1)) { - static int timer = NgProfiler::CreateTimer ("LocalH::FindInnerBoxes"); - NgProfiler::RegionTimer reg (timer); + static Timer timer("LocalH::FindInnerBoxes"); + RegionTimer reg (timer); int nf = adfront->GetNF(); @@ -812,6 +851,7 @@ namespace netgen void LocalH :: GetOuterPoints (NgArray > & points) { + static Timer t("LocalH::GetOuterPoints"); RegionTimer rt(t); for (int i = 0; i < boxes.Size(); i++) if (!boxes[i]->flags.isinner && !boxes[i]->flags.cutboundary) points.Append ( boxes[i] -> PMid()); diff --git a/libsrc/meshing/localh.hpp b/libsrc/meshing/localh.hpp index 7d2ec433..5edc940d 100644 --- a/libsrc/meshing/localh.hpp +++ b/libsrc/meshing/localh.hpp @@ -98,6 +98,8 @@ namespace netgen ~LocalH(); /// + unique_ptr Copy(); + /// void Delete(); /// void DoArchive(Archive& ar); diff --git a/libsrc/meshing/meshclass.cpp b/libsrc/meshing/meshclass.cpp index ca403d32..6d49d55f 100644 --- a/libsrc/meshing/meshclass.cpp +++ b/libsrc/meshing/meshclass.cpp @@ -384,6 +384,8 @@ namespace netgen volelements.Append (el); } volelements.Last().flags.illegal_valid = 0; + volelements.Last().flags.fixed = 0; + volelements.Last().flags.deleted = 0; // while (volelements.Size() > eltyps.Size()) // eltyps.Append (FREEELEMENT); @@ -405,6 +407,8 @@ namespace netgen volelements[ei] = el; volelements[ei].flags.illegal_valid = 0; + volelements[ei].flags.fixed = 0; + volelements[ei].flags.deleted = 0; } @@ -436,6 +440,7 @@ namespace netgen void Mesh :: Save (ostream & outfile) const { + static Timer timer("Mesh::Save"); RegionTimer rt(timer); int i, j; double scale = 1; // globflags.GetNumFlag ("scale", 1); @@ -2910,6 +2915,7 @@ namespace netgen void Mesh :: FreeOpenElementsEnvironment (int layers) { + static Timer timer("FreeOpenElementsEnvironment"); RegionTimer rt(timer); int i, j, k; PointIndex pi; const int large = 9999; @@ -6570,6 +6576,8 @@ namespace netgen [&](auto & table, ElementIndex ei) { const auto & el = (*this)[ei]; + if(el.IsDeleted()) + return; for (PointIndex pi : el.PNums()) if(free_points[pi]) @@ -6581,6 +6589,8 @@ namespace netgen [&](auto & table, ElementIndex ei) { const auto & el = (*this)[ei]; + if(el.IsDeleted()) + return; for (PointIndex pi : el.PNums()) table.Add (pi, ei); diff --git a/libsrc/meshing/meshclass.hpp b/libsrc/meshing/meshclass.hpp index 83f28c89..b8e282d0 100644 --- a/libsrc/meshing/meshclass.hpp +++ b/libsrc/meshing/meshclass.hpp @@ -486,6 +486,8 @@ namespace netgen { return openelements.Get(i); } auto & OpenElements() const { return openelements; } + + auto & OpenElements() { return openelements; } /// are also quads open elements bool HasOpenQuads () const; @@ -510,6 +512,11 @@ namespace netgen return boundaryedges->Used (i2); } + void DeleteBoundaryEdges () + { + boundaryedges = nullptr; + } + bool IsSegment (PointIndex pi1, PointIndex pi2) const { INDEX_2 i2 (pi1, pi2); diff --git a/libsrc/meshing/meshfunc.cpp b/libsrc/meshing/meshfunc.cpp index f3ebccde..c843babc 100644 --- a/libsrc/meshing/meshfunc.cpp +++ b/libsrc/meshing/meshfunc.cpp @@ -1,5 +1,6 @@ #include #include "meshing.hpp" +#include "debugging.hpp" namespace netgen { @@ -10,310 +11,742 @@ namespace netgen extern const char * pyramidrules2[]; extern const char * hexrules[]; - - // extern double teterrpow; - MESHING3_RESULT MeshVolume (const MeshingParameters & c_mp, Mesh& mesh3d) + struct MeshingData { - static Timer t("MeshVolume"); RegionTimer reg(t); + int domain; - MeshingParameters mp = c_mp; // copy mp to change them here - int oldne; - int meshed; + // mesh for one domain (contains all adjacent surface elments) + unique_ptr mesh; - NgArray connectednodes; + // maps from local (domain) mesh to global mesh + Array pmap; + + Array connected_pairs; + + MeshingParameters mp; + + unique_ptr meshing; + }; + + // extract surface meshes belonging to individual domains + Array DivideMesh(Mesh & mesh, const MeshingParameters & mp) + { + static Timer timer("DivideMesh"); RegionTimer rt(timer); + + Array ret; + auto num_domains = mesh.GetNDomains(); + + ret.SetSize(num_domains); + if(num_domains==1 || mp.only3D_domain_nr) + { + // no need to divide mesh, just fill in meshing data + ret[0].domain = 1; + if(mp.only3D_domain_nr) + ret[0].domain = mp.only3D_domain_nr; + + ret[0].mesh.reset(&mesh); // careful, this unique_ptr must not delete &mesh! (it will be released in MergeMeshes after meshing) + ret[0].mp = mp; + return ret; + } + + Array> ipmap; + ipmap.SetSize(num_domains); + auto dim = mesh.GetDimension(); + auto num_points = mesh.GetNP(); + auto num_facedescriptors = mesh.GetNFD(); + + auto & identifications = mesh.GetIdentifications(); + + for(auto i : Range(ret)) + { + auto & md = ret[i]; + md.domain = i+1; + + md.mp = mp; + md.mp.maxh = min2 (mp.maxh, mesh.MaxHDomain(md.domain)); + + ret[i].mesh = make_unique(); + auto & m = *ret[i].mesh; + + m.SetLocalH(mesh.GetLocalH()); + + ipmap[i].SetSize(num_points); + ipmap[i] = PointIndex::INVALID; + m.SetDimension( mesh.GetDimension() ); + + for(auto i : Range(1, num_facedescriptors+1)) + m.AddFaceDescriptor( mesh.GetFaceDescriptor(i) ); + } + + // mark used points for each domain, add surface elements (with wrong point numbers) to domain mesh + for(const auto & sel : mesh.SurfaceElements()) + { + const auto & fd = mesh.GetFaceDescriptor(sel.GetIndex()); + int dom_in = fd.DomainIn(); + int dom_out = fd.DomainOut(); + + for( auto dom : {dom_in, dom_out} ) + { + if(dom==0) + continue; + + auto & sels = ret[dom-1].mesh->SurfaceElements(); + for(auto pi : sel.PNums()) + ipmap[dom-1][pi] = 1; + sels.Append(sel); + } + } + + // mark locked/fixed points for each domain TODO: domain bounding box to add only relevant points? + for(auto pi : mesh.LockedPoints()) + for(auto i : Range(ret)) + ipmap[i][pi] = 1; + + // add used points to domain mesh, build point mapping + for(auto i : Range(ret)) + { + auto & m = *ret[i].mesh; + auto & pmap = ret[i].pmap; + + for(auto pi : Range(ipmap[i])) + if(ipmap[i][pi]) + { + auto pi_new = m.AddPoint( mesh[pi] ); + ipmap[i][pi] = pi_new; + pmap.Append( pi ); + } + } + + NgArray connectednodes; + for(auto i : Range(ret)) + { + auto & imap = ipmap[i]; + auto & m = *ret[i].mesh; + + for (auto & sel : m.SurfaceElements()) + for(auto & pi : sel.PNums()) + pi = imap[pi]; + + for (int nr = 1; nr <= identifications.GetMaxNr(); nr++) + if (identifications.GetType(nr) != Identifications::PERIODIC) + { + identifications.GetPairs (nr, connectednodes); + for (auto pair : connectednodes) + { + auto pi0 = pair[0]; + auto pi1 = pair[1]; + if(imap[pi0].IsValid() && imap[pi1].IsValid()) + ret[i].connected_pairs.Append({imap[pi0], imap[pi1]}); + } + } + } + return ret; + } + + void CloseOpenQuads( MeshingData & md) + { + auto & mesh = *md.mesh; + auto domain = md.domain; + MeshingParameters & mp = md.mp; + + int oldne; + if (multithread.terminate) + return; + + mesh.CalcSurfacesOfNode(); + mesh.FindOpenElements(domain); + + if (!mesh.GetNOpenElements()) + return; + + for (int qstep = 0; qstep <= 3; qstep++) + { + if (qstep == 0 && !mp.try_hexes) continue; + + if (mesh.HasOpenQuads()) + { + string rulefile = ngdir; + + const char ** rulep = NULL; + switch (qstep) + { + case 0: + rulep = hexrules; + break; + case 1: + rulep = prismrules2; + break; + case 2: // connect pyramid to triangle + rulep = pyramidrules2; + break; + case 3: // connect to vis-a-vis point + rulep = pyramidrules; + break; + } + + Meshing3 meshing(rulep); + + MeshingParameters mpquad = mp; + + mpquad.giveuptol = 15; + mpquad.baseelnp = 4; + mpquad.starshapeclass = 1000; + mpquad.check_impossible = qstep == 1; // for prisms only (air domain in trafo) + + + for (PointIndex pi : mesh.Points().Range()) + meshing.AddPoint (mesh[pi], pi); + + for (auto pair : md.connected_pairs) + meshing.AddConnectedPair (pair); + + for (int i = 1; i <= mesh.GetNOpenElements(); i++) + { + Element2d hel = mesh.OpenElement(i); + meshing.AddBoundaryElement (hel); + } + + oldne = mesh.GetNE(); + + meshing.GenerateMesh (mesh, mpquad); + + for (int i = oldne + 1; i <= mesh.GetNE(); i++) + mesh.VolumeElement(i).SetIndex (domain); + + (*testout) + << "mesh has " << mesh.GetNE() << " prism/pyramid elements" << endl; + + mesh.FindOpenElements(domain); + } + } + + + if (mesh.HasOpenQuads()) + { + PrintSysError ("mesh has still open quads"); + throw NgException ("Stop meshing since too many attempts"); + // return MESHING3_GIVEUP; + } + } + + void PrepareForBlockFillLocalH(MeshingData & md) + { + static Timer t("PrepareForBlockFillLocalH"); RegionTimer rt(t); + md.meshing = make_unique(nullptr); + + auto & mesh = *md.mesh; + + mesh.CalcSurfacesOfNode(); + mesh.FindOpenElements(md.domain); + + for (PointIndex pi : mesh.Points().Range()) + md.meshing->AddPoint (mesh[pi], pi); + + for (int i = 1; i <= mesh.GetNOpenElements(); i++) + md.meshing->AddBoundaryElement (mesh.OpenElement(i)); + + if (mesh.HasLocalHFunction()) + md.meshing->PrepareBlockFillLocalH(mesh, md.mp); + } + + + void MeshDomain( MeshingData & md) + { + auto & mesh = *md.mesh; + auto domain = md.domain; + MeshingParameters & mp = md.mp; + + if (mp.delaunay && mesh.GetNOpenElements()) + { + int oldne = mesh.GetNE(); + + md.meshing->Delaunay (mesh, domain, mp); + + for (int i = oldne + 1; i <= mesh.GetNE(); i++) + mesh.VolumeElement(i).SetIndex (domain); + + PrintMessage (3, mesh.GetNP(), " points, ", + mesh.GetNE(), " elements"); + } + + Box<3> domain_bbox( Box<3>::EMPTY_BOX ); + + for (auto & sel : mesh.SurfaceElements()) + { + if (sel.IsDeleted() ) continue; + + for (auto pi : sel.PNums()) + domain_bbox.Add (mesh[pi]); + } + domain_bbox.Increase (0.01 * domain_bbox.Diam()); + + mesh.FindOpenElements(domain); + + int cntsteps = 0; + int meshed; + if (mesh.GetNOpenElements()) + do + { + if (multithread.terminate) + break; + + mesh.FindOpenElements(domain); + PrintMessage (5, mesh.GetNOpenElements(), " open faces"); + GetOpenElements( mesh, domain )->Save("open_"+ToString(cntsteps)+".vol"); + cntsteps++; + + + if (cntsteps > mp.maxoutersteps) + throw NgException ("Stop meshing since too many attempts"); + + PrintMessage (1, "start tetmeshing"); + + Meshing3 meshing(tetrules); + + Array glob2loc(mesh.GetNP()); + glob2loc = PointIndex::INVALID; + + for (PointIndex pi : mesh.Points().Range()) + if (domain_bbox.IsIn (mesh[pi])) + glob2loc[pi] = meshing.AddPoint (mesh[pi], pi); + + for (auto sel : mesh.OpenElements() ) + { + for(auto & pi : sel.PNums()) + pi = glob2loc[pi]; + meshing.AddBoundaryElement (sel); + } + + int oldne = mesh.GetNE(); + + mp.giveuptol = 15 + 10 * cntsteps; + mp.sloppy = 5; + meshing.GenerateMesh (mesh, mp); + + for (ElementIndex ei = oldne; ei < mesh.GetNE(); ei++) + mesh[ei].SetIndex (domain); + + + mesh.CalcSurfacesOfNode(); + mesh.FindOpenElements(domain); + + // teterrpow = 2; + if (mesh.GetNOpenElements() != 0) + { + meshed = 0; + PrintMessage (5, mesh.GetNOpenElements(), " open faces found"); + + MeshOptimize3d optmesh(mp); + + const char * optstr = "mcmstmcmstmcmstmcm"; + for (size_t j = 1; j <= strlen(optstr); j++) + { + mesh.CalcSurfacesOfNode(); + mesh.FreeOpenElementsEnvironment(2); + mesh.CalcSurfacesOfNode(); + + switch (optstr[j-1]) + { + case 'c': optmesh.CombineImprove(mesh, OPT_REST); break; + case 'd': optmesh.SplitImprove(mesh, OPT_REST); break; + case 's': optmesh.SwapImprove(mesh, OPT_REST); break; + case 't': optmesh.SwapImprove2(mesh, OPT_REST); break; + case 'm': mesh.ImproveMesh(mp, OPT_REST); break; + } + + } + + mesh.FindOpenElements(); + PrintMessage (3, "Call remove problem"); + // mesh.Save("before_remove.vol"); + RemoveProblem (mesh, domain); + // mesh.Save("after_remove.vol"); + mesh.FindOpenElements(); + } + else + { + meshed = 1; + PrintMessage (1, "Success !"); + } + } + while (!meshed); + + { + PrintMessage (3, "Check subdomain ", domain, " / ", mesh.GetNDomains()); + + mesh.FindOpenElements(domain); + + bool res = (mesh.CheckConsistentBoundary() != 0); + if (res) + { + // mesh.Save("output.vol"); + PrintError ("Surface mesh not consistent"); + throw NgException ("Stop meshing since surface mesh not consistent"); + } + } + // OptimizeVolume( md.mp, mesh ); + } + + void MeshDomain(Mesh & mesh3d, const MeshingParameters & c_mp, int k, const Identifications & identifications) + { + MeshingParameters mp = c_mp; // copy mp to change them here + NgArray connectednodes; - if (!mesh3d.HasLocalHFunction()) mesh3d.CalcLocalH(mp.grading); + int oldne; + int meshed; + if(mp.only3D_domain_nr && mp.only3D_domain_nr !=k) + return; + if (multithread.terminate) + return; + + PrintMessage (2, ""); + PrintMessage (1, "Meshing subdomain ", k, " of ", mesh3d.GetNDomains()); + (*testout) << "Meshing subdomain " << k << endl; + + mp.maxh = min2 (mp.maxh, mesh3d.MaxHDomain(k)); - mesh3d.Compress(); + mesh3d.CalcSurfacesOfNode(); + mesh3d.FindOpenElements(k); + + if (!mesh3d.GetNOpenElements()) + return; + + - // mesh3d.PrintMemInfo (cout); + Box<3> domain_bbox( Box<3>::EMPTY_BOX ); + + for (SurfaceElementIndex sei = 0; sei < mesh3d.GetNSE(); sei++) + { + const Element2d & el = mesh3d[sei]; + if (el.IsDeleted() ) continue; - if (mp.checkoverlappingboundary) - if (mesh3d.CheckOverlappingBoundary()) - throw NgException ("Stop meshing since boundary mesh is overlapping"); + if (mesh3d.GetFaceDescriptor(el.GetIndex()).DomainIn() == k || + mesh3d.GetFaceDescriptor(el.GetIndex()).DomainOut() == k) + + for (int j = 0; j < el.GetNP(); j++) + domain_bbox.Add (mesh3d[el[j]]); + } + domain_bbox.Increase (0.01 * domain_bbox.Diam()); + - int nonconsist = 0; - for (int k = 1; k <= mesh3d.GetNDomains(); k++) + for (int qstep = 0; qstep <= 3; qstep++) + // for (int qstep = 0; qstep <= 0; qstep++) // for hex-filling + { + if (qstep == 0 && !mp.try_hexes) continue; + + // cout << "openquads = " << mesh3d.HasOpenQuads() << endl; + if (mesh3d.HasOpenQuads()) + { + string rulefile = ngdir; + + const char ** rulep = NULL; + switch (qstep) + { + case 0: + rulefile = "/Users/joachim/gitlab/netgen/rules/hexa.rls"; + rulep = hexrules; + break; + case 1: + rulefile += "/rules/prisms2.rls"; + rulep = prismrules2; + break; + case 2: // connect pyramid to triangle + rulefile += "/rules/pyramids2.rls"; + rulep = pyramidrules2; + break; + case 3: // connect to vis-a-vis point + rulefile += "/rules/pyramids.rls"; + rulep = pyramidrules; + break; + } + + // Meshing3 meshing(rulefile); + Meshing3 meshing(rulep); + + MeshingParameters mpquad = mp; + + mpquad.giveuptol = 15; + mpquad.baseelnp = 4; + mpquad.starshapeclass = 1000; + mpquad.check_impossible = qstep == 1; // for prisms only (air domain in trafo) + + + // for (PointIndex pi = mesh3d.Points().Begin(); pi < mesh3d.Points().End(); pi++) + for (PointIndex pi : mesh3d.Points().Range()) + meshing.AddPoint (mesh3d[pi], pi); + + /* + mesh3d.GetIdentifications().GetPairs (0, connectednodes); + for (int i = 1; i <= connectednodes.Size(); i++) + meshing.AddConnectedPair (connectednodes.Get(i)); + */ + // for (int nr = 1; nr <= identifications.GetMaxNr(); nr++) + // if (identifications.GetType(nr) != Identifications::PERIODIC) + // { + // identifications.GetPairs (nr, connectednodes); + // for (auto pair : connectednodes) + // meshing.AddConnectedPair (pair); + // } + + for (int i = 1; i <= mesh3d.GetNOpenElements(); i++) + { + Element2d hel = mesh3d.OpenElement(i); + meshing.AddBoundaryElement (hel); + } + + oldne = mesh3d.GetNE(); + + meshing.GenerateMesh (mesh3d, mpquad); + + for (int i = oldne + 1; i <= mesh3d.GetNE(); i++) + mesh3d.VolumeElement(i).SetIndex (k); + + (*testout) + << "mesh has " << mesh3d.GetNE() << " prism/pyramid elements" << endl; + + mesh3d.FindOpenElements(k); + } + } + + + if (mesh3d.HasOpenQuads()) + { + PrintSysError ("mesh has still open quads"); + throw NgException ("Stop meshing since too many attempts"); + // return MESHING3_GIVEUP; + } + + + if (mp.delaunay && mesh3d.GetNOpenElements()) + { + Meshing3 meshing((const char**)NULL); + + mesh3d.FindOpenElements(k); + + /* + for (PointIndex pi = mesh3d.Points().Begin(); pi < mesh3d.Points().End(); pi++) + meshing.AddPoint (mesh3d[pi], pi); + */ + for (PointIndex pi : mesh3d.Points().Range()) + meshing.AddPoint (mesh3d[pi], pi); + + for (int i = 1; i <= mesh3d.GetNOpenElements(); i++) + meshing.AddBoundaryElement (mesh3d.OpenElement(i)); + + oldne = mesh3d.GetNE(); + + meshing.Delaunay (mesh3d, k, mp); + + for (int i = oldne + 1; i <= mesh3d.GetNE(); i++) + mesh3d.VolumeElement(i).SetIndex (k); + + PrintMessage (3, mesh3d.GetNP(), " points, ", + mesh3d.GetNE(), " elements"); + } + + + int cntsteps = 0; + if (mesh3d.GetNOpenElements()) + do + { + if (multithread.terminate) + break; + + mesh3d.FindOpenElements(k); + PrintMessage (5, mesh3d.GetNOpenElements(), " open faces"); + cntsteps++; + + if (cntsteps > mp.maxoutersteps) + throw NgException ("Stop meshing since too many attempts"); + + string rulefile = ngdir + "/tetra.rls"; + PrintMessage (1, "start tetmeshing"); + + // Meshing3 meshing(rulefile); + Meshing3 meshing(tetrules); + + NgArray glob2loc(mesh3d.GetNP()); + glob2loc = -1; + + // for (PointIndex pi = mesh3d.Points().Begin(); pi < mesh3d.Points().End(); pi++) + for (PointIndex pi : mesh3d.Points().Range()) + if (domain_bbox.IsIn (mesh3d[pi])) + glob2loc[pi] = + meshing.AddPoint (mesh3d[pi], pi); + + for (int i = 1; i <= mesh3d.GetNOpenElements(); i++) + { + Element2d hel = mesh3d.OpenElement(i); + for (int j = 0; j < hel.GetNP(); j++) + hel[j] = glob2loc[hel[j]]; + meshing.AddBoundaryElement (hel); + // meshing.AddBoundaryElement (mesh3d.OpenElement(i)); + } + + oldne = mesh3d.GetNE(); + + mp.giveuptol = 15 + 10 * cntsteps; + mp.sloppy = 5; + meshing.GenerateMesh (mesh3d, mp); + + for (ElementIndex ei = oldne; ei < mesh3d.GetNE(); ei++) + mesh3d[ei].SetIndex (k); + + + mesh3d.CalcSurfacesOfNode(); + mesh3d.FindOpenElements(k); + + // teterrpow = 2; + if (mesh3d.GetNOpenElements() != 0) + { + meshed = 0; + PrintMessage (5, mesh3d.GetNOpenElements(), " open faces found"); + + MeshOptimize3d optmesh(mp); + + const char * optstr = "mcmstmcmstmcmstmcm"; + for (size_t j = 1; j <= strlen(optstr); j++) + { + mesh3d.CalcSurfacesOfNode(); + mesh3d.FreeOpenElementsEnvironment(2); + mesh3d.CalcSurfacesOfNode(); + + switch (optstr[j-1]) + { + case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break; + case 'd': optmesh.SplitImprove(mesh3d, OPT_REST); break; + case 's': optmesh.SwapImprove(mesh3d, OPT_REST); break; + case 't': optmesh.SwapImprove2(mesh3d, OPT_REST); break; + case 'm': mesh3d.ImproveMesh(mp, OPT_REST); break; + } + + } + + mesh3d.FindOpenElements(k); + PrintMessage (3, "Call remove problem"); + RemoveProblem (mesh3d, k); + mesh3d.FindOpenElements(k); + } + else + { + meshed = 1; + PrintMessage (1, "Success !"); + } + } + while (!meshed); + + PrintMessage (1, mesh3d.GetNP(), " points, ", + mesh3d.GetNE(), " elements"); { if(mp.only3D_domain_nr && mp.only3D_domain_nr !=k) - continue; + return; PrintMessage (3, "Check subdomain ", k, " / ", mesh3d.GetNDomains()); mesh3d.FindOpenElements(k); - /* - bool res = mesh3d.CheckOverlappingBoundary(); - if (res) - { - PrintError ("Surface is overlapping !!"); - nonconsist = 1; - } - */ - bool res = (mesh3d.CheckConsistentBoundary() != 0); if (res) { PrintError ("Surface mesh not consistent"); - nonconsist = 1; + throw NgException ("Stop meshing since surface mesh not consistent"); } } + } - if (nonconsist) + void MergeMeshes( Mesh & mesh, Array & md ) + { + // todo: optimize: count elements, alloc all memory, copy vol elements in parallel + static Timer t("MergeMeshes"); RegionTimer rt(t); + if(md.Size()==1) { - PrintError ("Stop meshing since surface mesh not consistent"); - throw NgException ("Stop meshing since surface mesh not consistent"); + // assume that mesh was never divided, no need to do anything + if(&mesh != md[0].mesh.get()) + throw Exception("Illegal Mesh pointer in MeshingData"); + + md[0].mesh.release(); + return; } - double globmaxh = mp.maxh; + for(auto & m_ : md) + { + auto first_new_pi = m_.pmap.Range().Next(); + auto & m = *m_.mesh; + Array pmap(m.Points().Size()); + for(auto pi : Range(PointIndex(PointIndex::BASE), first_new_pi)) + pmap[pi] = m_.pmap[pi]; - for (int k = 1; k <= mesh3d.GetNDomains(); k++) + for (auto pi : Range(first_new_pi, m.Points().Range().Next())) + pmap[pi] = mesh.AddPoint(m[pi]); + + + for ( auto el : m.VolumeElements() ) + { + for (auto i : Range(el.GetNP())) + el[i] = pmap[el[i]]; + el.SetIndex(m_.domain); + mesh.AddVolumeElement(el); + } + } + } + + void MergeMeshes( Mesh & mesh, FlatArray meshes, PointIndex first_new_pi ) + { + // todo: optimize: count elements, alloc all memory, copy vol elements in parallel + static Timer t("MergeMeshes"); RegionTimer rt(t); + for(auto & m : meshes) + { + Array pmap(m.Points().Size()); + for(auto pi : Range(PointIndex(PointIndex::BASE), first_new_pi)) + pmap[pi] = pi; + + for (auto pi : Range(first_new_pi, m.Points().Range().Next())) + pmap[pi] = mesh.AddPoint(m[pi]); + + + for ( auto el : m.VolumeElements() ) + { + for (auto i : Range(el.GetNP())) + el[i] = pmap[el[i]]; + mesh.AddVolumeElement(el); + } + } + } + + // extern double teterrpow; + MESHING3_RESULT MeshVolume (const MeshingParameters & mp, Mesh& mesh3d) + { + static Timer t("MeshVolume"); RegionTimer reg(t); + + mesh3d.Compress(); + + if (mp.checkoverlappingboundary) + if (mesh3d.CheckOverlappingBoundary()) + throw NgException ("Stop meshing since boundary mesh is overlapping"); + + + if(mesh3d.GetNDomains()==0) + return MESHING3_OK; + + // localh function is built for each domain separately in blockfill ( more efficient ) + if (!mesh3d.HasLocalHFunction() && !mp.blockfill) + mesh3d.CalcLocalH(mp.grading); + + auto md = DivideMesh(mesh3d, mp); + + ParallelFor( md.Range(), [&](int i) { - if(mp.only3D_domain_nr && mp.only3D_domain_nr !=k) - continue; - if (multithread.terminate) - break; - - PrintMessage (2, ""); - PrintMessage (1, "Meshing subdomain ", k, " of ", mesh3d.GetNDomains()); - (*testout) << "Meshing subdomain " << k << endl; - - mp.maxh = min2 (globmaxh, mesh3d.MaxHDomain(k)); + CloseOpenQuads( md[i] ); + }); - mesh3d.CalcSurfacesOfNode(); - mesh3d.FindOpenElements(k); - - if (!mesh3d.GetNOpenElements()) - continue; - - + for(auto & md_ : md) + PrepareForBlockFillLocalH(md_); - Box<3> domain_bbox( Box<3>::EMPTY_BOX ); - - for (SurfaceElementIndex sei = 0; sei < mesh3d.GetNSE(); sei++) - { - const Element2d & el = mesh3d[sei]; - if (el.IsDeleted() ) continue; + ParallelFor( md.Range(), [&](int i) + { + MeshDomain(md[i]); + }); - if (mesh3d.GetFaceDescriptor(el.GetIndex()).DomainIn() == k || - mesh3d.GetFaceDescriptor(el.GetIndex()).DomainOut() == k) - - for (int j = 0; j < el.GetNP(); j++) - domain_bbox.Add (mesh3d[el[j]]); - } - domain_bbox.Increase (0.01 * domain_bbox.Diam()); - - - for (int qstep = 0; qstep <= 3; qstep++) - // for (int qstep = 0; qstep <= 0; qstep++) // for hex-filling - { - if (qstep == 0 && !mp.try_hexes) continue; - - // cout << "openquads = " << mesh3d.HasOpenQuads() << endl; - if (mesh3d.HasOpenQuads()) - { - string rulefile = ngdir; - - const char ** rulep = NULL; - switch (qstep) - { - case 0: - rulefile = "/Users/joachim/gitlab/netgen/rules/hexa.rls"; - rulep = hexrules; - break; - case 1: - rulefile += "/rules/prisms2.rls"; - rulep = prismrules2; - break; - case 2: // connect pyramid to triangle - rulefile += "/rules/pyramids2.rls"; - rulep = pyramidrules2; - break; - case 3: // connect to vis-a-vis point - rulefile += "/rules/pyramids.rls"; - rulep = pyramidrules; - break; - } - - // Meshing3 meshing(rulefile); - Meshing3 meshing(rulep); - - MeshingParameters mpquad = mp; - - mpquad.giveuptol = 15; - mpquad.baseelnp = 4; - mpquad.starshapeclass = 1000; - mpquad.check_impossible = qstep == 1; // for prisms only (air domain in trafo) - - - // for (PointIndex pi = mesh3d.Points().Begin(); pi < mesh3d.Points().End(); pi++) - for (PointIndex pi : mesh3d.Points().Range()) - meshing.AddPoint (mesh3d[pi], pi); - - /* - mesh3d.GetIdentifications().GetPairs (0, connectednodes); - for (int i = 1; i <= connectednodes.Size(); i++) - meshing.AddConnectedPair (connectednodes.Get(i)); - */ - for (int nr = 1; nr <= mesh3d.GetIdentifications().GetMaxNr(); nr++) - if (mesh3d.GetIdentifications().GetType(nr) != Identifications::PERIODIC) - { - mesh3d.GetIdentifications().GetPairs (nr, connectednodes); - for (auto pair : connectednodes) - meshing.AddConnectedPair (pair); - } - - for (int i = 1; i <= mesh3d.GetNOpenElements(); i++) - { - Element2d hel = mesh3d.OpenElement(i); - meshing.AddBoundaryElement (hel); - } - - oldne = mesh3d.GetNE(); - - meshing.GenerateMesh (mesh3d, mpquad); - - for (int i = oldne + 1; i <= mesh3d.GetNE(); i++) - mesh3d.VolumeElement(i).SetIndex (k); - - (*testout) - << "mesh has " << mesh3d.GetNE() << " prism/pyramid elements" << endl; - - mesh3d.FindOpenElements(k); - } - } - - - if (mesh3d.HasOpenQuads()) - { - PrintSysError ("mesh has still open quads"); - throw NgException ("Stop meshing since too many attempts"); - // return MESHING3_GIVEUP; - } - - - if (mp.delaunay && mesh3d.GetNOpenElements()) - { - Meshing3 meshing((const char**)NULL); - - mesh3d.FindOpenElements(k); - - /* - for (PointIndex pi = mesh3d.Points().Begin(); pi < mesh3d.Points().End(); pi++) - meshing.AddPoint (mesh3d[pi], pi); - */ - for (PointIndex pi : mesh3d.Points().Range()) - meshing.AddPoint (mesh3d[pi], pi); - - for (int i = 1; i <= mesh3d.GetNOpenElements(); i++) - meshing.AddBoundaryElement (mesh3d.OpenElement(i)); - - oldne = mesh3d.GetNE(); - - meshing.Delaunay (mesh3d, k, mp); - - for (int i = oldne + 1; i <= mesh3d.GetNE(); i++) - mesh3d.VolumeElement(i).SetIndex (k); - - PrintMessage (3, mesh3d.GetNP(), " points, ", - mesh3d.GetNE(), " elements"); - } - - - int cntsteps = 0; - if (mesh3d.GetNOpenElements()) - do - { - if (multithread.terminate) - break; - - mesh3d.FindOpenElements(k); - PrintMessage (5, mesh3d.GetNOpenElements(), " open faces"); - cntsteps++; - - if (cntsteps > mp.maxoutersteps) - throw NgException ("Stop meshing since too many attempts"); - - string rulefile = ngdir + "/tetra.rls"; - PrintMessage (1, "start tetmeshing"); - - // Meshing3 meshing(rulefile); - Meshing3 meshing(tetrules); - - NgArray glob2loc(mesh3d.GetNP()); - glob2loc = -1; - - // for (PointIndex pi = mesh3d.Points().Begin(); pi < mesh3d.Points().End(); pi++) - for (PointIndex pi : mesh3d.Points().Range()) - if (domain_bbox.IsIn (mesh3d[pi])) - glob2loc[pi] = - meshing.AddPoint (mesh3d[pi], pi); - - for (int i = 1; i <= mesh3d.GetNOpenElements(); i++) - { - Element2d hel = mesh3d.OpenElement(i); - for (int j = 0; j < hel.GetNP(); j++) - hel[j] = glob2loc[hel[j]]; - meshing.AddBoundaryElement (hel); - // meshing.AddBoundaryElement (mesh3d.OpenElement(i)); - } - - oldne = mesh3d.GetNE(); - - mp.giveuptol = 15 + 10 * cntsteps; - mp.sloppy = 5; - meshing.GenerateMesh (mesh3d, mp); - - for (ElementIndex ei = oldne; ei < mesh3d.GetNE(); ei++) - mesh3d[ei].SetIndex (k); - - - mesh3d.CalcSurfacesOfNode(); - mesh3d.FindOpenElements(k); - - // teterrpow = 2; - if (mesh3d.GetNOpenElements() != 0) - { - meshed = 0; - PrintMessage (5, mesh3d.GetNOpenElements(), " open faces found"); - - MeshOptimize3d optmesh(mp); - - const char * optstr = "mcmstmcmstmcmstmcm"; - for (size_t j = 1; j <= strlen(optstr); j++) - { - mesh3d.CalcSurfacesOfNode(); - mesh3d.FreeOpenElementsEnvironment(2); - mesh3d.CalcSurfacesOfNode(); - - switch (optstr[j-1]) - { - case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break; - case 'd': optmesh.SplitImprove(mesh3d, OPT_REST); break; - case 's': optmesh.SwapImprove(mesh3d, OPT_REST); break; - case 't': optmesh.SwapImprove2(mesh3d, OPT_REST); break; - case 'm': mesh3d.ImproveMesh(mp, OPT_REST); break; - } - - } - - mesh3d.FindOpenElements(k); - PrintMessage (3, "Call remove problem"); - RemoveProblem (mesh3d, k); - mesh3d.FindOpenElements(k); - } - else - { - meshed = 1; - PrintMessage (1, "Success !"); - } - } - while (!meshed); - - PrintMessage (1, mesh3d.GetNP(), " points, ", - mesh3d.GetNE(), " elements"); - } - - mp.maxh = globmaxh; + MergeMeshes(mesh3d, md); MeshQuality3d (mesh3d); @@ -321,325 +754,6 @@ namespace netgen } - - - /* - - - MESHING3_RESULT MeshVolumeOld (MeshingParameters & mp, Mesh& mesh3d) - { - int i, k, oldne; - - - int meshed; - int cntsteps; - - - PlotStatistics3d * pstat; - if (globflags.GetNumFlag("silentflag", 1) <= 2) - pstat = new XPlotStatistics3d; - else - pstat = new TerminalPlotStatistics3d; - - cntsteps = 0; - do - { - cntsteps++; - if (cntsteps > mp.maxoutersteps) - { - return MESHING3_OUTERSTEPSEXCEEDED; - } - - - int noldp = mesh3d.GetNP(); - - - if ( (cntsteps == 1) && globflags.GetDefineFlag ("delaunay")) - { - cntsteps ++; - - mesh3d.CalcSurfacesOfNode(); - - - for (k = 1; k <= mesh3d.GetNDomains(); k++) - { - Meshing3 meshing(NULL, pstat); - - mesh3d.FindOpenElements(k); - - for (i = 1; i <= noldp; i++) - meshing.AddPoint (mesh3d.Point(i), i); - - for (i = 1; i <= mesh3d.GetNOpenElements(); i++) - { - if (mesh3d.OpenElement(i).GetIndex() == k) - meshing.AddBoundaryElement (mesh3d.OpenElement(i)); - } - - oldne = mesh3d.GetNE(); - if (globflags.GetDefineFlag ("blockfill")) - { - if (!globflags.GetDefineFlag ("localh")) - meshing.BlockFill - (mesh3d, mp.h * globflags.GetNumFlag ("relblockfillh", 1)); - else - meshing.BlockFillLocalH (mesh3d); - } - - MeshingParameters mpd; - meshing.Delaunay (mesh3d, mpd); - - for (i = oldne + 1; i <= mesh3d.GetNE(); i++) - mesh3d.VolumeElement(i).SetIndex (k); - } - } - - noldp = mesh3d.GetNP(); - - mesh3d.CalcSurfacesOfNode(); - mesh3d.FindOpenElements(); - for (k = 1; k <= mesh3d.GetNDomains(); k++) - { - Meshing3 meshing(globflags.GetStringFlag ("rules3d", NULL), pstat); - - Point3d pmin, pmax; - mesh3d.GetBox (pmin, pmax, k); - - rot.SetCenter (Center (pmin, pmax)); - - for (i = 1; i <= noldp; i++) - meshing.AddPoint (mesh3d.Point(i), i); - - for (i = 1; i <= mesh3d.GetNOpenElements(); i++) - { - if (mesh3d.OpenElement(i).GetIndex() == k) - meshing.AddBoundaryElement (mesh3d.OpenElement(i)); - } - - oldne = mesh3d.GetNE(); - - - if ( (cntsteps == 1) && globflags.GetDefineFlag ("blockfill")) - { - if (!globflags.GetDefineFlag ("localh")) - { - meshing.BlockFill - (mesh3d, - mp.h * globflags.GetNumFlag ("relblockfillh", 1)); - } - else - { - meshing.BlockFillLocalH (mesh3d); - } - } - - - mp.giveuptol = int(globflags.GetNumFlag ("giveuptol", 15)); - - meshing.GenerateMesh (mesh3d, mp); - - for (i = oldne + 1; i <= mesh3d.GetNE(); i++) - mesh3d.VolumeElement(i).SetIndex (k); - } - - - - mesh3d.CalcSurfacesOfNode(); - mesh3d.FindOpenElements(); - - teterrpow = 2; - if (mesh3d.GetNOpenElements() != 0) - { - meshed = 0; - (*mycout) << "Open elements found, old" << endl; - const char * optstr = "mcmcmcmcm"; - int j; - for (j = 1; j <= strlen(optstr); j++) - switch (optstr[j-1]) - { - case 'c': mesh3d.CombineImprove(); break; - case 'd': mesh3d.SplitImprove(); break; - case 's': mesh3d.SwapImprove(); break; - case 'm': mesh3d.ImproveMesh(2); break; - } - - (*mycout) << "Call remove" << endl; - RemoveProblem (mesh3d); - (*mycout) << "Problem removed" << endl; - } - else - meshed = 1; - } - while (!meshed); - - MeshQuality3d (mesh3d); - - return MESHING3_OK; - } - - */ - - - - - /* - MESHING3_RESULT MeshMixedVolume(MeshingParameters & mp, Mesh& mesh3d) - { - int i, j; - MESHING3_RESULT res; - Point3d pmin, pmax; - - mp.giveuptol = 10; - mp.baseelnp = 4; - mp.starshapeclass = 100; - - // TerminalPlotStatistics3d pstat; - - Meshing3 meshing1("pyramids.rls"); - for (i = 1; i <= mesh3d.GetNP(); i++) - meshing1.AddPoint (mesh3d.Point(i), i); - - mesh3d.FindOpenElements(); - for (i = 1; i <= mesh3d.GetNOpenElements(); i++) - if (mesh3d.OpenElement(i).GetIndex() == 1) - meshing1.AddBoundaryElement (mesh3d.OpenElement(i)); - - res = meshing1.GenerateMesh (mesh3d, mp); - - mesh3d.GetBox (pmin, pmax); - PrintMessage (1, "Mesh pyramids, res = ", res); - if (res) - exit (1); - - - for (i = 1; i <= mesh3d.GetNE(); i++) - mesh3d.VolumeElement(i).SetIndex (1); - - // do delaunay - - mp.baseelnp = 0; - mp.starshapeclass = 5; - - Meshing3 meshing2(NULL); - for (i = 1; i <= mesh3d.GetNP(); i++) - meshing2.AddPoint (mesh3d.Point(i), i); - - mesh3d.FindOpenElements(); - for (i = 1; i <= mesh3d.GetNOpenElements(); i++) - if (mesh3d.OpenElement(i).GetIndex() == 1) - meshing2.AddBoundaryElement (mesh3d.OpenElement(i)); - - MeshingParameters mpd; - meshing2.Delaunay (mesh3d, mpd); - - for (i = 1; i <= mesh3d.GetNE(); i++) - mesh3d.VolumeElement(i).SetIndex (1); - - - mp.baseelnp = 0; - mp.giveuptol = 10; - - for (int trials = 1; trials <= 50; trials++) - { - if (multithread.terminate) - return MESHING3_TERMINATE; - - Meshing3 meshing3("tetra.rls"); - for (i = 1; i <= mesh3d.GetNP(); i++) - meshing3.AddPoint (mesh3d.Point(i), i); - - mesh3d.FindOpenElements(); - for (i = 1; i <= mesh3d.GetNOpenElements(); i++) - if (mesh3d.OpenElement(i).GetIndex() == 1) - meshing3.AddBoundaryElement (mesh3d.OpenElement(i)); - - if (trials > 1) - CheckSurfaceMesh2 (mesh3d); - res = meshing3.GenerateMesh (mesh3d, mp); - - for (i = 1; i <= mesh3d.GetNE(); i++) - mesh3d.VolumeElement(i).SetIndex (1); - - if (res == 0) break; - - - - for (i = 1; i <= mesh3d.GetNE(); i++) - { - const Element & el = mesh3d.VolumeElement(i); - if (el.GetNP() != 4) - { - for (j = 1; j <= el.GetNP(); j++) - mesh3d.AddLockedPoint (el.PNum(j)); - } - } - - mesh3d.CalcSurfacesOfNode(); - mesh3d.FindOpenElements(); - - MeshOptimize3d optmesh; - - teterrpow = 2; - const char * optstr = "mcmcmcmcm"; - for (j = 1; j <= strlen(optstr); j++) - switch (optstr[j-1]) - { - case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break; - case 'd': optmesh.SplitImprove(mesh3d); break; - case 's': optmesh.SwapImprove(mesh3d); break; - case 'm': mesh3d.ImproveMesh(); break; - } - - RemoveProblem (mesh3d); - } - - - PrintMessage (1, "Meshing tets, res = ", res); - if (res) - { - mesh3d.FindOpenElements(); - PrintSysError (1, "Open elements: ", mesh3d.GetNOpenElements()); - exit (1); - } - - - - for (i = 1; i <= mesh3d.GetNE(); i++) - { - const Element & el = mesh3d.VolumeElement(i); - if (el.GetNP() != 4) - { - for (j = 1; j <= el.GetNP(); j++) - mesh3d.AddLockedPoint (el.PNum(j)); - } - } - - mesh3d.CalcSurfacesOfNode(); - mesh3d.FindOpenElements(); - - MeshOptimize3d optmesh; - - teterrpow = 2; - const char * optstr = "mcmcmcmcm"; - for (j = 1; j <= strlen(optstr); j++) - switch (optstr[j-1]) - { - case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break; - case 'd': optmesh.SplitImprove(mesh3d); break; - case 's': optmesh.SwapImprove(mesh3d); break; - case 'm': mesh3d.ImproveMesh(); break; - } - - - return MESHING3_OK; - } -*/ - - - - - - MESHING3_RESULT OptimizeVolume (const MeshingParameters & mp, Mesh & mesh3d) // const CSGeometry * geometry) diff --git a/libsrc/meshing/meshing3.cpp b/libsrc/meshing/meshing3.cpp index 6957251c..3d1b7341 100644 --- a/libsrc/meshing/meshing3.cpp +++ b/libsrc/meshing/meshing3.cpp @@ -1094,11 +1094,10 @@ static int TestSameSide (const Point3d & p1, const Point3d & p2) */ - -void Meshing3 :: BlockFillLocalH (Mesh & mesh, +void Meshing3 :: PrepareBlockFillLocalH (Mesh & mesh, const MeshingParameters & mp) { - static Timer t("Mesing3::BlockFillLocalH"); RegionTimer reg(t); + static Timer t("Mesing3::PrepareBlockFillLocalH"); RegionTimer reg(t); double filldist = mp.filldist; @@ -1107,10 +1106,95 @@ void Meshing3 :: BlockFillLocalH (Mesh & mesh, PrintMessage (3, "blockfill local h"); - NgArray > npoints; - adfront -> CreateTrees(); + double maxh = 0; + + for (int i = 1; i <= adfront->GetNF(); i++) + { + const MiniElement2d & el = adfront->GetFace(i); + for (int j = 1; j <= 3; j++) + { + const Point3d & p1 = adfront->GetPoint (el.PNumMod(j)); + const Point3d & p2 = adfront->GetPoint (el.PNumMod(j+1)); + + double hi = Dist (p1, p2); + if (hi > maxh) maxh = hi; + } + } + + + if (mp.maxh < maxh) maxh = mp.maxh; + + // auto loch_ptr = mesh.LocalHFunction().Copy(); + // auto & loch = *loch_ptr; + auto & loch = mesh.LocalHFunction(); + + bool changed; + static Timer t1("loop1"); + t1.Start(); + do + { + loch.ClearFlags(); + + static Timer tbox("adfront-bbox"); + tbox.Start(); + for (int i = 1; i <= adfront->GetNF(); i++) + { + const MiniElement2d & el = adfront->GetFace(i); + + Box<3> bbox (adfront->GetPoint (el[0])); + bbox.Add (adfront->GetPoint (el[1])); + bbox.Add (adfront->GetPoint (el[2])); + + + double filld = filldist * bbox.Diam(); + bbox.Increase (filld); + + loch.CutBoundary (bbox); // .PMin(), bbox.PMax()); + } + tbox.Stop(); + + // locadfront = adfront; + loch.FindInnerBoxes (adfront, NULL); + + npoints.SetSize(0); + loch.GetInnerPoints (npoints); + + changed = false; + for (int i = 1; i <= npoints.Size(); i++) + { + if (loch.GetH(npoints.Get(i)) > 1.5 * maxh) + { + loch.SetH (npoints.Get(i), maxh); + changed = true; + } + } + } + while (changed); + t1.Stop(); + + + +} + +void Meshing3 :: BlockFillLocalH (Mesh & mesh, + const MeshingParameters & mp) +{ + static Timer t("Mesing3::BlockFillLocalH"); RegionTimer reg(t); + + if (!mesh.HasLocalHFunction()) + { + mesh.CalcLocalH(mp.grading); + PrepareBlockFillLocalH(mesh, mp); + } + + double filldist = mp.filldist; + + // (*testout) << "blockfill local h" << endl; + // (*testout) << "rel filldist = " << filldist << endl; + PrintMessage (3, "blockfill local h"); + Box<3> bbox ( Box<3>::EMPTY_BOX ); double maxh = 0; @@ -1144,44 +1228,6 @@ void Meshing3 :: BlockFillLocalH (Mesh & mesh, if (mp.maxh < maxh) maxh = mp.maxh; - bool changed; - do - { - mesh.LocalHFunction().ClearFlags(); - - for (int i = 1; i <= adfront->GetNF(); i++) - { - const MiniElement2d & el = adfront->GetFace(i); - - Box<3> bbox (adfront->GetPoint (el[0])); - bbox.Add (adfront->GetPoint (el[1])); - bbox.Add (adfront->GetPoint (el[2])); - - - double filld = filldist * bbox.Diam(); - bbox.Increase (filld); - - mesh.LocalHFunction().CutBoundary (bbox); // .PMin(), bbox.PMax()); - } - - // locadfront = adfront; - mesh.LocalHFunction().FindInnerBoxes (adfront, NULL); - - npoints.SetSize(0); - mesh.LocalHFunction().GetInnerPoints (npoints); - - changed = false; - for (int i = 1; i <= npoints.Size(); i++) - { - if (mesh.LocalHFunction().GetH(npoints.Get(i)) > 1.5 * maxh) - { - mesh.LocalHFunction().SetH (npoints.Get(i), maxh); - changed = true; - } - } - } - while (changed); - if (debugparam.slowchecks) (*testout) << "Blockfill with points: " << endl; for (int i = 1; i <= npoints.Size(); i++) @@ -1208,6 +1254,8 @@ void Meshing3 :: BlockFillLocalH (Mesh & mesh, // find outer points + static Timer tloch2("build loch2"); + tloch2.Start(); loch2.ClearFlags(); for (int i = 1; i <= adfront->GetNF(); i++) @@ -1245,6 +1293,7 @@ void Meshing3 :: BlockFillLocalH (Mesh & mesh, // loch2.CutBoundary (pmin, pmax); loch2.CutBoundary (Box<3> (pmin, pmax)); // pmin, pmax); } + tloch2.Stop(); // locadfront = adfront; loch2.FindInnerBoxes (adfront, NULL); diff --git a/libsrc/meshing/meshing3.hpp b/libsrc/meshing/meshing3.hpp index 65b153b9..2944c6c3 100644 --- a/libsrc/meshing/meshing3.hpp +++ b/libsrc/meshing/meshing3.hpp @@ -28,6 +28,7 @@ class Meshing3 NgArray problems; /// tolerance criterion double tolfak; + NgArray > npoints; public: /// Meshing3 (const string & rulefilename); @@ -63,6 +64,7 @@ public: /// void BlockFill (Mesh & mesh, double gh); /// + void PrepareBlockFillLocalH (Mesh & mesh, const MeshingParameters & mp); void BlockFillLocalH (Mesh & mesh, const MeshingParameters & mp); /// uses points of adfront, and puts new elements into mesh diff --git a/libsrc/meshing/meshtype.hpp b/libsrc/meshing/meshtype.hpp index 20a34477..72488d8a 100644 --- a/libsrc/meshing/meshtype.hpp +++ b/libsrc/meshing/meshtype.hpp @@ -852,13 +852,24 @@ namespace netgen { _np = np; _typ = typ; _curved = is_curved; } // ar & _np & _typ & index & _curved; ar.DoPacked (_np, _typ, index, _curved); - if (ar.Input()) - { np = _np; typ = ELEMENT_TYPE(_typ); is_curved = _curved; } - /* - for (size_t i = 0; i < np; i++) - ar & pnum[i]; - */ + if (ar.Input()) + { + np = _np; + typ = ELEMENT_TYPE(_typ); + is_curved = _curved; + flags.marked = 1; + flags.badel = 0; + flags.reverse = 0; + flags.illegal = 0; + flags.illegal_valid = 0; + flags.badness_valid = 0; + flags.refflag = 1; + flags.strongrefflag = false; + flags.deleted = 0; + flags.fixed = 0; + } + static_assert(sizeof(int) == sizeof (PointIndex)); ar.Do( (int*)&pnum[0], np); } diff --git a/libsrc/meshing/msghandler.cpp b/libsrc/meshing/msghandler.cpp index d4da2c60..e1aa37f4 100644 --- a/libsrc/meshing/msghandler.cpp +++ b/libsrc/meshing/msghandler.cpp @@ -134,6 +134,7 @@ void ResetStatus() void PushStatus(const MyStr& s) { + return; msgstatus_stack.Append(new MyStr (s)); SetStatMsg(s); threadpercent_stack.Append(0); @@ -141,6 +142,7 @@ void PushStatus(const MyStr& s) void PushStatusF(const MyStr& s) { + return; msgstatus_stack.Append(new MyStr (s)); SetStatMsg(s); threadpercent_stack.Append(0); @@ -149,6 +151,7 @@ void PushStatusF(const MyStr& s) void PopStatus() { + return; if (msgstatus_stack.Size()) { if (msgstatus_stack.Size() > 1) diff --git a/tests/pytest/compare_results.py b/tests/pytest/compare_results.py index ed2c2dca..84e9efe8 100644 --- a/tests/pytest/compare_results.py +++ b/tests/pytest/compare_results.py @@ -15,7 +15,6 @@ def readData(a, files): file=[] for f in files: for t in a[f]: - file.append(f) if t['ne1d']>0: ne1d.append(t['ne1d']) if t['ne2d']>0: @@ -24,6 +23,7 @@ def readData(a, files): ne3d.append(t['ne3d']) if t['total_badness']>0.0: bad.append(t['total_badness']) + file.append(f) if 'angles_tet' in t: amin.append(t['angles_tet'][0]) amax.append(t['angles_tet'][1]) diff --git a/tests/pytest/results.json b/tests/pytest/results.json index 161dd1ea..8c8b0139 100644 --- a/tests/pytest/results.json +++ b/tests/pytest/results.json @@ -77,18 +77,18 @@ }, { "angles_tet": [ - 24.309, - 138.49 + 23.388, + 134.51 ], "angles_trig": [ 24.858, - 104.73 + 112.19 ], "ne1d": 181, "ne2d": 313, - "ne3d": 506, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 13, 25, 47, 64, 85, 94, 100, 51, 17]", - "total_badness": 650.35553279 + "ne3d": 513, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 17, 27, 54, 62, 87, 81, 98, 60, 21]", + "total_badness": 658.96429261 } ], "boxcyl.geo": [ @@ -124,8 +124,8 @@ }, { "angles_tet": [ - 15.88, - 154.64 + 15.882, + 154.85 ], "angles_trig": [ 20.0, @@ -133,9 +133,9 @@ ], "ne1d": 136, "ne2d": 222, - "ne3d": 352, - "quality_histogram": "[0, 0, 0, 0, 0, 5, 5, 7, 4, 7, 14, 26, 24, 54, 64, 61, 47, 18, 14, 2]", - "total_badness": 527.329265 + "ne3d": 357, + "quality_histogram": "[0, 0, 0, 0, 0, 5, 5, 6, 5, 8, 13, 23, 25, 50, 68, 58, 56, 21, 11, 3]", + "total_badness": 531.95100655 }, { "angles_tet": [ @@ -463,7 +463,7 @@ { "angles_tet": [ 5.3682, - 165.74 + 166.05 ], "angles_trig": [ 11.3, @@ -471,24 +471,24 @@ ], "ne1d": 262, "ne2d": 702, - "ne3d": 2099, - "quality_histogram": "[0, 0, 12, 32, 71, 94, 120, 96, 80, 58, 45, 67, 130, 209, 229, 261, 252, 190, 121, 32]", - "total_badness": 3918.4348785 + "ne3d": 2095, + "quality_histogram": "[0, 0, 13, 33, 70, 93, 118, 97, 80, 55, 43, 74, 127, 207, 219, 267, 264, 192, 112, 31]", + "total_badness": 3914.3913191 }, { "angles_tet": [ - 29.146, + 29.972, 134.34 ], "angles_trig": [ 25.65, - 116.54 + 118.92 ], "ne1d": 134, "ne2d": 160, - "ne3d": 244, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 25, 35, 41, 42, 42, 31, 15, 4, 2]", - "total_badness": 346.48816749 + "ne3d": 238, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 22, 39, 44, 35, 39, 30, 14, 5, 1]", + "total_badness": 340.29402313 }, { "angles_tet": [ @@ -501,9 +501,9 @@ ], "ne1d": 190, "ne2d": 282, - "ne3d": 584, - "quality_histogram": "[0, 0, 0, 0, 2, 0, 1, 5, 2, 15, 44, 43, 59, 99, 94, 91, 62, 43, 21, 3]", - "total_badness": 858.49088107 + "ne3d": 589, + "quality_histogram": "[0, 0, 0, 0, 2, 0, 0, 5, 2, 13, 40, 46, 62, 105, 91, 93, 60, 46, 20, 4]", + "total_badness": 862.8968917 }, { "angles_tet": [ @@ -516,9 +516,9 @@ ], "ne1d": 262, "ne2d": 702, - "ne3d": 2003, - "quality_histogram": "[0, 0, 2, 10, 38, 80, 114, 93, 69, 29, 54, 52, 121, 183, 222, 268, 284, 211, 139, 34]", - "total_badness": 3430.228346 + "ne3d": 1978, + "quality_histogram": "[0, 0, 2, 10, 39, 81, 115, 92, 68, 28, 53, 54, 110, 175, 225, 265, 273, 220, 133, 35]", + "total_badness": 3396.7269266 }, { "angles_tet": [ @@ -662,32 +662,32 @@ { "angles_tet": [ 20.409, - 143.04 + 143.05 ], "angles_trig": [ - 17.822, - 126.28 + 17.857, + 129.03 ], "ne1d": 64, "ne2d": 626, - "ne3d": 3285, - "quality_histogram": "[0, 0, 0, 0, 0, 1, 11, 13, 29, 65, 108, 230, 334, 508, 490, 550, 424, 337, 153, 32]", - "total_badness": 4649.9190359 + "ne3d": 3287, + "quality_histogram": "[0, 0, 0, 0, 0, 1, 12, 12, 28, 60, 114, 217, 356, 477, 533, 526, 427, 326, 160, 38]", + "total_badness": 4647.9849621 }, { "angles_tet": [ - 20.792, - 142.3 + 20.408, + 142.77 ], "angles_trig": [ - 16.821, - 121.95 + 17.345, + 126.66 ], "ne1d": 102, "ne2d": 1396, - "ne3d": 8170, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 2, 16, 62, 196, 410, 708, 1083, 1337, 1335, 1256, 994, 584, 186]", - "total_badness": 11044.804929 + "ne3d": 8210, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 3, 16, 60, 195, 429, 755, 1093, 1287, 1392, 1239, 995, 562, 184]", + "total_badness": 11121.187355 }, { "angles_tet": [ @@ -753,33 +753,33 @@ }, { "angles_tet": [ - 17.007, - 143.72 + 17.164, + 141.46 ], "angles_trig": [ - 14.293, - 127.98 + 14.437, + 126.84 ], "ne1d": 44, "ne2d": 246, - "ne3d": 735, - "quality_histogram": "[0, 0, 0, 0, 1, 1, 4, 17, 19, 42, 61, 80, 110, 117, 102, 73, 58, 27, 15, 8]", - "total_badness": 1161.4977052 + "ne3d": 727, + "quality_histogram": "[0, 0, 0, 0, 1, 0, 3, 13, 21, 42, 56, 89, 104, 100, 111, 75, 57, 34, 18, 3]", + "total_badness": 1139.0124704 }, { "angles_tet": [ - 20.529, + 20.627, 148.73 ], "angles_trig": [ - 20.178, - 127.02 + 20.235, + 125.83 ], "ne1d": 68, "ne2d": 396, - "ne3d": 1561, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 4, 14, 18, 57, 119, 168, 225, 245, 243, 239, 150, 65, 14]", - "total_badness": 2194.1567943 + "ne3d": 1564, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 4, 15, 20, 66, 116, 163, 226, 246, 252, 225, 157, 63, 11]", + "total_badness": 2205.4352879 }, { "angles_tet": [ @@ -798,18 +798,18 @@ }, { "angles_tet": [ - 22.863, + 22.862, 138.41 ], "angles_trig": [ - 23.26, - 121.85 + 23.255, + 128.04 ], "ne1d": 146, "ne2d": 1482, - "ne3d": 17978, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 45, 148, 430, 972, 1910, 3013, 3819, 4010, 2787, 839]", - "total_badness": 22078.910603 + "ne3d": 18030, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 50, 157, 444, 990, 1901, 3070, 3790, 4014, 2780, 829]", + "total_badness": 22163.624731 }, { "angles_tet": [ @@ -1184,17 +1184,17 @@ { "angles_tet": [ 18.27, - 146.04 + 146.12 ], "angles_trig": [ - 21.368, - 124.04 + 22.399, + 122.6 ], "ne1d": 156, "ne2d": 988, - "ne3d": 2245, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 7, 14, 43, 75, 120, 183, 280, 343, 372, 323, 268, 180, 37]", - "total_badness": 3082.4279481 + "ne3d": 2231, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 7, 8, 46, 73, 113, 188, 290, 342, 364, 319, 261, 179, 41]", + "total_badness": 3060.1530864 }, { "angles_tet": [ @@ -1228,18 +1228,18 @@ }, { "angles_tet": [ - 20.945, - 138.99 + 19.709, + 143.75 ], "angles_trig": [ - 22.422, + 22.581, 121.69 ], "ne1d": 156, "ne2d": 988, - "ne3d": 2191, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 3, 9, 25, 53, 97, 140, 243, 333, 354, 377, 308, 188, 61]", - "total_badness": 2925.6156836 + "ne3d": 2182, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 4, 7, 33, 47, 87, 142, 263, 318, 355, 373, 308, 180, 65]", + "total_badness": 2916.2059945 }, { "angles_tet": [ @@ -1361,9 +1361,9 @@ ], "ne1d": 50, "ne2d": 38, - "ne3d": 36, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 4, 7, 6, 8, 1, 1, 0, 1]", - "total_badness": 53.038414986 + "ne3d": 35, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 3, 8, 4, 10, 2, 0, 0, 2]", + "total_badness": 50.263302236 }, { "angles_tet": [ @@ -1406,9 +1406,9 @@ ], "ne1d": 50, "ne2d": 38, - "ne3d": 36, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 4, 7, 6, 8, 1, 1, 0, 1]", - "total_badness": 53.038414986 + "ne3d": 35, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 3, 8, 4, 10, 2, 0, 0, 2]", + "total_badness": 50.263302236 }, { "angles_tet": [ @@ -1444,7 +1444,7 @@ "frame.step": [ { "angles_tet": [ - 2.9086, + 2.906, 171.1 ], "angles_trig": [ @@ -1453,14 +1453,14 @@ ], "ne1d": 10108, "ne2d": 29958, - "ne3d": 152461, - "quality_histogram": "[0, 3, 1, 3, 6, 18, 51, 153, 539, 1234, 2814, 5708, 10236, 16240, 21696, 25712, 26711, 22859, 14609, 3868]", - "total_badness": 201603.34124 + "ne3d": 152534, + "quality_histogram": "[0, 3, 1, 3, 6, 14, 58, 147, 466, 1206, 2715, 5679, 10184, 16198, 21769, 25949, 26794, 22865, 14592, 3885]", + "total_badness": 201509.42542 }, { "angles_tet": [ 2.296, - 175.72 + 175.61 ], "angles_trig": [ 3.4731, @@ -1468,13 +1468,13 @@ ], "ne1d": 5988, "ne2d": 10976, - "ne3d": 28875, - "quality_histogram": "[3, 4, 4, 9, 16, 45, 103, 213, 662, 993, 1514, 2528, 3069, 3888, 4348, 4102, 3364, 2352, 1334, 324]", - "total_badness": 42759.274327 + "ne3d": 28946, + "quality_histogram": "[3, 4, 5, 11, 16, 45, 102, 210, 663, 980, 1507, 2531, 3080, 3906, 4321, 4193, 3360, 2375, 1322, 312]", + "total_badness": 42858.494901 }, { "angles_tet": [ - 2.1678, + 2.171, 174.11 ], "angles_trig": [ @@ -1483,9 +1483,9 @@ ], "ne1d": 9622, "ne2d": 23596, - "ne3d": 79955, - "quality_histogram": "[2, 15, 2, 17, 16, 36, 79, 196, 428, 1003, 2107, 4194, 7142, 10182, 12517, 13476, 12277, 9263, 5564, 1439]", - "total_badness": 109848.90296 + "ne3d": 80222, + "quality_histogram": "[2, 15, 4, 17, 17, 35, 89, 194, 426, 984, 2152, 4199, 7155, 10324, 12467, 13496, 12313, 9367, 5529, 1437]", + "total_badness": 110253.4299 } ], "hinge.stl": [ @@ -1500,13 +1500,13 @@ ], "ne1d": 456, "ne2d": 1212, - "ne3d": 1985, - "quality_histogram": "[0, 0, 0, 0, 0, 3, 3, 11, 21, 48, 78, 121, 177, 243, 281, 291, 257, 267, 140, 44]", - "total_badness": 2774.8392965 + "ne3d": 1977, + "quality_histogram": "[0, 0, 0, 0, 0, 1, 3, 10, 15, 45, 78, 122, 186, 262, 287, 291, 242, 249, 142, 44]", + "total_badness": 2760.6220954 }, { "angles_tet": [ - 7.6058, + 7.7862, 161.84 ], "angles_trig": [ @@ -1515,9 +1515,9 @@ ], "ne1d": 298, "ne2d": 610, - "ne3d": 785, - "quality_histogram": "[0, 0, 2, 11, 6, 6, 19, 18, 36, 45, 66, 84, 102, 91, 81, 82, 51, 54, 26, 5]", - "total_badness": 1354.028297 + "ne3d": 778, + "quality_histogram": "[0, 0, 2, 10, 9, 8, 23, 16, 37, 43, 67, 80, 99, 93, 80, 82, 48, 50, 27, 4]", + "total_badness": 1361.2707696 }, { "angles_tet": [ @@ -1530,39 +1530,39 @@ ], "ne1d": 370, "ne2d": 850, - "ne3d": 1123, - "quality_histogram": "[0, 0, 1, 1, 7, 6, 15, 27, 38, 52, 69, 112, 144, 138, 162, 142, 96, 62, 43, 8]", - "total_badness": 1791.0009554 + "ne3d": 1132, + "quality_histogram": "[0, 0, 1, 1, 7, 6, 15, 29, 42, 47, 70, 110, 142, 142, 161, 144, 97, 66, 44, 8]", + "total_badness": 1804.9964367 }, { "angles_tet": [ - 13.442, + 11.964, 156.97 ], "angles_trig": [ - 21.769, + 19.521, 131.54 ], "ne1d": 516, "ne2d": 1570, - "ne3d": 2603, - "quality_histogram": "[0, 0, 0, 0, 0, 4, 3, 5, 24, 49, 99, 162, 236, 315, 392, 410, 338, 298, 213, 55]", - "total_badness": 3617.4946271 + "ne3d": 2589, + "quality_histogram": "[0, 0, 0, 0, 1, 2, 2, 5, 33, 55, 86, 166, 228, 303, 411, 396, 353, 287, 206, 55]", + "total_badness": 3605.1956692 }, { "angles_tet": [ 19.878, - 146.81 + 145.41 ], "angles_trig": [ - 21.108, - 133.01 + 23.111, + 130.19 ], "ne1d": 722, "ne2d": 2856, - "ne3d": 6742, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 2, 22, 37, 55, 164, 381, 655, 846, 1080, 1151, 1213, 867, 268]", - "total_badness": 8659.2800224 + "ne3d": 6746, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 2, 2, 23, 31, 71, 156, 371, 632, 835, 1077, 1180, 1209, 888, 269]", + "total_badness": 8654.616002 }, { "angles_tet": [ @@ -1575,9 +1575,9 @@ ], "ne1d": 1862, "ne2d": 19428, - "ne3d": 136241, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 3, 21, 85, 308, 898, 2566, 6394, 12973, 21289, 28986, 31392, 23775, 7551]", - "total_badness": 165729.88879 + "ne3d": 136270, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 3, 19, 90, 309, 895, 2578, 6407, 12994, 21327, 29004, 31357, 23759, 7528]", + "total_badness": 165792.84022 } ], "lense.in2d": [ @@ -1806,9 +1806,9 @@ ], "ne1d": 4106, "ne2d": 27824, - "ne3d": 70201, - "quality_histogram": "[0, 0, 0, 1, 27, 76, 199, 309, 649, 1436, 2566, 3992, 6615, 9029, 10226, 10693, 9895, 7793, 4854, 1841]", - "total_badness": 98065.083443 + "ne3d": 70230, + "quality_histogram": "[0, 0, 0, 1, 27, 76, 197, 309, 658, 1433, 2557, 3994, 6611, 9073, 10219, 10679, 9920, 7787, 4836, 1853]", + "total_badness": 98105.849616 } ], "manyholes2.geo": [ @@ -1823,31 +1823,31 @@ ], "ne1d": 10202, "ne2d": 54864, - "ne3d": 127476, - "quality_histogram": "[0, 0, 0, 0, 3, 26, 67, 253, 706, 2016, 4264, 7581, 11687, 16856, 18247, 18310, 17519, 15264, 10990, 3687]", - "total_badness": 174923.26093 + "ne3d": 127454, + "quality_histogram": "[0, 0, 0, 0, 3, 26, 67, 250, 706, 2002, 4267, 7577, 11668, 16888, 18234, 18308, 17538, 15257, 10987, 3676]", + "total_badness": 174883.29195 } ], "matrix.geo": [ { "angles_tet": [ - 6.3942, - 171.62 + 9.2999, + 168.64 ], "angles_trig": [ - 8.6593, - 160.8 + 9.9493, + 158.64 ], "ne1d": 174, "ne2d": 1190, - "ne3d": 5100, - "quality_histogram": "[0, 0, 15, 128, 183, 43, 56, 114, 127, 183, 297, 369, 495, 599, 625, 611, 547, 412, 235, 61]", - "total_badness": 8961.2205551 + "ne3d": 5022, + "quality_histogram": "[0, 3, 8, 136, 159, 66, 55, 110, 121, 162, 298, 364, 481, 579, 646, 567, 522, 445, 244, 56]", + "total_badness": 8822.5232362 }, { "angles_tet": [ - 3.4677, - 173.13 + 7.9454, + 167.7 ], "angles_trig": [ 9.2392, @@ -1855,54 +1855,54 @@ ], "ne1d": 106, "ne2d": 564, - "ne3d": 1498, - "quality_histogram": "[0, 2, 15, 56, 89, 130, 198, 136, 138, 115, 110, 107, 116, 99, 71, 34, 36, 25, 15, 6]", - "total_badness": 3831.0654483 + "ne3d": 1506, + "quality_histogram": "[0, 1, 11, 48, 84, 143, 185, 151, 135, 109, 121, 113, 118, 100, 71, 34, 36, 25, 15, 6]", + "total_badness": 3783.4247875 }, { "angles_tet": [ - 7.6687, - 169.26 + 7.058, + 170.94 ], "angles_trig": [ - 8.6573, - 161.61 + 9.6098, + 160.25 ], "ne1d": 132, "ne2d": 812, - "ne3d": 2514, - "quality_histogram": "[0, 0, 7, 63, 69, 154, 134, 117, 148, 199, 247, 286, 257, 214, 177, 162, 120, 92, 45, 23]", - "total_badness": 5239.4475113 + "ne3d": 2452, + "quality_histogram": "[0, 0, 6, 40, 93, 132, 144, 118, 151, 182, 257, 278, 268, 182, 163, 172, 118, 83, 46, 19]", + "total_badness": 5085.642302 }, { "angles_tet": [ - 6.3942, - 171.62 + 9.4657, + 168.64 ], "angles_trig": [ - 8.6592, - 160.8 + 9.9493, + 158.64 ], "ne1d": 174, "ne2d": 1190, - "ne3d": 5054, - "quality_histogram": "[0, 0, 14, 117, 182, 41, 51, 115, 112, 153, 269, 315, 481, 581, 632, 634, 561, 474, 247, 75]", - "total_badness": 8725.1829981 + "ne3d": 4957, + "quality_histogram": "[0, 0, 5, 130, 150, 54, 48, 97, 112, 150, 252, 322, 470, 586, 602, 591, 566, 476, 275, 71]", + "total_badness": 8482.9984793 }, { "angles_tet": [ - 12.76, - 147.23 + 14.607, + 147.71 ], "angles_trig": [ - 15.824, + 16.257, 143.02 ], "ne1d": 248, "ne2d": 2320, - "ne3d": 16407, - "quality_histogram": "[0, 0, 0, 0, 0, 4, 20, 55, 118, 191, 287, 630, 956, 1497, 2097, 2550, 2936, 2608, 1913, 545]", - "total_badness": 21630.784432 + "ne3d": 16318, + "quality_histogram": "[0, 0, 0, 0, 0, 5, 22, 60, 105, 164, 321, 626, 1045, 1473, 2233, 2454, 2878, 2659, 1762, 511]", + "total_badness": 21585.561739 }, { "angles_tet": [ @@ -1911,13 +1911,13 @@ ], "angles_trig": [ 17.821, - 130.51 + 127.08 ], "ne1d": 418, "ne2d": 5958, - "ne3d": 102414, - "quality_histogram": "[0, 0, 0, 0, 0, 1, 4, 6, 45, 124, 368, 1028, 2576, 5782, 10622, 16119, 21223, 22353, 16809, 5354]", - "total_badness": 125921.99427 + "ne3d": 100762, + "quality_histogram": "[0, 0, 0, 0, 0, 1, 5, 8, 38, 107, 367, 1009, 2443, 5430, 10312, 16080, 20635, 21897, 17095, 5335]", + "total_badness": 123670.82692 } ], "ortho.geo": [ @@ -2015,18 +2015,18 @@ "part1.stl": [ { "angles_tet": [ - 13.063, - 147.22 + 21.018, + 145.74 ], "angles_trig": [ - 19.94, - 119.28 + 20.888, + 125.82 ], "ne1d": 170, "ne2d": 448, - "ne3d": 1232, - "quality_histogram": "[0, 0, 0, 0, 0, 1, 3, 7, 14, 22, 38, 66, 91, 150, 218, 198, 155, 156, 86, 27]", - "total_badness": 1707.0143419 + "ne3d": 1259, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 4, 8, 13, 21, 38, 69, 103, 136, 224, 198, 179, 138, 101, 27]", + "total_badness": 1739.7208845 }, { "angles_tet": [ @@ -2039,14 +2039,14 @@ ], "ne1d": 134, "ne2d": 286, - "ne3d": 509, - "quality_histogram": "[0, 0, 0, 2, 4, 3, 5, 5, 18, 25, 33, 48, 51, 64, 72, 65, 52, 30, 24, 8]", - "total_badness": 798.54900393 + "ne3d": 514, + "quality_histogram": "[0, 0, 0, 2, 4, 3, 4, 4, 18, 23, 36, 40, 67, 57, 65, 71, 56, 38, 23, 3]", + "total_badness": 801.0166951 }, { "angles_tet": [ - 19.624, - 148.62 + 20.054, + 147.85 ], "angles_trig": [ 19.446, @@ -2054,9 +2054,9 @@ ], "ne1d": 194, "ne2d": 590, - "ne3d": 1631, - "quality_histogram": "[0, 0, 0, 0, 0, 1, 1, 2, 7, 15, 35, 54, 127, 203, 240, 247, 285, 232, 144, 38]", - "total_badness": 2179.4995302 + "ne3d": 1641, + "quality_histogram": "[0, 0, 0, 0, 0, 1, 0, 4, 5, 15, 35, 59, 136, 181, 263, 261, 281, 218, 148, 34]", + "total_badness": 2193.9430492 }, { "angles_tet": [ @@ -2064,19 +2064,19 @@ 150.39 ], "angles_trig": [ - 23.604, - 120.32 + 23.365, + 119.75 ], "ne1d": 266, "ne2d": 980, - "ne3d": 4061, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 1, 2, 5, 30, 78, 131, 284, 527, 619, 852, 827, 552, 152]", - "total_badness": 5098.4284907 + "ne3d": 4126, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 0, 1, 12, 26, 62, 188, 281, 508, 660, 867, 823, 561, 136]", + "total_badness": 5189.9740302 }, { "angles_tet": [ - 20.783, - 146.42 + 20.78, + 146.34 ], "angles_trig": [ 24.61, @@ -2084,101 +2084,101 @@ ], "ne1d": 674, "ne2d": 6832, - "ne3d": 82637, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 4, 17, 97, 397, 1390, 3595, 7583, 12590, 17553, 19516, 15071, 4823]", - "total_badness": 99971.30166 + "ne3d": 82638, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 4, 17, 95, 389, 1384, 3560, 7554, 12625, 17561, 19497, 15113, 4838]", + "total_badness": 99948.684705 } ], "period.geo": [ { "angles_tet": [ - 13.348, - 152.73 + 14.261, + 145.23 ], "angles_trig": [ 15.314, - 135.35 + 135.43 ], "ne1d": 344, "ne2d": 1118, - "ne3d": 3303, - "quality_histogram": "[0, 0, 0, 0, 1, 3, 19, 26, 62, 80, 167, 270, 341, 414, 475, 449, 428, 344, 170, 54]", - "total_badness": 4786.8429022 + "ne3d": 3244, + "quality_histogram": "[0, 0, 0, 0, 1, 2, 17, 23, 60, 76, 186, 248, 338, 436, 447, 438, 420, 341, 163, 48]", + "total_badness": 4702.5839044 }, { "angles_tet": [ - 10.254, - 166.55 + 12.301, + 162.28 ], "angles_trig": [ 14.767, - 144.13 + 141.06 ], "ne1d": 160, "ne2d": 280, - "ne3d": 581, - "quality_histogram": "[0, 0, 1, 1, 4, 8, 17, 22, 29, 58, 59, 78, 67, 40, 55, 45, 32, 46, 16, 3]", - "total_badness": 1019.9118615 + "ne3d": 587, + "quality_histogram": "[0, 0, 0, 0, 6, 11, 16, 25, 34, 52, 59, 81, 61, 43, 51, 52, 32, 49, 12, 3]", + "total_badness": 1032.3023037 }, { "angles_tet": [ - 13.869, - 161.3 + 13.112, + 162.52 ], "angles_trig": [ - 16.622, + 14.216, 141.37 ], "ne1d": 232, "ne2d": 566, - "ne3d": 1302, - "quality_histogram": "[0, 0, 0, 1, 4, 17, 29, 39, 64, 86, 116, 123, 148, 143, 127, 134, 119, 83, 58, 11]", - "total_badness": 2151.3919236 + "ne3d": 1298, + "quality_histogram": "[0, 0, 0, 0, 6, 20, 29, 43, 58, 102, 116, 121, 144, 136, 120, 125, 121, 83, 65, 9]", + "total_badness": 2158.1299972 }, { "angles_tet": [ - 14.824, - 146.25 + 15.428, + 143.14 ], "angles_trig": [ 15.314, - 135.03 + 135.42 ], "ne1d": 344, "ne2d": 1118, - "ne3d": 3261, - "quality_histogram": "[0, 0, 0, 0, 1, 2, 14, 23, 47, 67, 152, 225, 319, 424, 475, 458, 420, 389, 183, 62]", - "total_badness": 4647.8518467 + "ne3d": 3217, + "quality_histogram": "[0, 0, 0, 0, 1, 2, 16, 22, 51, 66, 153, 227, 339, 401, 483, 433, 436, 345, 197, 45]", + "total_badness": 4606.4639973 }, { "angles_tet": [ - 21.808, - 142.31 + 21.714, + 141.28 ], "angles_trig": [ - 23.022, - 128.64 + 20.739, + 121.89 ], "ne1d": 480, "ne2d": 2248, - "ne3d": 11618, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 8, 29, 90, 215, 539, 874, 1483, 1964, 2225, 2201, 1553, 437]", - "total_badness": 14695.782197 + "ne3d": 11742, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 7, 25, 112, 245, 521, 980, 1531, 1984, 2284, 2161, 1475, 416]", + "total_badness": 14920.250669 }, { "angles_tet": [ - 22.578, - 141.63 + 22.192, + 145.4 ], "angles_trig": [ 22.146, - 120.55 + 122.13 ], "ne1d": 820, "ne2d": 6206, - "ne3d": 68506, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 6, 49, 164, 556, 1500, 3472, 6624, 10942, 14570, 15222, 11736, 3665]", - "total_badness": 83683.476233 + "ne3d": 68273, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 1, 7, 54, 182, 505, 1504, 3650, 7047, 11075, 14240, 15020, 11269, 3719]", + "total_badness": 83584.302919 } ], "plane.stl": [ @@ -2193,54 +2193,54 @@ ], "ne1d": 886, "ne2d": 2528, - "ne3d": 8259, - "quality_histogram": "[5, 8, 29, 42, 47, 53, 42, 53, 86, 127, 234, 422, 649, 869, 1201, 1333, 1280, 1021, 605, 153]", - "total_badness": 12253.881955 + "ne3d": 8238, + "quality_histogram": "[5, 8, 28, 42, 46, 54, 44, 60, 87, 123, 252, 414, 633, 875, 1235, 1255, 1253, 1065, 604, 155]", + "total_badness": 12230.270782 }, { "angles_tet": [ - 1.1793, + 1.181, 174.03 ], "angles_trig": [ 4.4862, - 152.74 + 148.52 ], "ne1d": 570, "ne2d": 1126, - "ne3d": 1585, - "quality_histogram": "[4, 28, 40, 51, 57, 65, 84, 108, 127, 145, 155, 131, 141, 135, 112, 71, 58, 49, 20, 4]", - "total_badness": 4116.4289328 + "ne3d": 1592, + "quality_histogram": "[4, 27, 41, 49, 62, 73, 91, 112, 117, 142, 162, 129, 138, 140, 114, 71, 61, 42, 16, 1]", + "total_badness": 4125.4080636 }, { "angles_tet": [ 1.1, - 172.17 + 172.16 ], "angles_trig": [ - 3.2068, + 3.728, 163.66 ], "ne1d": 724, "ne2d": 1662, - "ne3d": 3087, - "quality_histogram": "[2, 15, 30, 56, 49, 41, 55, 69, 99, 124, 187, 257, 341, 403, 358, 368, 297, 206, 109, 21]", - "total_badness": 5672.1029809 + "ne3d": 3117, + "quality_histogram": "[2, 12, 30, 54, 56, 40, 51, 70, 98, 128, 217, 263, 320, 383, 400, 362, 301, 205, 108, 17]", + "total_badness": 5701.3001361 }, { "angles_tet": [ 1.2152, - 165.67 + 169.91 ], "angles_trig": [ 1.1526, - 152.31 + 158.98 ], "ne1d": 956, "ne2d": 2742, - "ne3d": 8640, - "quality_histogram": "[3, 10, 38, 48, 47, 55, 52, 55, 83, 138, 177, 324, 506, 776, 1201, 1406, 1497, 1301, 722, 201]", - "total_badness": 12611.933258 + "ne3d": 8642, + "quality_histogram": "[3, 11, 40, 45, 45, 55, 54, 56, 84, 135, 185, 320, 518, 792, 1121, 1438, 1493, 1311, 732, 204]", + "total_badness": 12619.116865 }, { "angles_tet": [ @@ -2253,9 +2253,9 @@ ], "ne1d": 1554, "ne2d": 6276, - "ne3d": 30128, - "quality_histogram": "[2, 8, 13, 8, 26, 47, 54, 67, 97, 161, 296, 601, 1218, 2303, 3660, 5126, 5976, 5561, 3809, 1095]", - "total_badness": 38992.872327 + "ne3d": 30127, + "quality_histogram": "[2, 8, 13, 7, 28, 46, 56, 65, 99, 149, 301, 625, 1226, 2243, 3685, 5125, 5942, 5591, 3816, 1100]", + "total_badness": 38992.330542 }, { "angles_tet": [ @@ -2268,9 +2268,9 @@ ], "ne1d": 2992, "ne2d": 23260, - "ne3d": 281849, - "quality_histogram": "[4, 10, 11, 10, 9, 25, 27, 57, 103, 264, 751, 2013, 5565, 13730, 27855, 44729, 59205, 63981, 48551, 14949]", - "total_badness": 344465.16205 + "ne3d": 282006, + "quality_histogram": "[4, 10, 11, 10, 10, 24, 27, 58, 103, 256, 737, 2052, 5583, 13827, 27949, 44817, 59126, 64139, 48326, 14937]", + "total_badness": 344740.46205 } ], "revolution.geo": [ @@ -2286,8 +2286,8 @@ "ne1d": 320, "ne2d": 3036, "ne3d": 8332, - "quality_histogram": "[0, 0, 0, 0, 0, 1, 6, 14, 93, 181, 405, 666, 868, 1013, 1163, 1292, 1106, 859, 537, 128]", - "total_badness": 11773.570067 + "quality_histogram": "[0, 0, 0, 0, 0, 1, 6, 14, 93, 181, 405, 666, 866, 1015, 1161, 1292, 1107, 860, 537, 128]", + "total_badness": 11773.566772 }, { "angles_tet": [ @@ -2331,8 +2331,8 @@ "ne1d": 320, "ne2d": 3036, "ne3d": 8213, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 3, 49, 124, 291, 550, 780, 982, 1146, 1315, 1218, 939, 652, 163]", - "total_badness": 11293.441654 + "quality_histogram": "[0, 0, 0, 0, 0, 0, 1, 3, 49, 124, 291, 550, 780, 982, 1145, 1316, 1218, 939, 652, 163]", + "total_badness": 11293.441797 }, { "angles_tet": [ @@ -2368,22 +2368,22 @@ "screw.step": [ { "angles_tet": [ - 17.752, - 142.33 + 14.842, + 147.02 ], "angles_trig": [ - 19.029, - 137.96 + 18.845, + 139.34 ], "ne1d": 400, "ne2d": 1390, - "ne3d": 2335, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 2, 55, 79, 134, 196, 259, 266, 307, 287, 261, 222, 141, 104, 22]", - "total_badness": 3618.6672084 + "ne3d": 2327, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 6, 55, 69, 140, 196, 249, 278, 293, 290, 264, 224, 135, 108, 20]", + "total_badness": 3607.9685551 }, { "angles_tet": [ - 19.834, + 22.362, 146.38 ], "angles_trig": [ @@ -2392,24 +2392,24 @@ ], "ne1d": 528, "ne2d": 2724, - "ne3d": 8021, - "quality_histogram": "[0, 0, 0, 0, 0, 1, 3, 10, 28, 70, 148, 286, 485, 757, 1058, 1331, 1509, 1230, 840, 265]", - "total_badness": 10517.478669 + "ne3d": 8020, + "quality_histogram": "[0, 0, 0, 0, 0, 1, 3, 10, 27, 67, 140, 283, 497, 749, 1061, 1336, 1515, 1219, 846, 266]", + "total_badness": 10509.582064 }, { "angles_tet": [ - 20.14, - 143.25 + 20.122, + 143.27 ], "angles_trig": [ - 23.794, + 23.433, 129.76 ], "ne1d": 666, "ne2d": 4792, - "ne3d": 31261, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 2, 6, 21, 103, 237, 651, 1503, 3041, 4906, 6579, 7204, 5289, 1719]", - "total_badness": 38140.005778 + "ne3d": 31239, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 2, 7, 22, 105, 239, 652, 1497, 3032, 4913, 6571, 7208, 5276, 1715]", + "total_badness": 38119.574769 } ], "sculpture.geo": [ @@ -2507,7 +2507,7 @@ "shaft.geo": [ { "angles_tet": [ - 9.0272, + 9.0274, 162.65 ], "angles_trig": [ @@ -2516,9 +2516,9 @@ ], "ne1d": 708, "ne2d": 1702, - "ne3d": 2702, - "quality_histogram": "[0, 0, 1, 3, 11, 21, 27, 39, 97, 138, 279, 414, 309, 306, 236, 278, 234, 193, 92, 24]", - "total_badness": 4366.515194 + "ne3d": 2692, + "quality_histogram": "[0, 0, 1, 3, 9, 13, 32, 40, 85, 144, 282, 385, 330, 298, 240, 280, 242, 198, 85, 25]", + "total_badness": 4328.7489873 }, { "angles_tet": [ @@ -2531,9 +2531,9 @@ ], "ne1d": 410, "ne2d": 592, - "ne3d": 758, - "quality_histogram": "[0, 0, 0, 0, 1, 4, 2, 7, 27, 35, 40, 57, 81, 83, 95, 90, 90, 82, 51, 13]", - "total_badness": 1126.5212658 + "ne3d": 752, + "quality_histogram": "[0, 0, 0, 0, 1, 4, 2, 7, 26, 32, 38, 57, 77, 84, 97, 88, 85, 86, 47, 21]", + "total_badness": 1111.6630355 }, { "angles_tet": [ @@ -2546,9 +2546,9 @@ ], "ne1d": 510, "ne2d": 996, - "ne3d": 1816, - "quality_histogram": "[0, 0, 0, 0, 6, 19, 34, 69, 83, 108, 123, 159, 163, 197, 236, 222, 211, 84, 77, 25]", - "total_badness": 2937.5679156 + "ne3d": 1811, + "quality_histogram": "[0, 0, 0, 0, 6, 19, 35, 68, 84, 104, 123, 161, 163, 197, 234, 222, 211, 84, 76, 24]", + "total_badness": 2930.4129856 }, { "angles_tet": [ @@ -2561,9 +2561,9 @@ ], "ne1d": 708, "ne2d": 1702, - "ne3d": 2677, - "quality_histogram": "[0, 0, 0, 1, 3, 1, 9, 25, 50, 119, 274, 411, 334, 300, 263, 298, 260, 208, 94, 27]", - "total_badness": 4129.758993 + "ne3d": 2666, + "quality_histogram": "[0, 0, 0, 1, 3, 1, 10, 20, 53, 112, 258, 404, 329, 308, 261, 304, 263, 220, 93, 26]", + "total_badness": 4093.2797611 }, { "angles_tet": [ @@ -2576,9 +2576,9 @@ ], "ne1d": 1138, "ne2d": 4170, - "ne3d": 11024, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 3, 31, 70, 182, 338, 557, 913, 1365, 1807, 2087, 1935, 1366, 370]", - "total_badness": 14215.80019 + "ne3d": 11042, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 3, 31, 70, 184, 343, 553, 926, 1360, 1795, 2086, 1951, 1364, 376]", + "total_badness": 14240.174863 }, { "angles_tet": [ @@ -2691,23 +2691,23 @@ "sphereincube.geo": [ { "angles_tet": [ - 10.889, - 166.62 + 12.057, + 166.24 ], "angles_trig": [ - 11.28, - 151.39 + 11.453, + 154.54 ], "ne1d": 46, "ne2d": 202, - "ne3d": 422, - "quality_histogram": "[0, 0, 2, 60, 42, 39, 29, 25, 44, 40, 28, 14, 16, 8, 9, 12, 12, 25, 12, 5]", - "total_badness": 1241.4610254 + "ne3d": 421, + "quality_histogram": "[0, 0, 0, 37, 79, 26, 29, 25, 44, 40, 28, 14, 16, 8, 9, 12, 12, 25, 12, 5]", + "total_badness": 1199.7968459 }, { "angles_tet": [ 8.6025, - 158.11 + 153.04 ], "angles_trig": [ 10.358, @@ -2716,38 +2716,38 @@ "ne1d": 24, "ne2d": 60, "ne3d": 128, - "quality_histogram": "[0, 0, 5, 12, 14, 16, 34, 28, 18, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]", - "total_badness": 451.47087804 + "quality_histogram": "[0, 0, 5, 12, 14, 14, 38, 25, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]", + "total_badness": 448.93317767 }, { "angles_tet": [ - 8.4226, - 166.75 + 8.4046, + 166.8 ], "angles_trig": [ 7.4251, - 143.95 + 148.77 ], "ne1d": 30, "ne2d": 114, "ne3d": 270, - "quality_histogram": "[0, 0, 6, 14, 25, 64, 31, 17, 22, 17, 13, 14, 11, 10, 8, 8, 5, 3, 2, 0]", - "total_badness": 818.97155597 + "quality_histogram": "[0, 0, 6, 15, 25, 54, 39, 18, 22, 17, 13, 14, 11, 10, 8, 8, 5, 3, 2, 0]", + "total_badness": 817.84877369 }, { "angles_tet": [ - 10.889, - 166.62 + 12.057, + 166.24 ], "angles_trig": [ - 11.28, - 151.39 + 11.453, + 154.54 ], "ne1d": 46, "ne2d": 202, - "ne3d": 422, - "quality_histogram": "[0, 0, 2, 60, 42, 39, 29, 25, 44, 40, 28, 14, 16, 8, 9, 12, 12, 25, 12, 5]", - "total_badness": 1241.4610254 + "ne3d": 421, + "quality_histogram": "[0, 0, 0, 37, 79, 26, 29, 25, 44, 40, 28, 14, 16, 8, 9, 12, 12, 25, 12, 5]", + "total_badness": 1199.7968459 }, { "angles_tet": [ @@ -2760,24 +2760,24 @@ ], "ne1d": 74, "ne2d": 412, - "ne3d": 1681, - "quality_histogram": "[0, 0, 0, 0, 0, 5, 5, 17, 18, 30, 48, 94, 133, 194, 249, 242, 240, 204, 159, 43]", - "total_badness": 2334.8383469 + "ne3d": 1693, + "quality_histogram": "[0, 0, 0, 0, 0, 5, 5, 17, 19, 31, 46, 99, 133, 197, 244, 254, 235, 222, 134, 52]", + "total_badness": 2354.342993 }, { "angles_tet": [ - 25.029, - 138.94 + 25.791, + 140.88 ], "angles_trig": [ - 22.069, - 127.5 + 22.85, + 127.71 ], "ne1d": 122, "ne2d": 1076, - "ne3d": 14037, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 3, 24, 84, 179, 418, 822, 1431, 2256, 2852, 2929, 2328, 711]", - "total_badness": 17344.477334 + "ne3d": 14090, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 3, 29, 70, 191, 458, 841, 1451, 2274, 2882, 2906, 2270, 715]", + "total_badness": 17442.506268 } ], "square.in2d": [ @@ -3156,13 +3156,13 @@ ], "angles_trig": [ 14.916, - 130.79 + 132.02 ], "ne1d": 690, "ne2d": 1670, - "ne3d": 5169, - "quality_histogram": "[0, 0, 1, 0, 0, 8, 33, 39, 106, 196, 284, 368, 450, 562, 679, 709, 595, 542, 461, 136]", - "total_badness": 7464.5609796 + "ne3d": 5157, + "quality_histogram": "[0, 0, 1, 0, 1, 7, 31, 35, 106, 197, 275, 372, 450, 550, 687, 710, 598, 542, 457, 138]", + "total_badness": 7437.6066687 }, { "angles_tet": [ @@ -3175,14 +3175,14 @@ ], "ne1d": 390, "ne2d": 522, - "ne3d": 1382, - "quality_histogram": "[0, 0, 3, 8, 13, 39, 84, 122, 123, 153, 169, 133, 139, 114, 88, 88, 55, 37, 12, 2]", - "total_badness": 2771.9730366 + "ne3d": 1371, + "quality_histogram": "[0, 0, 3, 9, 14, 39, 85, 122, 122, 148, 170, 128, 141, 119, 86, 88, 49, 35, 11, 2]", + "total_badness": 2761.1807782 }, { "angles_tet": [ - 8.6612, - 163.89 + 7.8932, + 164.55 ], "angles_trig": [ 14.15, @@ -3191,8 +3191,8 @@ "ne1d": 512, "ne2d": 866, "ne3d": 2373, - "quality_histogram": "[0, 0, 0, 3, 9, 17, 46, 71, 120, 145, 191, 205, 314, 382, 341, 234, 138, 87, 46, 24]", - "total_badness": 3936.100832 + "quality_histogram": "[0, 0, 0, 5, 9, 17, 44, 69, 124, 144, 188, 210, 312, 384, 341, 232, 137, 87, 46, 24]", + "total_badness": 3943.045729 }, { "angles_tet": [ @@ -3201,13 +3201,13 @@ ], "angles_trig": [ 14.916, - 130.79 + 132.02 ], "ne1d": 690, "ne2d": 1670, - "ne3d": 5123, - "quality_histogram": "[0, 0, 1, 0, 0, 3, 22, 38, 106, 190, 271, 350, 435, 551, 670, 694, 624, 558, 468, 142]", - "total_badness": 7336.254691 + "ne3d": 5105, + "quality_histogram": "[0, 0, 1, 0, 0, 3, 22, 36, 106, 193, 265, 350, 426, 543, 665, 708, 610, 566, 470, 141]", + "total_badness": 7305.257781 }, { "angles_tet": [ @@ -3220,41 +3220,41 @@ ], "ne1d": 1050, "ne2d": 3784, - "ne3d": 17727, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 3, 14, 36, 63, 190, 539, 1406, 2089, 2407, 2557, 2702, 2729, 2318, 674]", - "total_badness": 23111.051534 + "ne3d": 17780, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 3, 14, 35, 68, 187, 555, 1415, 2142, 2388, 2642, 2686, 2709, 2266, 670]", + "total_badness": 23216.867073 }, { "angles_tet": [ - 15.321, - 149.42 + 14.338, + 149.32 ], "angles_trig": [ - 20.032, + 19.234, 129.78 ], "ne1d": 1722, "ne2d": 10022, - "ne3d": 85092, - "quality_histogram": "[0, 0, 0, 0, 0, 3, 50, 1423, 715, 400, 647, 1222, 2399, 5628, 9024, 13434, 16387, 16909, 12811, 4040]", - "total_badness": 108920.32258 + "ne3d": 84769, + "quality_histogram": "[0, 0, 0, 0, 0, 4, 52, 1412, 716, 376, 655, 1213, 2420, 5329, 8801, 13265, 16504, 17081, 12828, 4113]", + "total_badness": 108356.07392 } ], "twobricks.geo": [ { "angles_tet": [ - 29.453, - 134.56 + 26.301, + 137.72 ], "angles_trig": [ - 26.574, - 91.538 + 24.205, + 111.42 ], "ne1d": 72, "ne2d": 50, - "ne3d": 36, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 2, 18, 2, 4, 0, 0, 0, 0]", - "total_badness": 55.618194358 + "ne3d": 46, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 5, 4, 14, 7, 6, 3, 1, 0, 0]", + "total_badness": 70.226764001 }, { "angles_tet": [ @@ -3288,18 +3288,18 @@ }, { "angles_tet": [ - 29.453, - 134.56 + 26.301, + 137.72 ], "angles_trig": [ - 26.574, - 91.538 + 24.205, + 111.42 ], "ne1d": 72, "ne2d": 50, - "ne3d": 36, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 2, 18, 2, 4, 0, 0, 0, 0]", - "total_badness": 55.618194358 + "ne3d": 46, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 5, 4, 14, 7, 6, 3, 1, 0, 0]", + "total_badness": 70.226762635 }, { "angles_tet": [ @@ -3319,34 +3319,34 @@ { "angles_tet": [ 28.752, - 130.07 + 132.08 ], "angles_trig": [ - 25.5, + 27.418, 109.19 ], "ne1d": 186, "ne2d": 334, - "ne3d": 596, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 21, 35, 49, 93, 105, 118, 99, 54, 17]", - "total_badness": 770.34262233 + "ne3d": 583, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 19, 35, 62, 94, 100, 106, 99, 57, 7]", + "total_badness": 757.36550186 } ], "twocubes.geo": [ { "angles_tet": [ - 29.453, - 134.56 + 26.301, + 137.72 ], "angles_trig": [ - 26.574, - 91.538 + 24.205, + 111.42 ], "ne1d": 72, "ne2d": 50, - "ne3d": 36, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 2, 18, 2, 4, 0, 0, 0, 0]", - "total_badness": 55.618194358 + "ne3d": 46, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 5, 4, 14, 7, 6, 3, 1, 0, 0]", + "total_badness": 70.226764001 }, { "angles_tet": [ @@ -3380,18 +3380,18 @@ }, { "angles_tet": [ - 29.453, - 134.56 + 26.301, + 137.72 ], "angles_trig": [ - 26.574, - 91.538 + 24.205, + 111.42 ], "ne1d": 72, "ne2d": 50, - "ne3d": 36, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 2, 18, 2, 4, 0, 0, 0, 0]", - "total_badness": 55.618194358 + "ne3d": 46, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 5, 4, 14, 7, 6, 3, 1, 0, 0]", + "total_badness": 70.226762635 }, { "angles_tet": [ @@ -3411,17 +3411,17 @@ { "angles_tet": [ 28.752, - 130.07 + 132.08 ], "angles_trig": [ - 25.5, + 27.418, 109.19 ], "ne1d": 186, "ne2d": 334, - "ne3d": 596, - "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 21, 35, 49, 93, 105, 118, 99, 54, 17]", - "total_badness": 770.34262233 + "ne3d": 583, + "quality_histogram": "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 19, 35, 62, 94, 100, 106, 99, 57, 7]", + "total_badness": 757.36550186 } ], "twocyl.geo": [ diff --git a/tests/pytest/test_pickling.py b/tests/pytest/test_pickling.py index 17f22163..3e15f806 100644 --- a/tests/pytest/test_pickling.py +++ b/tests/pytest/test_pickling.py @@ -87,19 +87,23 @@ def test_pickle_geom2d(): def test_pickle_mesh(): import netgen.csg as csg - geo = csg.CSGeometry() + geo1 = csg.CSGeometry() + geo2 = csg.CSGeometry() brick = csg.OrthoBrick(csg.Pnt(-3,-3,-3), csg.Pnt(3,3,3)) - mesh = geo.GenerateMesh(maxh=0.2) - assert geo == mesh.GetGeometry() - dump = pickle.dumps([geo,mesh]) - geo2, mesh2 = pickle.loads(dump) - assert geo2 == mesh2.GetGeometry() - mesh.Save("msh1.vol.gz") - mesh2.Save("msh2.vol.gz") - import filecmp, os - assert filecmp.cmp("msh1.vol.gz", "msh2.vol.gz") - os.remove("msh1.vol.gz") - os.remove("msh2.vol.gz") + geo2.Add(brick) + + for geo in [geo1, geo2]: + mesh = geo.GenerateMesh(maxh=2) + assert geo == mesh.GetGeometry() + dump = pickle.dumps([geo,mesh]) + geo2, mesh2 = pickle.loads(dump) + assert geo2 == mesh2.GetGeometry() + mesh.Save("msh1.vol.gz") + mesh2.Save("msh2.vol.gz") + import filecmp, os + assert filecmp.cmp("msh1.vol.gz", "msh2.vol.gz") + os.remove("msh1.vol.gz") + os.remove("msh2.vol.gz") if __name__ == "__main__": test_pickle_mesh()