mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-24 21:10:33 +05:00
* Changes to the Boundary Layer generation system
* More user feedback when saving and exporting mesh files to disk
This commit is contained in:
parent
6f39164242
commit
b2e8610f90
@ -141,9 +141,14 @@ namespace netgen
|
|||||||
Currently, the layer height is calculated using:
|
Currently, the layer height is calculated using:
|
||||||
height = h_first_layer * (growth_factor^(num_layers - 1))
|
height = h_first_layer * (growth_factor^(num_layers - 1))
|
||||||
*/
|
*/
|
||||||
void GenerateBoundaryLayer (Mesh & mesh)
|
void GenerateBoundaryLayer (Mesh & mesh, MeshingParameters & mp)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
|
// Angle between a surface element and a growth-vector below which
|
||||||
|
// a prism is project onto that surface as a quad
|
||||||
|
// (in degrees)
|
||||||
|
double angleThreshold = 15.0;
|
||||||
|
|
||||||
cout << "Generate Prismatic Boundary Layers (Experimental)...." << endl;
|
cout << "Generate Prismatic Boundary Layers (Experimental)...." << endl;
|
||||||
|
|
||||||
@ -167,7 +172,13 @@ namespace netgen
|
|||||||
if(surfinp >= 0) surfid.Append(surfinp);
|
if(surfinp >= 0) surfid.Append(surfinp);
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "Number of surfaces entered = " << surfid.Size() << endl;
|
cout << "Number of surfaces entered = " << surfid.Size() << endl;
|
||||||
|
cout << "Selected surfaces are:" << endl;
|
||||||
|
|
||||||
|
for(i = 1; i <= surfid.Size(); i++)
|
||||||
|
{
|
||||||
|
cout << "Surface " << i << ": " << surfid.Elem(i) << endl;
|
||||||
|
}
|
||||||
|
|
||||||
cout << endl << "Enter number of prism layers: ";
|
cout << endl << "Enter number of prism layers: ";
|
||||||
cin >> prismlayers;
|
cin >> prismlayers;
|
||||||
@ -188,8 +199,18 @@ namespace netgen
|
|||||||
{
|
{
|
||||||
cout << "Generating layer: " << layer << endl;
|
cout << "Generating layer: " << layer << endl;
|
||||||
|
|
||||||
//double layerht = hfirst + growthfactor*(layer - 1)*hfirst;
|
double layerht = hfirst;
|
||||||
double layerht = hfirst*pow(growthfactor,(double)(layer-1));
|
|
||||||
|
if(growthfactor == 1)
|
||||||
|
{
|
||||||
|
layerht = layer * hfirst;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
layerht = hfirst*(pow(growthfactor,(layer+1)) - 1)/(growthfactor - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "Layer Height = " << layerht << endl;
|
||||||
|
|
||||||
// Need to store the old number of points and
|
// Need to store the old number of points and
|
||||||
// surface elements because there are new points and
|
// surface elements because there are new points and
|
||||||
@ -201,6 +222,9 @@ namespace netgen
|
|||||||
// consistency
|
// consistency
|
||||||
int nseg = mesh.GetNSeg();
|
int nseg = mesh.GetNSeg();
|
||||||
|
|
||||||
|
// Update the mesh topology structures
|
||||||
|
mesh.UpdateTopology();
|
||||||
|
|
||||||
const MeshTopology& meshtopo = mesh.GetTopology();
|
const MeshTopology& meshtopo = mesh.GetTopology();
|
||||||
|
|
||||||
// Indicate which points need to be remapped
|
// Indicate which points need to be remapped
|
||||||
@ -213,9 +237,6 @@ namespace netgen
|
|||||||
// the effective surface normal at a given point
|
// the effective surface normal at a given point
|
||||||
Array<Vec3d> growthvectors(np);
|
Array<Vec3d> growthvectors(np);
|
||||||
|
|
||||||
// Update the mesh topology structures
|
|
||||||
mesh.UpdateTopology();
|
|
||||||
|
|
||||||
// Bit array to identify all the points belonging
|
// Bit array to identify all the points belonging
|
||||||
// to the surface of interest
|
// to the surface of interest
|
||||||
bndnodes.Clear();
|
bndnodes.Clear();
|
||||||
@ -242,7 +263,7 @@ namespace netgen
|
|||||||
bndnodes.Set(sel.PNum(j));
|
bndnodes.Set(sel.PNum(j));
|
||||||
|
|
||||||
// Vec3d& surfacenormal = Vec3d(); ????
|
// Vec3d& surfacenormal = Vec3d(); ????
|
||||||
Vec3d surfacenormal;
|
Vec3d surfacenormal;
|
||||||
|
|
||||||
// Calculate the surface normal at the current point
|
// Calculate the surface normal at the current point
|
||||||
// with respect to the current surface element
|
// with respect to the current surface element
|
||||||
@ -369,8 +390,13 @@ namespace netgen
|
|||||||
mesh.LineSegment(j)[1] = mapto.Get(seg_p1);
|
mesh.LineSegment(j)[1] = mapto.Get(seg_p1);
|
||||||
mesh.LineSegment(j)[0] = mapto.Get(seg_p2);
|
mesh.LineSegment(j)[0] = mapto.Get(seg_p2);
|
||||||
|
|
||||||
if(surfangle <= 1.5707)
|
if(surfangle <= angleThreshold * 3.141592 / 180.0)
|
||||||
{
|
{
|
||||||
|
// Since the surface is lower than the threshold, change the effective
|
||||||
|
// prism growth vector to match with the surface vector, so that
|
||||||
|
// the Quad which is created lies on the original surface
|
||||||
|
growthvectors.Elem(segpair_p1) = surfelem_vect;
|
||||||
|
|
||||||
// Add a quad element to account for the prism volume
|
// Add a quad element to account for the prism volume
|
||||||
// element which is going to be added
|
// element which is going to be added
|
||||||
Element2d sel(QUAD);
|
Element2d sel(QUAD);
|
||||||
@ -521,24 +547,27 @@ namespace netgen
|
|||||||
{
|
{
|
||||||
double sfact = 0.9;
|
double sfact = 0.9;
|
||||||
Element volel = mesh.VolumeElement(vertelems.Elem(j));
|
Element volel = mesh.VolumeElement(vertelems.Elem(j));
|
||||||
if((volel.GetType() == TET) || (volel.GetType() == TET10))
|
if(((volel.GetType() == TET) || (volel.GetType() == TET10)) && (!volel.IsDeleted()))
|
||||||
{
|
{
|
||||||
while((volel.Volume(mesh.Points()) <= 0.0) && (sfact >= 0.0))
|
//while((volel.Volume(mesh.Points()) <= 0.0) && (sfact >= 0.0))
|
||||||
{
|
//{
|
||||||
mesh.Point(i).SetPoint(pointtomove + (sfact * layerht * growthvectors.Elem(i)));
|
// mesh.Point(i).SetPoint(pointtomove + (sfact * layerht * growthvectors.Elem(i)));
|
||||||
mesh.ImproveMesh();
|
// mesh.ImproveMesh();
|
||||||
|
|
||||||
// Try to move the point back by one step but
|
// // Try to move the point back by one step but
|
||||||
// if the volume drops to below zero, double back
|
// // if the volume drops to below zero, double back
|
||||||
mesh.Point(i).SetPoint(pointtomove + ((sfact + 0.1) * layerht * growthvectors.Elem(i)));
|
// mesh.Point(i).SetPoint(pointtomove + ((sfact + 0.1) * layerht * growthvectors.Elem(i)));
|
||||||
if(volel.Volume(mesh.Points()) <= 0.0)
|
// if(volel.Volume(mesh.Points()) <= 0.0)
|
||||||
{
|
// {
|
||||||
mesh.Point(i).SetPoint(pointtomove + (sfact * layerht * growthvectors.Elem(i)));
|
// mesh.Point(i).SetPoint(pointtomove + (sfact * layerht * growthvectors.Elem(i)));
|
||||||
}
|
// }
|
||||||
sfact -= 0.1;
|
// sfact -= 0.1;
|
||||||
}
|
//}
|
||||||
|
volel.Delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mesh.Compress();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@ extern void InsertVirtualBoundaryLayer (Mesh & mesh);
|
|||||||
|
|
||||||
/// Create a typical prismatic boundary layer on the given
|
/// Create a typical prismatic boundary layer on the given
|
||||||
/// surfaces
|
/// surfaces
|
||||||
extern void GenerateBoundaryLayer (Mesh & mesh);
|
extern void GenerateBoundaryLayer (Mesh & mesh, MeshingParameters & mp);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -13,298 +13,298 @@ namespace netgen
|
|||||||
extern double teterrpow;
|
extern double teterrpow;
|
||||||
MESHING3_RESULT MeshVolume (MeshingParameters & mp, Mesh& mesh3d)
|
MESHING3_RESULT MeshVolume (MeshingParameters & mp, Mesh& mesh3d)
|
||||||
{
|
{
|
||||||
int i, oldne;
|
int i, oldne;
|
||||||
PointIndex pi;
|
PointIndex pi;
|
||||||
|
|
||||||
int meshed;
|
int meshed;
|
||||||
int cntsteps;
|
int cntsteps;
|
||||||
|
|
||||||
|
|
||||||
Array<INDEX_2> connectednodes;
|
Array<INDEX_2> connectednodes;
|
||||||
|
|
||||||
if (&mesh3d.LocalHFunction() == NULL) mesh3d.CalcLocalH();
|
if (&mesh3d.LocalHFunction() == NULL) mesh3d.CalcLocalH();
|
||||||
|
|
||||||
mesh3d.Compress();
|
mesh3d.Compress();
|
||||||
|
|
||||||
// mesh3d.PrintMemInfo (cout);
|
// mesh3d.PrintMemInfo (cout);
|
||||||
|
|
||||||
if (mp.checkoverlappingboundary)
|
if (mp.checkoverlappingboundary)
|
||||||
if (mesh3d.CheckOverlappingBoundary())
|
if (mesh3d.CheckOverlappingBoundary())
|
||||||
throw NgException ("Stop meshing since boundary mesh is overlapping");
|
throw NgException ("Stop meshing since boundary mesh is overlapping");
|
||||||
|
|
||||||
int nonconsist = 0;
|
int nonconsist = 0;
|
||||||
for (int k = 1; k <= mesh3d.GetNDomains(); k++)
|
for (int k = 1; k <= mesh3d.GetNDomains(); k++)
|
||||||
{
|
{
|
||||||
PrintMessage (3, "Check subdomain ", k, " / ", mesh3d.GetNDomains());
|
PrintMessage (3, "Check subdomain ", k, " / ", mesh3d.GetNDomains());
|
||||||
|
|
||||||
mesh3d.FindOpenElements(k);
|
mesh3d.FindOpenElements(k);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
bool res = mesh3d.CheckOverlappingBoundary();
|
bool res = mesh3d.CheckOverlappingBoundary();
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
PrintError ("Surface is overlapping !!");
|
PrintError ("Surface is overlapping !!");
|
||||||
nonconsist = 1;
|
nonconsist = 1;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool res = (mesh3d.CheckConsistentBoundary() != 0);
|
bool res = (mesh3d.CheckConsistentBoundary() != 0);
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
PrintError ("Surface mesh not consistent");
|
PrintError ("Surface mesh not consistent");
|
||||||
nonconsist = 1;
|
nonconsist = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nonconsist)
|
if (nonconsist)
|
||||||
{
|
{
|
||||||
PrintError ("Stop meshing since surface mesh not consistent");
|
PrintError ("Stop meshing since surface mesh not consistent");
|
||||||
throw NgException ("Stop meshing since surface mesh not consistent");
|
throw NgException ("Stop meshing since surface mesh not consistent");
|
||||||
}
|
}
|
||||||
|
|
||||||
double globmaxh = mp.maxh;
|
double globmaxh = mp.maxh;
|
||||||
|
|
||||||
for (int k = 1; k <= mesh3d.GetNDomains(); k++)
|
for (int k = 1; k <= mesh3d.GetNDomains(); k++)
|
||||||
{
|
{
|
||||||
if (multithread.terminate)
|
if (multithread.terminate)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
PrintMessage (2, "");
|
PrintMessage (2, "");
|
||||||
PrintMessage (1, "Meshing subdomain ", k, " of ", mesh3d.GetNDomains());
|
PrintMessage (1, "Meshing subdomain ", k, " of ", mesh3d.GetNDomains());
|
||||||
(*testout) << "Meshing subdomain " << k << endl;
|
(*testout) << "Meshing subdomain " << k << endl;
|
||||||
|
|
||||||
mp.maxh = min2 (globmaxh, mesh3d.MaxHDomain(k));
|
|
||||||
|
|
||||||
mesh3d.CalcSurfacesOfNode();
|
mp.maxh = min2 (globmaxh, mesh3d.MaxHDomain(k));
|
||||||
mesh3d.FindOpenElements(k);
|
|
||||||
|
|
||||||
if (!mesh3d.GetNOpenElements())
|
mesh3d.CalcSurfacesOfNode();
|
||||||
continue;
|
mesh3d.FindOpenElements(k);
|
||||||
|
|
||||||
|
if (!mesh3d.GetNOpenElements())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Box<3> domain_bbox( Box<3>::EMPTY_BOX );
|
Box<3> domain_bbox( Box<3>::EMPTY_BOX );
|
||||||
/*
|
/*
|
||||||
Point<3> (1e10, 1e10, 1e10),
|
Point<3> (1e10, 1e10, 1e10),
|
||||||
Point<3> (-1e10, -1e10, -1e10));
|
Point<3> (-1e10, -1e10, -1e10));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (SurfaceElementIndex sei = 0; sei < mesh3d.GetNSE(); sei++)
|
for (SurfaceElementIndex sei = 0; sei < mesh3d.GetNSE(); sei++)
|
||||||
{
|
{
|
||||||
const Element2d & el = mesh3d[sei];
|
const Element2d & el = mesh3d[sei];
|
||||||
if (el.IsDeleted() ) continue;
|
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++)
|
if (mesh3d.GetFaceDescriptor(el.GetIndex()).DomainIn() == k ||
|
||||||
domain_bbox.Add (mesh3d[el[j]]);
|
mesh3d.GetFaceDescriptor(el.GetIndex()).DomainOut() == k)
|
||||||
}
|
|
||||||
domain_bbox.Increase (0.01 * domain_bbox.Diam());
|
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++)
|
for (int qstep = 1; qstep <= 3; qstep++)
|
||||||
{
|
{
|
||||||
if (mesh3d.HasOpenQuads())
|
if (mesh3d.HasOpenQuads())
|
||||||
{
|
{
|
||||||
string rulefile = ngdir;
|
string rulefile = ngdir;
|
||||||
|
|
||||||
const char ** rulep = NULL;
|
const char ** rulep = NULL;
|
||||||
switch (qstep)
|
switch (qstep)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
rulefile += "/rules/prisms2.rls";
|
rulefile += "/rules/prisms2.rls";
|
||||||
rulep = prismrules2;
|
rulep = prismrules2;
|
||||||
break;
|
break;
|
||||||
case 2: // connect pyramid to triangle
|
case 2: // connect pyramid to triangle
|
||||||
rulefile += "/rules/pyramids2.rls";
|
rulefile += "/rules/pyramids2.rls";
|
||||||
rulep = pyramidrules2;
|
rulep = pyramidrules2;
|
||||||
break;
|
break;
|
||||||
case 3: // connect to vis-a-vis point
|
case 3: // connect to vis-a-vis point
|
||||||
rulefile += "/rules/pyramids.rls";
|
rulefile += "/rules/pyramids.rls";
|
||||||
rulep = pyramidrules;
|
rulep = pyramidrules;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Meshing3 meshing(rulefile);
|
// Meshing3 meshing(rulefile);
|
||||||
Meshing3 meshing(rulep);
|
Meshing3 meshing(rulep);
|
||||||
|
|
||||||
MeshingParameters mpquad = mp;
|
MeshingParameters mpquad = mp;
|
||||||
|
|
||||||
mpquad.giveuptol = 15;
|
mpquad.giveuptol = 15;
|
||||||
mpquad.baseelnp = 4;
|
mpquad.baseelnp = 4;
|
||||||
mpquad.starshapeclass = 1000;
|
mpquad.starshapeclass = 1000;
|
||||||
mpquad.check_impossible = qstep == 1; // for prisms only (air domain in trafo)
|
mpquad.check_impossible = qstep == 1; // for prisms only (air domain in trafo)
|
||||||
|
|
||||||
|
|
||||||
for (pi = PointIndex::BASE;
|
for (pi = PointIndex::BASE;
|
||||||
pi < mesh3d.GetNP()+PointIndex::BASE; pi++)
|
pi < mesh3d.GetNP()+PointIndex::BASE; pi++)
|
||||||
meshing.AddPoint (mesh3d[pi], pi);
|
meshing.AddPoint (mesh3d[pi], pi);
|
||||||
|
|
||||||
mesh3d.GetIdentifications().GetPairs (0, connectednodes);
|
mesh3d.GetIdentifications().GetPairs (0, connectednodes);
|
||||||
for (i = 1; i <= connectednodes.Size(); i++)
|
for (i = 1; i <= connectednodes.Size(); i++)
|
||||||
meshing.AddConnectedPair (connectednodes.Get(i));
|
meshing.AddConnectedPair (connectednodes.Get(i));
|
||||||
|
|
||||||
for (i = 1; i <= mesh3d.GetNOpenElements(); i++)
|
for (i = 1; i <= mesh3d.GetNOpenElements(); i++)
|
||||||
{
|
{
|
||||||
Element2d hel = mesh3d.OpenElement(i);
|
Element2d hel = mesh3d.OpenElement(i);
|
||||||
meshing.AddBoundaryElement (hel);
|
meshing.AddBoundaryElement (hel);
|
||||||
}
|
}
|
||||||
|
|
||||||
oldne = mesh3d.GetNE();
|
oldne = mesh3d.GetNE();
|
||||||
|
|
||||||
meshing.GenerateMesh (mesh3d, mpquad);
|
meshing.GenerateMesh (mesh3d, mpquad);
|
||||||
|
|
||||||
for (i = oldne + 1; i <= mesh3d.GetNE(); i++)
|
for (i = oldne + 1; i <= mesh3d.GetNE(); i++)
|
||||||
mesh3d.VolumeElement(i).SetIndex (k);
|
mesh3d.VolumeElement(i).SetIndex (k);
|
||||||
|
|
||||||
(*testout)
|
(*testout)
|
||||||
<< "mesh has " << mesh3d.GetNE() << " prism/pyramid elements" << endl;
|
<< "mesh has " << mesh3d.GetNE() << " prism/pyramid elements" << endl;
|
||||||
|
|
||||||
mesh3d.FindOpenElements(k);
|
mesh3d.FindOpenElements(k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (mesh3d.HasOpenQuads())
|
if (mesh3d.HasOpenQuads())
|
||||||
{
|
{
|
||||||
PrintSysError ("mesh has still open quads");
|
PrintSysError ("mesh has still open quads");
|
||||||
throw NgException ("Stop meshing since too many attempts");
|
throw NgException ("Stop meshing since too many attempts");
|
||||||
// return MESHING3_GIVEUP;
|
// return MESHING3_GIVEUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (mp.delaunay && mesh3d.GetNOpenElements())
|
if (mp.delaunay && mesh3d.GetNOpenElements())
|
||||||
{
|
{
|
||||||
Meshing3 meshing((const char**)NULL);
|
Meshing3 meshing((const char**)NULL);
|
||||||
|
|
||||||
mesh3d.FindOpenElements(k);
|
|
||||||
|
|
||||||
|
|
||||||
for (pi = PointIndex::BASE;
|
mesh3d.FindOpenElements(k);
|
||||||
pi < mesh3d.GetNP()+PointIndex::BASE; pi++)
|
|
||||||
meshing.AddPoint (mesh3d[pi], pi);
|
|
||||||
|
|
||||||
|
|
||||||
for (i = 1; i <= mesh3d.GetNOpenElements(); i++)
|
|
||||||
meshing.AddBoundaryElement (mesh3d.OpenElement(i));
|
|
||||||
|
|
||||||
oldne = mesh3d.GetNE();
|
|
||||||
|
|
||||||
meshing.Delaunay (mesh3d, k, mp);
|
|
||||||
|
|
||||||
for (i = oldne + 1; i <= mesh3d.GetNE(); i++)
|
|
||||||
mesh3d.VolumeElement(i).SetIndex (k);
|
|
||||||
|
|
||||||
PrintMessage (3, mesh3d.GetNP(), " points, ",
|
|
||||||
mesh3d.GetNE(), " elements");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cntsteps = 0;
|
for (pi = PointIndex::BASE;
|
||||||
if (mesh3d.GetNOpenElements())
|
pi < mesh3d.GetNP()+PointIndex::BASE; pi++)
|
||||||
do
|
meshing.AddPoint (mesh3d[pi], pi);
|
||||||
{
|
|
||||||
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 (pi = PointIndex::BASE;
|
|
||||||
pi < mesh3d.GetNP()+PointIndex::BASE; pi++)
|
|
||||||
|
|
||||||
if (domain_bbox.IsIn (mesh3d[pi]))
|
|
||||||
glob2loc[pi] =
|
|
||||||
meshing.AddPoint (mesh3d[pi], pi);
|
|
||||||
|
|
||||||
for (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");
|
|
||||||
|
|
||||||
// mesh3d.Save ("tmp.vol");
|
|
||||||
|
|
||||||
|
|
||||||
MeshOptimize3d optmesh;
|
for (i = 1; i <= mesh3d.GetNOpenElements(); i++)
|
||||||
|
meshing.AddBoundaryElement (mesh3d.OpenElement(i));
|
||||||
|
|
||||||
const char * optstr = "mcmstmcmstmcmstmcm";
|
oldne = mesh3d.GetNE();
|
||||||
size_t j;
|
|
||||||
for (j = 1; j <= strlen(optstr); j++)
|
|
||||||
{
|
|
||||||
mesh3d.CalcSurfacesOfNode();
|
|
||||||
mesh3d.FreeOpenElementsEnvironment(2);
|
|
||||||
mesh3d.CalcSurfacesOfNode();
|
|
||||||
|
|
||||||
switch (optstr[j-1])
|
meshing.Delaunay (mesh3d, k, mp);
|
||||||
{
|
|
||||||
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(OPT_REST); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
for (i = oldne + 1; i <= mesh3d.GetNE(); i++)
|
||||||
|
mesh3d.VolumeElement(i).SetIndex (k);
|
||||||
|
|
||||||
mesh3d.FindOpenElements(k);
|
PrintMessage (3, mesh3d.GetNP(), " points, ",
|
||||||
PrintMessage (3, "Call remove problem");
|
mesh3d.GetNE(), " elements");
|
||||||
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;
|
cntsteps = 0;
|
||||||
|
if (mesh3d.GetNOpenElements())
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (multithread.terminate)
|
||||||
|
break;
|
||||||
|
|
||||||
MeshQuality3d (mesh3d);
|
mesh3d.FindOpenElements(k);
|
||||||
|
PrintMessage (5, mesh3d.GetNOpenElements(), " open faces");
|
||||||
|
cntsteps++;
|
||||||
|
|
||||||
return MESHING3_OK;
|
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 (pi = PointIndex::BASE;
|
||||||
|
pi < mesh3d.GetNP()+PointIndex::BASE; pi++)
|
||||||
|
|
||||||
|
if (domain_bbox.IsIn (mesh3d[pi]))
|
||||||
|
glob2loc[pi] =
|
||||||
|
meshing.AddPoint (mesh3d[pi], pi);
|
||||||
|
|
||||||
|
for (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");
|
||||||
|
|
||||||
|
// mesh3d.Save ("tmp.vol");
|
||||||
|
|
||||||
|
|
||||||
|
MeshOptimize3d optmesh;
|
||||||
|
|
||||||
|
const char * optstr = "mcmstmcmstmcmstmcm";
|
||||||
|
size_t j;
|
||||||
|
for (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(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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -399,7 +399,7 @@ namespace netgen
|
|||||||
}
|
}
|
||||||
|
|
||||||
const string filename (argv[1]);
|
const string filename (argv[1]);
|
||||||
PrintMessage (1, "Save mesh to file ", filename);
|
PrintMessage (1, "Save mesh to file ", filename, ".... Please Wait!");
|
||||||
|
|
||||||
ofstream outfile(filename.c_str());
|
ofstream outfile(filename.c_str());
|
||||||
mesh -> Save (outfile);
|
mesh -> Save (outfile);
|
||||||
@ -408,6 +408,7 @@ namespace netgen
|
|||||||
|
|
||||||
if (geometry && geometry->GetNSurf()) geometry->SaveSurfaces(outfile);
|
if (geometry && geometry->GetNSurf()) geometry->SaveSurfaces(outfile);
|
||||||
|
|
||||||
|
PrintMessage (1, "Save mesh to file .... DONE!");
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,6 +466,7 @@ namespace netgen
|
|||||||
|
|
||||||
string filename (argv[1]);
|
string filename (argv[1]);
|
||||||
string filetype (argv[2]);
|
string filetype (argv[2]);
|
||||||
|
PrintMessage (1, "Export mesh to file ", filename, ".... Please Wait!");
|
||||||
|
|
||||||
if (WriteUserFormat (filetype, *mesh, *geometry, filename))
|
if (WriteUserFormat (filetype, *mesh, *geometry, filename))
|
||||||
{
|
{
|
||||||
@ -474,6 +476,7 @@ namespace netgen
|
|||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrintMessage (1, "Export mesh to file .... DONE!");
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1868,7 +1871,7 @@ namespace netgen
|
|||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateBoundaryLayer (*mesh);
|
GenerateBoundaryLayer (*mesh, mparam);
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user