int CheckSurfaceMesh2 (const Mesh & mesh) { int i, j, k; const Point<3> *tri1[3], *tri2[3]; for (i = 1; i <= mesh.GetNOpenElements(); i++) { PrintDot (); for (j = 1; j < i; j++) { for (k = 1; k <= 3; k++) { tri1[k-1] = &mesh.Point (mesh.OpenElement(i).PNum(k)); tri2[k-1] = &mesh.Point (mesh.OpenElement(j).PNum(k)); } if (IntersectTriangleTriangle (&tri1[0], &tri2[0])) { PrintSysError ("Surface elements are intersecting"); (*testout) << "Intersecting: " << endl; for (k = 0; k <= 2; k++) (*testout) << *tri1[k] << " "; (*testout) << endl; for (k = 0; k <= 2; k++) (*testout) << *tri2[k] << " "; (*testout) << endl; } } } return 0; }
int STLLine :: GetRightTrig(int nr) const { if (nr > righttrigs.Size()) { PrintSysError("In STLLine::GetRightTrig!!!"); return 0; } return righttrigs.Get(nr); };
int STLLine :: GetLeftTrig(int nr) const { if (nr > lefttrigs.Size()) { PrintSysError("In STLLine::GetLeftTrig!!!"); return 0; } return lefttrigs.Get(nr); };
int CheckSurfaceMesh (const Mesh & mesh) { PrintMessage (3, "Check Surface mesh"); int nf = mesh.GetNSE(); INDEX_2_HASHTABLE<int> edges(nf+2); int i, j; INDEX_2 i2; int cnt1 = 0, cnt2 = 0; for (i = 1; i <= nf; i++) for (j = 1; j <= 3; j++) { i2.I1() = mesh.SurfaceElement(i).PNumMod(j); i2.I2() = mesh.SurfaceElement(i).PNumMod(j+1); if (edges.Used(i2)) { int hi; hi = edges.Get(i2); if (hi != 1) PrintSysError ("CheckSurfaceMesh, hi = ", hi); edges.Set(i2, 2); cnt2++; } else { Swap (i2.I1(), i2.I2()); edges.Set(i2, 1); cnt1++; } } if (cnt1 != cnt2) { PrintUserError ("Surface mesh not consistent"); // MyBeep(2); // (*mycout) << "cnt1 = " << cnt1 << " cnt2 = " << cnt2 << endl; return 0; } return 1; }
void PopStatus() { if (msgstatus_stack.Size()) { if (msgstatus_stack.Size() > 1) SetStatMsg (*msgstatus_stack.Last()); else SetStatMsg (""); delete msgstatus_stack.Last(); msgstatus_stack.DeleteLast(); threadpercent_stack.DeleteLast(); if(threadpercent_stack.Size() > 0) multithread.percent = threadpercent_stack.Last(); else multithread.percent = 100.; } else { PrintSysError("PopStatus failed"); } }
// extern double teterrpow; MESHING3_RESULT MeshVolume (MeshingParameters & mp, Mesh& mesh3d) { int oldne; int meshed; Array<INDEX_2> connectednodes; if (&mesh3d.LocalHFunction() == NULL) mesh3d.CalcLocalH(mp.grading); mesh3d.Compress(); // mesh3d.PrintMemInfo (cout); if (mp.checkoverlappingboundary) if (mesh3d.CheckOverlappingBoundary()) throw NgException ("Stop meshing since boundary mesh is overlapping"); int nonconsist = 0; for (int k = 1; k <= mesh3d.GetNDomains(); k++) { 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; } } if (nonconsist) { PrintError ("Stop meshing since surface mesh not consistent"); throw NgException ("Stop meshing since surface mesh not consistent"); } double globmaxh = mp.maxh; for (int k = 1; k <= mesh3d.GetNDomains(); k++) { 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)); mesh3d.CalcSurfacesOfNode(); mesh3d.FindOpenElements(k); if (!mesh3d.GetNOpenElements()) continue; 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 (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 = 1; qstep <= 3; qstep++) { // cout << "openquads = " << mesh3d.HasOpenQuads() << endl; if (mesh3d.HasOpenQuads()) { string rulefile = ngdir; const char ** rulep = NULL; switch (qstep) { 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++) 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 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); Array<int, PointIndex::BASE> glob2loc(mesh3d.GetNP()); glob2loc = -1; for (PointIndex pi = mesh3d.Points().Begin(); pi < mesh3d.Points().End(); pi++) 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; MeshQuality3d (mesh3d); return MESHING3_OK; }
/* double stlgh; double GetH(const Point3d& p, double x) { return stlgh;//+0.5)*(x+0.5); } */ STLLine* STLLine :: Mesh(const Array<Point<3> >& ap, Array<Point3d>& mp, double ghi, class Mesh& mesh) const { static int timer1a = NgProfiler::CreateTimer ("mesh stl-line 1a"); static int timer1b = NgProfiler::CreateTimer ("mesh stl-line 1b"); static int timer2 = NgProfiler::CreateTimer ("mesh stl-line 2"); static int timer3 = NgProfiler::CreateTimer ("mesh stl-line 3"); NgProfiler::StartTimer (timer1a); STLLine* line = new STLLine(geometry); //stlgh = ghi; //uebergangsloesung!!!! double len = GetLength(ap); double inthl = 0; //integral of 1/h double dist = 0; double h; int ind; Point3d p; Box<3> bbox; GetBoundingBox (ap, bbox); double diam = bbox.Diam(); double minh = mesh.LocalHFunction().GetMinH (bbox.PMin(), bbox.PMax()); double maxseglen = 0; for (int i = 1; i <= GetNS(); i++) maxseglen = max2 (maxseglen, GetSegLen (ap, i)); int nph = 10+int(maxseglen / minh); //anzahl der integralauswertungen pro segment Array<double> inthi(GetNS()*nph); Array<double> curvelen(GetNS()*nph); NgProfiler::StopTimer (timer1a); NgProfiler::StartTimer (timer1b); for (int i = 1; i <= GetNS(); i++) { //double seglen = GetSegLen(ap,i); for (int j = 1; j <= nph; j++) { p = GetPointInDist(ap,dist,ind); //h = GetH(p,dist/len); h = mesh.GetH(p); dist += GetSegLen(ap,i)/(double)nph; inthl += GetSegLen(ap,i)/nph/(h); inthi.Elem((i-1)*nph+j) = GetSegLen(ap,i)/nph/h; curvelen.Elem((i-1)*nph+j) = GetSegLen(ap,i)/nph; } } int inthlint = int(inthl+1); if ( (inthlint < 3) && (StartP() == EndP())) { inthlint = 3; } if ( (inthlint == 1) && ShouldSplit()) { inthlint = 2; } double fact = inthl/(double)inthlint; dist = 0; int j = 1; p = ap.Get(StartP()); int pn = AddPointIfNotExists(mp, p, 1e-10*diam); int segn = 1; line->AddPoint(pn); line->AddLeftTrig(GetLeftTrig(segn)); line->AddRightTrig(GetRightTrig(segn)); line->AddDist(dist); NgProfiler::StopTimer (timer1b); NgProfiler::StartTimer (timer2); inthl = 0; //restart each meshseg for (int i = 1; i <= inthlint; i++) { while (inthl < 1.000000001 && j <= inthi.Size()) { inthl += inthi.Get(j)/fact; dist += curvelen.Get(j); j++; } //went too far: j--; double tofar = (inthl - 1)/inthi.Get(j); inthl -= tofar*inthi.Get(j); dist -= tofar*curvelen.Get(j)*fact; if (i == inthlint && fabs(dist - len) >= 1E-8) { PrintSysError("meshline failed!!!"); } if (i != inthlint) { p = GetPointInDist(ap,dist,ind); pn = AddPointIfNotExists(mp, p, 1e-10*diam); segn = ind; line->AddPoint(pn); line->AddLeftTrig(GetLeftTrig(segn)); line->AddRightTrig(GetRightTrig(segn)); line->AddDist(dist); } inthl = tofar*inthi.Get(j); dist += tofar*curvelen.Get(j)*fact; j++; } NgProfiler::StopTimer (timer2); NgProfiler::StartTimer (timer3); p = ap.Get(EndP()); pn = AddPointIfNotExists(mp, p, 1e-10*diam); segn = GetNS(); line->AddPoint(pn); line->AddLeftTrig(GetLeftTrig(segn)); line->AddRightTrig(GetRightTrig(segn)); line->AddDist(dist); for (int ii = 1; ii <= line->GetNS(); ii++) { int p1, p2; line->GetSeg(ii,p1,p2); } /* (*testout) << "line, " << ap.Get(StartP()) << "-" << ap.Get(EndP()) << " len = " << Dist (ap.Get(StartP()), ap.Get(EndP())) << endl; */ NgProfiler::StopTimer (timer3); return line; }
void Refinement :: MakeSecondOrder (Mesh & mesh) { int nseg, nse, ne; mesh.ComputeNVertices(); mesh.SetNP(mesh.GetNV()); INDEX_2_HASHTABLE<int> between(mesh.GetNP() + 5); bool thinlayers = 0; for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++) if (mesh[ei].GetType() == PRISM || mesh[ei].GetType() == PRISM12) thinlayers = 1; nseg = mesh.GetNSeg(); for (SegmentIndex si = 0; si < nseg; si++) { Segment & el = mesh.LineSegment(si); INDEX_2 i2 = INDEX_2::Sort (el[0], el[1]); if (between.Used(i2)) el[2] = between.Get(i2); else { Point<3> pb; EdgePointGeomInfo ngi; PointBetween (mesh.Point (el[0]), mesh.Point (el[1]), 0.5, el.surfnr1, el.surfnr2, el.epgeominfo[0], el.epgeominfo[1], pb, ngi); el[2] = mesh.AddPoint (pb, mesh.Point(el[0]).GetLayer(), EDGEPOINT); between.Set (i2, el[2]); } } // refine surface elements nse = mesh.GetNSE(); for (SurfaceElementIndex sei = 0; sei < nse; sei++) { int j; const Element2d & el = mesh.SurfaceElement(sei); int onp(0); Element2d newel; newel.SetIndex (el.GetIndex()); static int betw_trig[3][3] = { { 1, 2, 3 }, { 0, 2, 4 }, { 0, 1, 5 } }; static int betw_quad6[2][3] = { { 0, 1, 4 }, { 3, 2, 5 } }; static int betw_quad8[4][3] = { { 0, 1, 4 }, { 3, 2, 5 }, { 0, 3, 6 }, { 1, 2, 7 } }; int (*betw)[3] = NULL; switch (el.GetType()) { case TRIG: case TRIG6: { betw = betw_trig; newel.SetType (TRIG6); onp = 3; break; } case QUAD: case QUAD6: case QUAD8: { if (thinlayers) { betw = betw_quad6; newel.SetType (QUAD6); } else { betw = betw_quad8; newel.SetType (QUAD8); } onp = 4; break; } default: PrintSysError ("Unhandled element in secondorder:", int(el.GetType())); } for (j = 0; j < onp; j++) newel[j] = el[j]; int nnp = newel.GetNP(); for (j = 0; j < nnp-onp; j++) { int pi1 = newel[betw[j][0]]; int pi2 = newel[betw[j][1]]; INDEX_2 i2 = INDEX_2::Sort (pi1, pi2); if (between.Used(i2)) newel[onp+j] = between.Get(i2); else { Point<3> pb; PointGeomInfo newgi; PointBetween (mesh.Point (pi1), mesh.Point (pi2), 0.5, mesh.GetFaceDescriptor(el.GetIndex ()).SurfNr(), el.GeomInfoPi (betw[j][0]+1), el.GeomInfoPi (betw[j][1]+1), pb, newgi); newel[onp+j] = mesh.AddPoint (pb, mesh.Point(pi1).GetLayer(), SURFACEPOINT); between.Set (i2, newel[onp+j]); } } mesh.SurfaceElement(sei) = newel; } // int i, j; // refine volume elements ne = mesh.GetNE(); for (int i = 1; i <= ne; i++) { const Element & el = mesh.VolumeElement(i); int onp = 0; Element newel; newel.SetIndex (el.GetIndex()); static int betw_tet[6][3] = { { 0, 1, 4 }, { 0, 2, 5 }, { 0, 3, 6 }, { 1, 2, 7 }, { 1, 3, 8 }, { 2, 3, 9 } }; static int betw_prism[6][3] = { { 0, 2, 6 }, { 0, 1, 7 }, { 1, 2, 8 }, { 3, 5, 9 }, { 3, 4, 10 }, { 4, 5, 11 }, }; int (*betw)[3] = NULL; switch (el.GetType()) { case TET: case TET10: { betw = betw_tet; newel.SetType (TET10); onp = 4; break; } case PRISM: case PRISM12: { betw = betw_prism; newel.SetType (PRISM12); onp = 6; break; } default: PrintSysError ("MakeSecondOrder, illegal vol type ", el.GetType()); } for (int j = 1; j <= onp; j++) newel.PNum(j) = el.PNum(j); int nnp = newel.GetNP(); for (int j = 0; j < nnp-onp; j++) { INDEX_2 i2(newel[betw[j][0]], newel[betw[j][1]]); i2.Sort(); if (between.Used(i2)) newel.PNum(onp+1+j) = between.Get(i2); else { newel.PNum(onp+1+j) = mesh.AddPoint (Center (mesh.Point(i2.I1()), mesh.Point(i2.I2())), mesh.Point(i2.I1()).GetLayer(), INNERPOINT); between.Set (i2, newel.PNum(onp+1+j)); } } mesh.VolumeElement (i) = newel; } // makes problems after linear mesh refinement, since // 2nd order identifications are not removed // update identification tables for (int i = 1; i <= mesh.GetIdentifications().GetMaxNr(); i++) { Array<int,PointIndex::BASE> identmap; mesh.GetIdentifications().GetMap (i, identmap); for (INDEX_2_HASHTABLE<int>::Iterator it = between.Begin(); it != between.End(); it++) { INDEX_2 i2; int newpi; between.GetData (it, i2, newpi); INDEX_2 oi2(identmap.Get(i2.I1()), identmap.Get(i2.I2())); oi2.Sort(); if (between.Used (oi2)) { int onewpi = between.Get(oi2); mesh.GetIdentifications().Add (newpi, onewpi, i); } } /* for (int j = 1; j <= between.GetNBags(); j++) for (int k = 1; k <= between.GetBagSize(j); k++) { INDEX_2 i2; int newpi; between.GetData (j, k, i2, newpi); INDEX_2 oi2(identmap.Get(i2.I1()), identmap.Get(i2.I2())); oi2.Sort(); if (between.Used (oi2)) { int onewpi = between.Get(oi2); mesh.GetIdentifications().Add (newpi, onewpi, i); } } */ } // mesh.mglevels++; int oldsize = mesh.mlbetweennodes.Size(); mesh.mlbetweennodes.SetSize(mesh.GetNP()); for (int i = oldsize; i < mesh.GetNP(); i++) mesh.mlbetweennodes[i] = INDEX_2(0,0); /* for (i = 1; i <= between.GetNBags(); i++) for (j = 1; j <= between.GetBagSize(i); j++) { INDEX_2 oldp; int newp; between.GetData (i, j, oldp, newp); mesh.mlbetweennodes.Elem(newp) = oldp; } */ for (INDEX_2_HASHTABLE<int>::Iterator it = between.Begin(); it != between.End(); it++) { mesh.mlbetweennodes[between.GetData (it)] = between.GetHash(it); } mesh.ComputeNVertices(); mesh.RebuildSurfaceElementLists(); // ValidateSecondOrder (mesh); }