mirror of
https://github.com/NGSolve/netgen.git
synced 2025-01-11 21:50:34 +05:00
second order mesh merge
This commit is contained in:
parent
834304923b
commit
22222d4cbc
@ -1470,15 +1470,28 @@ namespace netgen
|
|||||||
|
|
||||||
// int si = sel.GetIndex();
|
// int si = sel.GetIndex();
|
||||||
|
|
||||||
for (int j = 0; j < sel.GetNP(); j++)
|
if (sel.GetNP() <= 4)
|
||||||
{
|
for (int j = 0; j < sel.GetNP(); j++)
|
||||||
INDEX_2 i2;
|
{
|
||||||
i2.I1() = sel.PNumMod(j+1);
|
INDEX_2 i2;
|
||||||
i2.I2() = sel.PNumMod(j+2);
|
i2.I1() = sel.PNumMod(j+1);
|
||||||
i2.Sort();
|
i2.I2() = sel.PNumMod(j+2);
|
||||||
if (sel.GetNP() <= 4)
|
i2.Sort();
|
||||||
boundaryedges->Set (i2, 1);
|
boundaryedges->Set (i2, 1);
|
||||||
|
}
|
||||||
|
else if (sel.GetType()==TRIG6)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
INDEX_2 i2;
|
||||||
|
i2.I1() = sel[j];
|
||||||
|
i2.I2() = sel[(j+1)%3];
|
||||||
|
i2.Sort();
|
||||||
|
boundaryedges->Set (i2, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
cerr << "illegal elemenet for buildboundaryedges" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1825,6 +1838,7 @@ namespace netgen
|
|||||||
for (ii = 0; ii < row.Size(); ii++)
|
for (ii = 0; ii < row.Size(); ii++)
|
||||||
{
|
{
|
||||||
hel = SurfaceElement(row[ii]);
|
hel = SurfaceElement(row[ii]);
|
||||||
|
if (hel.GetType() == TRIG6) hel.SetType(TRIG);
|
||||||
int ind = hel.GetIndex();
|
int ind = hel.GetIndex();
|
||||||
|
|
||||||
if (GetFaceDescriptor(ind).DomainIn() &&
|
if (GetFaceDescriptor(ind).DomainIn() &&
|
||||||
@ -4347,11 +4361,9 @@ namespace netgen
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
const int maxits = 30;
|
const int maxits = 30;
|
||||||
|
|
||||||
while(delta > 1e-16 && i<maxits)
|
while(delta > 1e-16 && i<maxits)
|
||||||
{
|
{
|
||||||
curvedelems->CalcElementTransformation(lam,element-1,x,Jac);
|
curvedelems->CalcElementTransformation(lam,element-1,x,Jac);
|
||||||
|
|
||||||
rhs = p-x;
|
rhs = p-x;
|
||||||
Jac.Solve(rhs,deltalam);
|
Jac.Solve(rhs,deltalam);
|
||||||
|
|
||||||
@ -4367,7 +4379,6 @@ namespace netgen
|
|||||||
if(i==maxits)
|
if(i==maxits)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
for(i=0; i<3; i++)
|
for(i=0; i<3; i++)
|
||||||
lami[i] = lam(i);
|
lami[i] = lam(i);
|
||||||
|
|
||||||
@ -4568,7 +4579,6 @@ namespace netgen
|
|||||||
ii = locels.Get(i);
|
ii = locels.Get(i);
|
||||||
else
|
else
|
||||||
ii = i;
|
ii = i;
|
||||||
|
|
||||||
if(ii == ps_startelement) continue;
|
if(ii == ps_startelement) continue;
|
||||||
|
|
||||||
if(indices != NULL && indices->Size() > 0)
|
if(indices != NULL && indices->Size() > 0)
|
||||||
|
@ -354,11 +354,22 @@ namespace netgen
|
|||||||
///
|
///
|
||||||
int GetNV() const
|
int GetNV() const
|
||||||
{
|
{
|
||||||
|
if (typ == TRIG || typ == TRIG6)
|
||||||
|
return 3;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (typ != QUAD && typ != QUAD6 && typ != QUAD8)
|
||||||
|
PrintSysError ("element2d::GetNV not implemented for typ", typ)
|
||||||
|
#endif
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
/*
|
||||||
switch (typ)
|
switch (typ)
|
||||||
{
|
{
|
||||||
case TRIG:
|
case TRIG:
|
||||||
case TRIG6: return 3;
|
case TRIG6: return 3;
|
||||||
|
|
||||||
case QUAD:
|
case QUAD:
|
||||||
case QUAD8:
|
case QUAD8:
|
||||||
case QUAD6: return 4;
|
case QUAD6: return 4;
|
||||||
@ -369,6 +380,7 @@ namespace netgen
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
return np;
|
return np;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include <mystdlib.h>
|
#include <mystdlib.h>
|
||||||
#include "meshing.hpp"
|
#include "meshing.hpp"
|
||||||
|
|
||||||
|
|
||||||
@ -13,13 +13,64 @@ namespace netgen
|
|||||||
|
|
||||||
void Refinement :: MakeSecondOrder (Mesh & mesh)
|
void Refinement :: MakeSecondOrder (Mesh & mesh)
|
||||||
{
|
{
|
||||||
int nseg, nse, ne;
|
/*
|
||||||
|
Berlin, 2014: if we have curved surface elements, keep them !
|
||||||
|
*/
|
||||||
|
|
||||||
mesh.ComputeNVertices();
|
mesh.ComputeNVertices();
|
||||||
mesh.SetNP(mesh.GetNV());
|
// mesh.SetNP(mesh.GetNV());
|
||||||
|
mesh.SetNP(mesh.GetNP()); // setup multilevel-table
|
||||||
|
|
||||||
INDEX_2_HASHTABLE<PointIndex> between(mesh.GetNP() + 5);
|
INDEX_2_HASHTABLE<PointIndex> between(mesh.GetNP() + 5);
|
||||||
|
|
||||||
|
for (SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++)
|
||||||
|
{
|
||||||
|
const Element2d & el = mesh[sei];
|
||||||
|
|
||||||
|
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 onp = 0;
|
||||||
|
int (*betw)[3] = NULL;
|
||||||
|
switch (el.GetType())
|
||||||
|
{
|
||||||
|
case TRIG6:
|
||||||
|
{
|
||||||
|
betw = betw_trig;
|
||||||
|
onp = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QUAD6:
|
||||||
|
{
|
||||||
|
betw = betw_quad6;
|
||||||
|
onp = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QUAD8:
|
||||||
|
{
|
||||||
|
betw = betw_quad8;
|
||||||
|
onp = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (betw)
|
||||||
|
for (int j = 0; j < el.GetNP()-onp; j++)
|
||||||
|
{
|
||||||
|
int pi1 = el[betw[j][0]];
|
||||||
|
int pi2 = el[betw[j][1]];
|
||||||
|
INDEX_2 i2 = INDEX_2::Sort (pi1, pi2);
|
||||||
|
between.Set (i2, el[onp+j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool thinlayers = 0;
|
bool thinlayers = 0;
|
||||||
for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++)
|
for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++)
|
||||||
@ -28,7 +79,7 @@ namespace netgen
|
|||||||
thinlayers = 1;
|
thinlayers = 1;
|
||||||
|
|
||||||
|
|
||||||
nseg = mesh.GetNSeg();
|
int nseg = mesh.GetNSeg();
|
||||||
for (SegmentIndex si = 0; si < nseg; si++)
|
for (SegmentIndex si = 0; si < nseg; si++)
|
||||||
{
|
{
|
||||||
Segment & el = mesh.LineSegment(si);
|
Segment & el = mesh.LineSegment(si);
|
||||||
@ -54,8 +105,7 @@ namespace netgen
|
|||||||
}
|
}
|
||||||
|
|
||||||
// refine surface elements
|
// refine surface elements
|
||||||
nse = mesh.GetNSE();
|
for (SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++)
|
||||||
for (SurfaceElementIndex sei = 0; sei < nse; sei++)
|
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
const Element2d & el = mesh.SurfaceElement(sei);
|
const Element2d & el = mesh.SurfaceElement(sei);
|
||||||
@ -149,8 +199,7 @@ namespace netgen
|
|||||||
|
|
||||||
|
|
||||||
// refine volume elements
|
// refine volume elements
|
||||||
ne = mesh.GetNE();
|
for (int i = 1; i <= mesh.GetNE(); i++)
|
||||||
for (int i = 1; i <= ne; i++)
|
|
||||||
{
|
{
|
||||||
const Element & el = mesh.VolumeElement(i);
|
const Element & el = mesh.VolumeElement(i);
|
||||||
int onp = 0;
|
int onp = 0;
|
||||||
|
@ -22,6 +22,9 @@ void STLGeometry :: MakeAtlas(Mesh & mesh)
|
|||||||
int timer1 = NgProfiler::CreateTimer ("makeatlas");
|
int timer1 = NgProfiler::CreateTimer ("makeatlas");
|
||||||
int timer2 = NgProfiler::CreateTimer ("makeatlas - part 2");
|
int timer2 = NgProfiler::CreateTimer ("makeatlas - part 2");
|
||||||
int timer3 = NgProfiler::CreateTimer ("makeatlas - part 3");
|
int timer3 = NgProfiler::CreateTimer ("makeatlas - part 3");
|
||||||
|
int timer4 = NgProfiler::CreateTimer ("makeatlas - part 4");
|
||||||
|
int timer4a = NgProfiler::CreateTimer ("makeatlas - part 4a");
|
||||||
|
int timer5 = NgProfiler::CreateTimer ("makeatlas - part 5");
|
||||||
|
|
||||||
PushStatusF("Make Atlas");
|
PushStatusF("Make Atlas");
|
||||||
|
|
||||||
@ -113,6 +116,8 @@ void STLGeometry :: MakeAtlas(Mesh & mesh)
|
|||||||
STLChart * chart = new STLChart(this);
|
STLChart * chart = new STLChart(this);
|
||||||
atlas.Append(chart);
|
atlas.Append(chart);
|
||||||
|
|
||||||
|
// *testout << "Chart " << atlas.Size() << endl;
|
||||||
|
|
||||||
//find unmarked trig
|
//find unmarked trig
|
||||||
int prelastunmarked = lastunmarked;
|
int prelastunmarked = lastunmarked;
|
||||||
|
|
||||||
@ -143,7 +148,8 @@ void STLGeometry :: MakeAtlas(Mesh & mesh)
|
|||||||
|
|
||||||
Vec<3> sn = GetTriangle(starttrig).Normal();
|
Vec<3> sn = GetTriangle(starttrig).Normal();
|
||||||
chart->SetNormal (startp, sn);
|
chart->SetNormal (startp, sn);
|
||||||
|
|
||||||
|
// *testout << "first trig " << starttrig << ", n = " << sn << endl;
|
||||||
|
|
||||||
SetMarker(starttrig, chartnum);
|
SetMarker(starttrig, chartnum);
|
||||||
markedtrigcnt++;
|
markedtrigcnt++;
|
||||||
@ -181,14 +187,16 @@ void STLGeometry :: MakeAtlas(Mesh & mesh)
|
|||||||
for (int j = 1; j <= NONeighbourTrigs(i); j++)
|
for (int j = 1; j <= NONeighbourTrigs(i); j++)
|
||||||
{
|
{
|
||||||
int nt = NeighbourTrig(i,j);
|
int nt = NeighbourTrig(i,j);
|
||||||
|
// *testout << "check trig " << nt << endl;
|
||||||
int np1, np2;
|
int np1, np2;
|
||||||
GetTriangle(i).GetNeighbourPoints(GetTriangle(nt),np1,np2);
|
GetTriangle(i).GetNeighbourPoints(GetTriangle(nt),np1,np2);
|
||||||
if (GetMarker(nt) == 0 && !IsEdge(np1,np2))
|
if (GetMarker(nt) == 0 && !IsEdge(np1,np2))
|
||||||
{
|
{
|
||||||
Vec<3> n2 = GetTriangle(nt).Normal();
|
Vec<3> n2 = GetTriangle(nt).Normal();
|
||||||
|
// *testout << "acos = " << 180/M_PI*acos (n2*sn) << endl;
|
||||||
if ( (n2 * sn) >= coschartangle )
|
if ( (n2 * sn) >= coschartangle )
|
||||||
{
|
{
|
||||||
|
// *testout << "good angle " << endl;
|
||||||
accepted = 1;
|
accepted = 1;
|
||||||
/*
|
/*
|
||||||
//alter spiralentest, schnell, aber ungenau
|
//alter spiralentest, schnell, aber ungenau
|
||||||
@ -229,19 +237,22 @@ void STLGeometry :: MakeAtlas(Mesh & mesh)
|
|||||||
accepted = chartbound.TestSeg(GetPoint(nnp1),
|
accepted = chartbound.TestSeg(GetPoint(nnp1),
|
||||||
GetPoint(nnp2),
|
GetPoint(nnp2),
|
||||||
sn,sinchartangle,1 /*chartboundarydivisions*/ ,points, eps);
|
sn,sinchartangle,1 /*chartboundarydivisions*/ ,points, eps);
|
||||||
|
|
||||||
|
// if (!accepted) *testout << "not acc due to testseg" << endl;
|
||||||
|
|
||||||
Vec<3> n3 = GetTriangle(nnt).Normal();
|
Vec<3> n3 = GetTriangle(nnt).Normal();
|
||||||
if ( (n3 * sn) >= coschartangle &&
|
if ( (n3 * sn) >= coschartangle &&
|
||||||
IsSmoothEdge (nnp1, nnp2) )
|
IsSmoothEdge (nnp1, nnp2) )
|
||||||
accepted = 1;
|
accepted = 1;
|
||||||
}
|
}
|
||||||
if (!accepted) {break;}
|
if (!accepted)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (accepted)
|
if (accepted)
|
||||||
{
|
{
|
||||||
|
// *testout << "trig accepted" << endl;
|
||||||
SetMarker(nt, chartnum);
|
SetMarker(nt, chartnum);
|
||||||
changed = true;
|
changed = true;
|
||||||
markedtrigcnt++;
|
markedtrigcnt++;
|
||||||
@ -318,6 +329,8 @@ void STLGeometry :: MakeAtlas(Mesh & mesh)
|
|||||||
{
|
{
|
||||||
accepted = 1;
|
accepted = 1;
|
||||||
|
|
||||||
|
NgProfiler::StartTimer (timer4);
|
||||||
|
|
||||||
bool isdirtytrig = false;
|
bool isdirtytrig = false;
|
||||||
Vec<3> gn = GetTriangle(nt).GeomNormal(points);
|
Vec<3> gn = GetTriangle(nt).GeomNormal(points);
|
||||||
double gnlen = gn.Length();
|
double gnlen = gn.Length();
|
||||||
@ -339,11 +352,15 @@ void STLGeometry :: MakeAtlas(Mesh & mesh)
|
|||||||
int nnp1, nnp2;
|
int nnp1, nnp2;
|
||||||
GetTriangle(nt).GetNeighbourPoints(GetTriangle(nnt),nnp1,nnp2);
|
GetTriangle(nt).GetNeighbourPoints(GetTriangle(nnt),nnp1,nnp2);
|
||||||
|
|
||||||
|
// NgProfiler::StartTimer (timer4a);
|
||||||
|
|
||||||
accepted =
|
accepted =
|
||||||
chartbound.TestSeg(GetPoint(nnp1),GetPoint(nnp2),
|
chartbound.TestSeg(GetPoint(nnp1),GetPoint(nnp2),
|
||||||
sn,sinouterchartangle, 0 /*chartboundarydivisions*/ ,points, eps);
|
sn,sinouterchartangle, 0 /*chartboundarydivisions*/ ,points, eps);
|
||||||
|
|
||||||
|
// NgProfiler::StopTimer (timer4a);
|
||||||
|
|
||||||
|
|
||||||
Vec<3> n3 = GetTriangle(nnt).Normal();
|
Vec<3> n3 = GetTriangle(nnt).Normal();
|
||||||
if ( (n3 * sn) >= cosouterchartangle &&
|
if ( (n3 * sn) >= cosouterchartangle &&
|
||||||
IsSmoothEdge (nnp1, nnp2) )
|
IsSmoothEdge (nnp1, nnp2) )
|
||||||
@ -352,7 +369,11 @@ void STLGeometry :: MakeAtlas(Mesh & mesh)
|
|||||||
if (!accepted) break;
|
if (!accepted) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NgProfiler::StopTimer (timer4);
|
||||||
|
|
||||||
|
NgProfiler::RegionTimer reg5(timer5);
|
||||||
|
|
||||||
|
|
||||||
// outer chart is only small environment of
|
// outer chart is only small environment of
|
||||||
// inner chart:
|
// inner chart:
|
||||||
|
|
||||||
|
@ -894,10 +894,10 @@ void STLBoundary ::AddTriangle(const STLTriangle & t)
|
|||||||
int STLBoundary :: TestSeg(const Point<3>& p1, const Point<3> & p2, const Vec<3> & sn,
|
int STLBoundary :: TestSeg(const Point<3>& p1, const Point<3> & p2, const Vec<3> & sn,
|
||||||
double sinchartangle, int divisions, Array<Point<3> >& points, double eps)
|
double sinchartangle, int divisions, Array<Point<3> >& points, double eps)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (usechartnormal)
|
if (usechartnormal)
|
||||||
return TestSegChartNV (p1, p2, sn);
|
return TestSegChartNV (p1, p2, sn);
|
||||||
|
|
||||||
|
#ifdef NONE
|
||||||
// for statistics
|
// for statistics
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -936,7 +936,7 @@ int STLBoundary :: TestSeg(const Point<3>& p1, const Point<3> & p2, const Vec<3>
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int i,j,k;
|
int i,j,k;
|
||||||
Point<3> seg1p/*, seg2p*/;
|
Point<3> seg1p/*, seg2p*/;
|
||||||
@ -1087,6 +1087,9 @@ int STLBoundary :: TestSeg(const Point<3>& p1, const Point<3> & p2, const Vec<3>
|
|||||||
int STLBoundary :: TestSegChartNV(const Point3d & p1, const Point3d& p2,
|
int STLBoundary :: TestSegChartNV(const Point3d & p1, const Point3d& p2,
|
||||||
const Vec3d& sn)
|
const Vec3d& sn)
|
||||||
{
|
{
|
||||||
|
int timer = NgProfiler::CreateTimer ("TestSegChartNV");
|
||||||
|
NgProfiler::StartTimer (timer);
|
||||||
|
|
||||||
int nseg = NOSegments();
|
int nseg = NOSegments();
|
||||||
|
|
||||||
Point<2> p2d1 = chart->Project2d (p1);
|
Point<2> p2d1 = chart->Project2d (p1);
|
||||||
@ -1103,11 +1106,10 @@ int STLBoundary :: TestSegChartNV(const Point3d & p1, const Point3d& p2,
|
|||||||
|
|
||||||
for (int j = 1; j <= nseg; j++)
|
for (int j = 1; j <= nseg; j++)
|
||||||
{
|
{
|
||||||
if (!ok) continue;
|
|
||||||
const STLBoundarySeg & seg = GetSegment(j);
|
const STLBoundarySeg & seg = GetSegment(j);
|
||||||
|
|
||||||
if (!box2d.Intersect (seg.BoundingBox())) continue;
|
|
||||||
if (seg.IsSmoothEdge()) continue;
|
if (seg.IsSmoothEdge()) continue;
|
||||||
|
if (!box2d.Intersect (seg.BoundingBox())) continue;
|
||||||
|
|
||||||
const Point<2> & sp1 = seg.P2D1();
|
const Point<2> & sp1 = seg.P2D1();
|
||||||
const Point<2> & sp2 = seg.P2D2();
|
const Point<2> & sp2 = seg.P2D2();
|
||||||
@ -1115,14 +1117,18 @@ int STLBoundary :: TestSegChartNV(const Point3d & p1, const Point3d& p2,
|
|||||||
Line2d l2 (sp1, sp2);
|
Line2d l2 (sp1, sp2);
|
||||||
double lam1, lam2;
|
double lam1, lam2;
|
||||||
|
|
||||||
int err =
|
int err = CrossPointBarycentric (l1, l2, lam1, lam2);
|
||||||
CrossPointBarycentric (l1, l2, lam1, lam2);
|
|
||||||
|
|
||||||
if (!err && lam1 > eps && lam1 < 1-eps &&
|
if (!err && lam1 > eps && lam1 < 1-eps &&
|
||||||
lam2 > eps && lam2 < 1-eps)
|
lam2 > eps && lam2 < 1-eps)
|
||||||
ok = false;
|
{
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NgProfiler::StopTimer (timer);
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user