2010-03-23 17:52:07 +05:00
|
|
|
#include <mystdlib.h>
|
|
|
|
#include "meshing.hpp"
|
|
|
|
|
|
|
|
namespace netgen
|
|
|
|
{
|
|
|
|
|
2013-02-06 18:55:20 +06:00
|
|
|
DLL_HEADER GeometryRegisterArray geometryregister;
|
2019-07-09 13:39:16 +05:00
|
|
|
//DLL_HEADER NgArray<GeometryRegister*> geometryregister;
|
2011-01-11 01:18:01 +05:00
|
|
|
|
|
|
|
GeometryRegister :: ~GeometryRegister()
|
|
|
|
{ ; }
|
|
|
|
|
2019-10-24 16:17:00 +05:00
|
|
|
void NetgenGeometry :: Analyse(Mesh& mesh,
|
2019-10-28 18:41:31 +05:00
|
|
|
const MeshingParameters& mparam) const
|
2019-10-24 16:17:00 +05:00
|
|
|
{
|
|
|
|
static Timer t1("SetLocalMeshsize"); RegionTimer regt(t1);
|
|
|
|
mesh.SetGlobalH(mparam.maxh);
|
|
|
|
mesh.SetMinimalH(mparam.minh);
|
|
|
|
|
|
|
|
mesh.SetLocalH(bounding_box.PMin(), bounding_box.PMax(),
|
|
|
|
mparam.grading);
|
|
|
|
|
|
|
|
if(mparam.uselocalh)
|
2019-10-24 20:34:53 +05:00
|
|
|
RestrictLocalMeshsize(mesh, mparam);
|
2019-10-24 16:17:00 +05:00
|
|
|
mesh.LoadLocalMeshSize(mparam.meshsizefilename);
|
|
|
|
}
|
|
|
|
|
2019-10-28 18:41:31 +05:00
|
|
|
void NetgenGeometry :: FindEdges(Mesh& mesh,
|
|
|
|
const MeshingParameters& mparam) const
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void NetgenGeometry :: MeshSurface(Mesh& mesh,
|
|
|
|
const MeshingParameters& mparam) const
|
|
|
|
{
|
|
|
|
static Timer t1("Surface Meshing"); RegionTimer regt(t1);
|
|
|
|
|
|
|
|
Array<int, PointIndex> glob2loc(mesh.GetNP());
|
|
|
|
for(auto k : Range(faces))
|
|
|
|
{
|
|
|
|
const auto& face = *faces[k];
|
|
|
|
auto bb = face.GetBoundingBox();
|
|
|
|
bb.Increase(bb.Diam()/10);
|
|
|
|
Meshing2 meshing(*this, mparam, bb);
|
|
|
|
glob2loc = 0;
|
|
|
|
int cntp = 0;
|
|
|
|
|
|
|
|
for(auto& seg : mesh.LineSegments())
|
|
|
|
{
|
|
|
|
if(seg.si == k+1)
|
|
|
|
{
|
|
|
|
for(auto j : Range(2))
|
|
|
|
{
|
|
|
|
auto pi = seg[j];
|
|
|
|
if(glob2loc[pi] == 0)
|
|
|
|
{
|
|
|
|
meshing.AddPoint(mesh[pi], pi);
|
|
|
|
cntp++;
|
|
|
|
glob2loc[pi] = cntp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(auto & seg : mesh.LineSegments())
|
|
|
|
{
|
|
|
|
if(seg.si == k+1)
|
|
|
|
{
|
|
|
|
PointGeomInfo gi0, gi1;
|
|
|
|
gi0.trignum = gi1.trignum = k+1;
|
|
|
|
gi0.u = seg.epgeominfo[0].u;
|
|
|
|
gi0.v = seg.epgeominfo[0].v;
|
|
|
|
gi1.u = seg.epgeominfo[1].u;
|
|
|
|
gi1.v = seg.epgeominfo[1].v;
|
|
|
|
meshing.AddBoundaryElement(glob2loc[seg[0]],
|
|
|
|
glob2loc[seg[1]],
|
|
|
|
gi0, gi1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO Set max area 2* area of face
|
|
|
|
|
|
|
|
auto noldsurfels = mesh.GetNSE();
|
|
|
|
|
|
|
|
|
|
|
|
static Timer t("GenerateMesh"); RegionTimer reg(t);
|
|
|
|
MESHING2_RESULT res = meshing.GenerateMesh(mesh, mparam, mparam.maxh, k+1);
|
|
|
|
|
|
|
|
for(auto i : Range(noldsurfels, mesh.GetNSE()))
|
|
|
|
{
|
|
|
|
mesh.SurfaceElements()[i].SetIndex(k+1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void NetgenGeometry :: OptimizeSurface(Mesh& mesh, const MeshingParameters& mparam) const
|
2019-10-02 21:14:38 +05:00
|
|
|
{
|
|
|
|
const auto savetask = multithread.task;
|
|
|
|
multithread.task = "Optimizing surface";
|
|
|
|
|
|
|
|
static Timer timer_opt2d("Optimization 2D");
|
|
|
|
RegionTimer reg(timer_opt2d);
|
2019-10-02 23:29:18 +05:00
|
|
|
auto meshopt = MeshOptimize2d(mesh);
|
2019-10-02 21:14:38 +05:00
|
|
|
for(auto i : Range(mparam.optsteps2d))
|
|
|
|
{
|
|
|
|
PrintMessage(2, "Optimization step ", i);
|
|
|
|
for(auto optstep : mparam.optimize2d)
|
|
|
|
{
|
|
|
|
switch(optstep)
|
|
|
|
{
|
|
|
|
case 's':
|
2019-10-02 23:29:18 +05:00
|
|
|
meshopt.EdgeSwapping(0);
|
2019-10-02 21:14:38 +05:00
|
|
|
break;
|
|
|
|
case 'S':
|
2019-10-02 23:29:18 +05:00
|
|
|
meshopt.EdgeSwapping(1);
|
2019-10-02 21:14:38 +05:00
|
|
|
break;
|
2019-10-03 15:09:13 +05:00
|
|
|
case 'm':
|
2019-10-02 23:29:18 +05:00
|
|
|
meshopt.ImproveMesh(mparam);
|
2019-10-02 21:14:38 +05:00
|
|
|
break;
|
2019-10-03 15:09:13 +05:00
|
|
|
case 'c':
|
2019-10-02 23:29:18 +05:00
|
|
|
meshopt.CombineImprove();
|
2019-10-02 21:14:38 +05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mesh.CalcSurfacesOfNode();
|
|
|
|
mesh.Compress();
|
|
|
|
multithread.task = savetask;
|
|
|
|
}
|
2018-05-12 12:16:02 +05:00
|
|
|
|
|
|
|
shared_ptr<NetgenGeometry> GeometryRegisterArray :: LoadFromMeshFile (istream & ist) const
|
|
|
|
{
|
|
|
|
for (int i = 0; i < Size(); i++)
|
|
|
|
{
|
|
|
|
NetgenGeometry * hgeom = (*this)[i]->LoadFromMeshFile (ist);
|
|
|
|
if (hgeom)
|
|
|
|
return shared_ptr<NetgenGeometry>(hgeom);
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
2011-01-11 01:18:01 +05:00
|
|
|
|
|
|
|
|
|
|
|
|
2010-03-23 17:52:07 +05:00
|
|
|
|
2016-12-05 17:50:21 +05:00
|
|
|
int NetgenGeometry :: GenerateMesh (shared_ptr<Mesh> & mesh, MeshingParameters & mparam)
|
2010-03-23 17:52:07 +05:00
|
|
|
{
|
2019-10-02 20:20:13 +05:00
|
|
|
multithread.percent = 0;
|
2010-03-23 17:52:07 +05:00
|
|
|
|
2019-10-02 20:20:13 +05:00
|
|
|
if(mparam.perfstepsstart <= MESHCONST_ANALYSE)
|
2010-03-23 17:52:07 +05:00
|
|
|
{
|
2019-10-02 20:20:13 +05:00
|
|
|
if(!mesh)
|
|
|
|
mesh = make_shared<Mesh>();
|
|
|
|
mesh->geomtype = GetGeomType();
|
|
|
|
Analyse(*mesh, mparam);
|
|
|
|
}
|
2010-03-23 17:52:07 +05:00
|
|
|
|
2019-10-02 20:20:13 +05:00
|
|
|
if(multithread.terminate || mparam.perfstepsend <= MESHCONST_ANALYSE)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if(mparam.perfstepsstart <= MESHCONST_MESHEDGES)
|
|
|
|
FindEdges(*mesh, mparam);
|
|
|
|
|
|
|
|
if(multithread.terminate || mparam.perfstepsend <= MESHCONST_MESHEDGES)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (mparam.perfstepsstart <= MESHCONST_MESHSURFACE)
|
|
|
|
{
|
|
|
|
MeshSurface(*mesh, mparam);
|
|
|
|
mesh->CalcSurfacesOfNode();
|
2010-03-23 17:52:07 +05:00
|
|
|
}
|
2019-10-03 15:09:13 +05:00
|
|
|
|
2019-10-02 20:20:13 +05:00
|
|
|
if (multithread.terminate || mparam.perfstepsend <= MESHCONST_MESHSURFACE)
|
|
|
|
return 0;
|
2019-10-03 15:09:13 +05:00
|
|
|
|
2019-10-02 20:20:13 +05:00
|
|
|
if (mparam.perfstepsstart <= MESHCONST_OPTSURFACE)
|
|
|
|
OptimizeSurface(*mesh, mparam);
|
|
|
|
|
|
|
|
if (multithread.terminate || mparam.perfstepsend <= MESHCONST_OPTSURFACE)
|
|
|
|
return 0;
|
2010-03-23 17:52:07 +05:00
|
|
|
|
2019-10-03 15:09:13 +05:00
|
|
|
|
2019-10-02 20:20:13 +05:00
|
|
|
if(mparam.perfstepsstart <= MESHCONST_MESHVOLUME)
|
|
|
|
{
|
|
|
|
multithread.task = "Volume meshing";
|
|
|
|
|
|
|
|
MESHING3_RESULT res = MeshVolume (mparam, *mesh);
|
|
|
|
|
|
|
|
if (res != MESHING3_OK) return 1;
|
|
|
|
if (multithread.terminate) return 0;
|
|
|
|
|
|
|
|
RemoveIllegalElements (*mesh);
|
|
|
|
if (multithread.terminate) return 0;
|
|
|
|
|
|
|
|
MeshQuality3d (*mesh);
|
|
|
|
}
|
|
|
|
|
2016-12-05 17:50:21 +05:00
|
|
|
if (multithread.terminate || mparam.perfstepsend <= MESHCONST_MESHVOLUME)
|
2010-03-23 17:52:07 +05:00
|
|
|
return 0;
|
2019-10-03 15:09:13 +05:00
|
|
|
|
2010-03-23 17:52:07 +05:00
|
|
|
|
2016-12-05 17:50:21 +05:00
|
|
|
if (mparam.perfstepsstart <= MESHCONST_OPTVOLUME)
|
2010-03-23 17:52:07 +05:00
|
|
|
{
|
|
|
|
multithread.task = "Volume optimization";
|
2019-10-03 15:09:13 +05:00
|
|
|
|
2010-03-23 17:52:07 +05:00
|
|
|
OptimizeVolume (mparam, *mesh);
|
|
|
|
if (multithread.terminate) return 0;
|
|
|
|
}
|
2019-10-02 20:20:13 +05:00
|
|
|
FinalizeMesh(*mesh);
|
2010-03-23 17:52:07 +05:00
|
|
|
return 0;
|
2019-10-02 20:20:13 +05:00
|
|
|
}
|
2010-03-23 17:52:07 +05:00
|
|
|
|
2011-01-11 01:18:01 +05:00
|
|
|
void NetgenGeometry :: Save (string filename) const
|
|
|
|
{
|
|
|
|
throw NgException("Cannot save geometry - no geometry available");
|
|
|
|
}
|
|
|
|
|
2018-12-14 16:01:58 +05:00
|
|
|
static RegisterClassForArchive<NetgenGeometry> regnggeo;
|
2010-03-23 17:52:07 +05:00
|
|
|
}
|