Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/meshfunc.cpp
3206 views
#include <mystdlib.h>1#include "meshing.hpp"23namespace netgen4{5extern const char * tetrules[];6// extern const char * tetrules2[];7extern const char * prismrules2[];8extern const char * pyramidrules[];9extern const char * pyramidrules2[];101112extern double teterrpow;13MESHING3_RESULT MeshVolume (MeshingParameters & mp, Mesh& mesh3d)14{15int i, oldne;16PointIndex pi;1718int meshed;19int cntsteps;202122ARRAY<INDEX_2> connectednodes;2324mesh3d.Compress();2526// mesh3d.PrintMemInfo (cout);2728if (mp.checkoverlappingboundary)29if (mesh3d.CheckOverlappingBoundary())30throw NgException ("Stop meshing since boundary mesh is overlapping");3132int nonconsist = 0;33for (int k = 1; k <= mesh3d.GetNDomains(); k++)34{35PrintMessage (3, "Check subdomain ", k, " / ", mesh3d.GetNDomains());3637mesh3d.FindOpenElements(k);3839/*40bool res = mesh3d.CheckOverlappingBoundary();41if (res)42{43PrintError ("Surface is overlapping !!");44nonconsist = 1;45}46*/4748bool res = (mesh3d.CheckConsistentBoundary() != 0);49if (res)50{51PrintError ("Surface mesh not consistent");52nonconsist = 1;53}54}5556if (nonconsist)57{58PrintError ("Stop meshing since surface mesh not consistent");59throw NgException ("Stop meshing since surface mesh not consistent");60}6162double globmaxh = mp.maxh;6364for (int k = 1; k <= mesh3d.GetNDomains(); k++)65{66if (multithread.terminate)67break;6869PrintMessage (2, "");70PrintMessage (1, "Meshing subdomain ", k, " of ", mesh3d.GetNDomains());71(*testout) << "Meshing subdomain " << k << endl;7273mp.maxh = min2 (globmaxh, mesh3d.MaxHDomain(k));7475mesh3d.CalcSurfacesOfNode();76mesh3d.FindOpenElements(k);7778if (!mesh3d.GetNOpenElements())79continue;80818283Box<3> domain_bbox( Box<3>::EMPTY_BOX );84/*85Point<3> (1e10, 1e10, 1e10),86Point<3> (-1e10, -1e10, -1e10));87*/8889for (SurfaceElementIndex sei = 0; sei < mesh3d.GetNSE(); sei++)90{91const Element2d & el = mesh3d[sei];92if (el.IsDeleted() ) continue;9394if (mesh3d.GetFaceDescriptor(el.GetIndex()).DomainIn() == k ||95mesh3d.GetFaceDescriptor(el.GetIndex()).DomainOut() == k)9697for (int j = 0; j < el.GetNP(); j++)98domain_bbox.Add (mesh3d[el[j]]);99}100domain_bbox.Increase (0.01 * domain_bbox.Diam());101102103for (int qstep = 1; qstep <= 3; qstep++)104{105if (mesh3d.HasOpenQuads())106{107string rulefile = ngdir;108109const char ** rulep = NULL;110switch (qstep)111{112case 1:113rulefile += "/rules/prisms2.rls";114rulep = prismrules2;115break;116case 2: // connect pyramid to triangle117rulefile += "/rules/pyramids2.rls";118rulep = pyramidrules2;119break;120case 3: // connect to vis-a-vis point121rulefile += "/rules/pyramids.rls";122rulep = pyramidrules;123break;124}125126// Meshing3 meshing(rulefile);127Meshing3 meshing(rulep);128129MeshingParameters mpquad = mp;130131mpquad.giveuptol = 15;132mpquad.baseelnp = 4;133mpquad.starshapeclass = 1000;134mpquad.check_impossible = qstep == 1; // for prisms only (air domain in trafo)135136137for (pi = PointIndex::BASE;138pi < mesh3d.GetNP()+PointIndex::BASE; pi++)139meshing.AddPoint (mesh3d[pi], pi);140141mesh3d.GetIdentifications().GetPairs (0, connectednodes);142for (i = 1; i <= connectednodes.Size(); i++)143meshing.AddConnectedPair (connectednodes.Get(i));144145for (i = 1; i <= mesh3d.GetNOpenElements(); i++)146{147Element2d hel = mesh3d.OpenElement(i);148meshing.AddBoundaryElement (hel);149}150151oldne = mesh3d.GetNE();152153meshing.GenerateMesh (mesh3d, mpquad);154155for (i = oldne + 1; i <= mesh3d.GetNE(); i++)156mesh3d.VolumeElement(i).SetIndex (k);157158(*testout)159<< "mesh has " << mesh3d.GetNE() << " prism/pyramid�elements" << endl;160161mesh3d.FindOpenElements(k);162}163}164165166if (mesh3d.HasOpenQuads())167{168PrintSysError ("mesh has still open quads");169throw NgException ("Stop meshing since too many attempts");170// return MESHING3_GIVEUP;171}172173174if (mp.delaunay && mesh3d.GetNOpenElements())175{176Meshing3 meshing((const char**)NULL);177178mesh3d.FindOpenElements(k);179180181for (pi = PointIndex::BASE;182pi < mesh3d.GetNP()+PointIndex::BASE; pi++)183meshing.AddPoint (mesh3d[pi], pi);184185186for (i = 1; i <= mesh3d.GetNOpenElements(); i++)187meshing.AddBoundaryElement (mesh3d.OpenElement(i));188189oldne = mesh3d.GetNE();190191meshing.Delaunay (mesh3d, k, mp);192193for (i = oldne + 1; i <= mesh3d.GetNE(); i++)194mesh3d.VolumeElement(i).SetIndex (k);195196PrintMessage (3, mesh3d.GetNP(), " points, ",197mesh3d.GetNE(), " elements");198}199200201cntsteps = 0;202if (mesh3d.GetNOpenElements())203do204{205if (multithread.terminate)206break;207208mesh3d.FindOpenElements(k);209PrintMessage (5, mesh3d.GetNOpenElements(), " open faces");210cntsteps++;211212if (cntsteps > mp.maxoutersteps)213throw NgException ("Stop meshing since too many attempts");214215string rulefile = ngdir + "/tetra.rls";216PrintMessage (1, "start tetmeshing");217218// Meshing3 meshing(rulefile);219Meshing3 meshing(tetrules);220221ARRAY<int, PointIndex::BASE> glob2loc(mesh3d.GetNP());222glob2loc = -1;223224for (pi = PointIndex::BASE;225pi < mesh3d.GetNP()+PointIndex::BASE; pi++)226227if (domain_bbox.IsIn (mesh3d[pi]))228glob2loc[pi] =229meshing.AddPoint (mesh3d[pi], pi);230231for (i = 1; i <= mesh3d.GetNOpenElements(); i++)232{233Element2d hel = mesh3d.OpenElement(i);234for (int j = 0; j < hel.GetNP(); j++)235hel[j] = glob2loc[hel[j]];236meshing.AddBoundaryElement (hel);237// meshing.AddBoundaryElement (mesh3d.OpenElement(i));238}239240oldne = mesh3d.GetNE();241242mp.giveuptol = 15 + 10 * cntsteps;243mp.sloppy = 5;244meshing.GenerateMesh (mesh3d, mp);245246for (ElementIndex ei = oldne; ei < mesh3d.GetNE(); ei++)247mesh3d[ei].SetIndex (k);248249250mesh3d.CalcSurfacesOfNode();251mesh3d.FindOpenElements(k);252253teterrpow = 2;254if (mesh3d.GetNOpenElements() != 0)255{256meshed = 0;257PrintMessage (5, mesh3d.GetNOpenElements(), " open faces found");258259// mesh3d.Save ("tmp.vol");260261262MeshOptimize3d optmesh;263264const char * optstr = "mcmstmcmstmcmstmcm";265size_t j;266for (j = 1; j <= strlen(optstr); j++)267{268mesh3d.CalcSurfacesOfNode();269mesh3d.FreeOpenElementsEnvironment(2);270mesh3d.CalcSurfacesOfNode();271272switch (optstr[j-1])273{274case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break;275case 'd': optmesh.SplitImprove(mesh3d, OPT_REST); break;276case 's': optmesh.SwapImprove(mesh3d, OPT_REST); break;277case 't': optmesh.SwapImprove2(mesh3d, OPT_REST); break;278case 'm': mesh3d.ImproveMesh(OPT_REST); break;279}280281}282283mesh3d.FindOpenElements(k);284PrintMessage (3, "Call remove problem");285RemoveProblem (mesh3d, k);286mesh3d.FindOpenElements(k);287}288else289{290meshed = 1;291PrintMessage (1, "Success !");292}293}294while (!meshed);295296PrintMessage (1, mesh3d.GetNP(), " points, ",297mesh3d.GetNE(), " elements");298}299300mp.maxh = globmaxh;301302MeshQuality3d (mesh3d);303304return MESHING3_OK;305}306307308309310/*311312313MESHING3_RESULT MeshVolumeOld (MeshingParameters & mp, Mesh& mesh3d)314{315int i, k, oldne;316317318int meshed;319int cntsteps;320321322PlotStatistics3d * pstat;323if (globflags.GetNumFlag("silentflag", 1) <= 2)324pstat = new XPlotStatistics3d;325else326pstat = new TerminalPlotStatistics3d;327328cntsteps = 0;329do330{331cntsteps++;332if (cntsteps > mp.maxoutersteps)333{334return MESHING3_OUTERSTEPSEXCEEDED;335}336337338int noldp = mesh3d.GetNP();339340341if ( (cntsteps == 1) && globflags.GetDefineFlag ("delaunay"))342{343cntsteps ++;344345mesh3d.CalcSurfacesOfNode();346347348for (k = 1; k <= mesh3d.GetNDomains(); k++)349{350Meshing3 meshing(NULL, pstat);351352mesh3d.FindOpenElements(k);353354for (i = 1; i <= noldp; i++)355meshing.AddPoint (mesh3d.Point(i), i);356357for (i = 1; i <= mesh3d.GetNOpenElements(); i++)358{359if (mesh3d.OpenElement(i).GetIndex() == k)360meshing.AddBoundaryElement (mesh3d.OpenElement(i));361}362363oldne = mesh3d.GetNE();364if (globflags.GetDefineFlag ("blockfill"))365{366if (!globflags.GetDefineFlag ("localh"))367meshing.BlockFill368(mesh3d, mp.h * globflags.GetNumFlag ("relblockfillh", 1));369else370meshing.BlockFillLocalH (mesh3d);371}372373MeshingParameters mpd;374meshing.Delaunay (mesh3d, mpd);375376for (i = oldne + 1; i <= mesh3d.GetNE(); i++)377mesh3d.VolumeElement(i).SetIndex (k);378}379}380381noldp = mesh3d.GetNP();382383mesh3d.CalcSurfacesOfNode();384mesh3d.FindOpenElements();385for (k = 1; k <= mesh3d.GetNDomains(); k++)386{387Meshing3 meshing(globflags.GetStringFlag ("rules3d", NULL), pstat);388389Point3d pmin, pmax;390mesh3d.GetBox (pmin, pmax, k);391392rot.SetCenter (Center (pmin, pmax));393394for (i = 1; i <= noldp; i++)395meshing.AddPoint (mesh3d.Point(i), i);396397for (i = 1; i <= mesh3d.GetNOpenElements(); i++)398{399if (mesh3d.OpenElement(i).GetIndex() == k)400meshing.AddBoundaryElement (mesh3d.OpenElement(i));401}402403oldne = mesh3d.GetNE();404405406if ( (cntsteps == 1) && globflags.GetDefineFlag ("blockfill"))407{408if (!globflags.GetDefineFlag ("localh"))409{410meshing.BlockFill411(mesh3d,412mp.h * globflags.GetNumFlag ("relblockfillh", 1));413}414else415{416meshing.BlockFillLocalH (mesh3d);417}418}419420421mp.giveuptol = int(globflags.GetNumFlag ("giveuptol", 15));422423meshing.GenerateMesh (mesh3d, mp);424425for (i = oldne + 1; i <= mesh3d.GetNE(); i++)426mesh3d.VolumeElement(i).SetIndex (k);427}428429430431mesh3d.CalcSurfacesOfNode();432mesh3d.FindOpenElements();433434teterrpow = 2;435if (mesh3d.GetNOpenElements() != 0)436{437meshed = 0;438(*mycout) << "Open elements found, old" << endl;439const char * optstr = "mcmcmcmcm";440int j;441for (j = 1; j <= strlen(optstr); j++)442switch (optstr[j-1])443{444case 'c': mesh3d.CombineImprove(); break;445case 'd': mesh3d.SplitImprove(); break;446case 's': mesh3d.SwapImprove(); break;447case 'm': mesh3d.ImproveMesh(2); break;448}449450(*mycout) << "Call remove" << endl;451RemoveProblem (mesh3d);452(*mycout) << "Problem removed" << endl;453}454else455meshed = 1;456}457while (!meshed);458459MeshQuality3d (mesh3d);460461return MESHING3_OK;462}463464*/465466467468469/*470MESHING3_RESULT MeshMixedVolume(MeshingParameters & mp, Mesh& mesh3d)471{472int i, j;473MESHING3_RESULT res;474Point3d pmin, pmax;475476mp.giveuptol = 10;477mp.baseelnp = 4;478mp.starshapeclass = 100;479480// TerminalPlotStatistics3d pstat;481482Meshing3 meshing1("pyramids.rls");483for (i = 1; i <= mesh3d.GetNP(); i++)484meshing1.AddPoint (mesh3d.Point(i), i);485486mesh3d.FindOpenElements();487for (i = 1; i <= mesh3d.GetNOpenElements(); i++)488if (mesh3d.OpenElement(i).GetIndex() == 1)489meshing1.AddBoundaryElement (mesh3d.OpenElement(i));490491res = meshing1.GenerateMesh (mesh3d, mp);492493mesh3d.GetBox (pmin, pmax);494PrintMessage (1, "Mesh pyramids, res = ", res);495if (res)496exit (1);497498499for (i = 1; i <= mesh3d.GetNE(); i++)500mesh3d.VolumeElement(i).SetIndex (1);501502// do delaunay503504mp.baseelnp = 0;505mp.starshapeclass = 5;506507Meshing3 meshing2(NULL);508for (i = 1; i <= mesh3d.GetNP(); i++)509meshing2.AddPoint (mesh3d.Point(i), i);510511mesh3d.FindOpenElements();512for (i = 1; i <= mesh3d.GetNOpenElements(); i++)513if (mesh3d.OpenElement(i).GetIndex() == 1)514meshing2.AddBoundaryElement (mesh3d.OpenElement(i));515516MeshingParameters mpd;517meshing2.Delaunay (mesh3d, mpd);518519for (i = 1; i <= mesh3d.GetNE(); i++)520mesh3d.VolumeElement(i).SetIndex (1);521522523mp.baseelnp = 0;524mp.giveuptol = 10;525526for (int trials = 1; trials <= 50; trials++)527{528if (multithread.terminate)529return MESHING3_TERMINATE;530531Meshing3 meshing3("tetra.rls");532for (i = 1; i <= mesh3d.GetNP(); i++)533meshing3.AddPoint (mesh3d.Point(i), i);534535mesh3d.FindOpenElements();536for (i = 1; i <= mesh3d.GetNOpenElements(); i++)537if (mesh3d.OpenElement(i).GetIndex() == 1)538meshing3.AddBoundaryElement (mesh3d.OpenElement(i));539540if (trials > 1)541CheckSurfaceMesh2 (mesh3d);542res = meshing3.GenerateMesh (mesh3d, mp);543544for (i = 1; i <= mesh3d.GetNE(); i++)545mesh3d.VolumeElement(i).SetIndex (1);546547if (res == 0) break;548549550551for (i = 1; i <= mesh3d.GetNE(); i++)552{553const Element & el = mesh3d.VolumeElement(i);554if (el.GetNP() != 4)555{556for (j = 1; j <= el.GetNP(); j++)557mesh3d.AddLockedPoint (el.PNum(j));558}559}560561mesh3d.CalcSurfacesOfNode();562mesh3d.FindOpenElements();563564MeshOptimize3d optmesh;565566teterrpow = 2;567const char * optstr = "mcmcmcmcm";568for (j = 1; j <= strlen(optstr); j++)569switch (optstr[j-1])570{571case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break;572case 'd': optmesh.SplitImprove(mesh3d); break;573case 's': optmesh.SwapImprove(mesh3d); break;574case 'm': mesh3d.ImproveMesh(); break;575}576577RemoveProblem (mesh3d);578}579580581PrintMessage (1, "Meshing tets, res = ", res);582if (res)583{584mesh3d.FindOpenElements();585PrintSysError (1, "Open elemetns: ", mesh3d.GetNOpenElements());586exit (1);587}588589590591for (i = 1; i <= mesh3d.GetNE(); i++)592{593const Element & el = mesh3d.VolumeElement(i);594if (el.GetNP() != 4)595{596for (j = 1; j <= el.GetNP(); j++)597mesh3d.AddLockedPoint (el.PNum(j));598}599}600601mesh3d.CalcSurfacesOfNode();602mesh3d.FindOpenElements();603604MeshOptimize3d optmesh;605606teterrpow = 2;607const char * optstr = "mcmcmcmcm";608for (j = 1; j <= strlen(optstr); j++)609switch (optstr[j-1])610{611case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break;612case 'd': optmesh.SplitImprove(mesh3d); break;613case 's': optmesh.SwapImprove(mesh3d); break;614case 'm': mesh3d.ImproveMesh(); break;615}616617618return MESHING3_OK;619}620*/621622623624625626627MESHING3_RESULT OptimizeVolume (MeshingParameters & mp,628Mesh & mesh3d)629// const CSGeometry * geometry)630{631int i;632633PrintMessage (1, "Volume Optimization");634635/*636if (!mesh3d.PureTetMesh())637return MESHING3_OK;638*/639640// (*mycout) << "optstring = " << mp.optimize3d << endl;641/*642const char * optstr = globflags.GetStringFlag ("optimize3d", "cmh");643int optsteps = int (globflags.GetNumFlag ("optsteps3d", 2));644*/645646mesh3d.CalcSurfacesOfNode();647for (i = 1; i <= mp.optsteps3d; i++)648{649if (multithread.terminate)650break;651652MeshOptimize3d optmesh;653654teterrpow = mp.opterrpow;655for (size_t j = 1; j <= strlen(mp.optimize3d); j++)656{657if (multithread.terminate)658break;659660switch (mp.optimize3d[j-1])661{662case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break;663case 'd': optmesh.SplitImprove(mesh3d); break;664case 's': optmesh.SwapImprove(mesh3d); break;665// case 'u': optmesh.SwapImproveSurface(mesh3d); break;666case 't': optmesh.SwapImprove2(mesh3d); break;667#ifdef SOLIDGEOM668case 'm': mesh3d.ImproveMesh(*geometry); break;669case 'M': mesh3d.ImproveMesh(*geometry); break;670#else671case 'm': mesh3d.ImproveMesh(); break;672case 'M': mesh3d.ImproveMesh(); break;673#endif674case 'j': mesh3d.ImproveMeshJacobian(); break;675}676}677mesh3d.mglevels = 1;678MeshQuality3d (mesh3d);679}680681return MESHING3_OK;682}683684685686687void RemoveIllegalElements (Mesh & mesh3d)688{689int it = 10;690int nillegal, oldn;691692PrintMessage (1, "Remove Illegal Elements");693// return, if non-pure tet-mesh694/*695if (!mesh3d.PureTetMesh())696return;697*/698mesh3d.CalcSurfacesOfNode();699700nillegal = mesh3d.MarkIllegalElements();701702MeshOptimize3d optmesh;703while (nillegal && (it--) > 0)704{705if (multithread.terminate)706break;707708PrintMessage (5, nillegal, " illegal tets");709optmesh.SplitImprove (mesh3d, OPT_LEGAL);710711mesh3d.MarkIllegalElements(); // test712optmesh.SwapImprove (mesh3d, OPT_LEGAL);713mesh3d.MarkIllegalElements(); // test714optmesh.SwapImprove2 (mesh3d, OPT_LEGAL);715716oldn = nillegal;717nillegal = mesh3d.MarkIllegalElements();718719if (oldn != nillegal)720it = 10;721}722PrintMessage (5, nillegal, " illegal tets");723}724}725726727