fix parallel surface optimization with occ

This commit is contained in:
mhochsteger@cerbsim.com 2022-03-02 14:58:39 +01:00
parent 4e8fe77098
commit 43382d4be8
3 changed files with 46 additions and 86 deletions

View File

@ -982,11 +982,10 @@ namespace netgen
static Timer timer_opt2d("Optimization 2D");
RegionTimer reg(timer_opt2d);
auto meshopt = MeshOptimize2d(mesh);
meshopt.SetFaceIndex(0);
for(auto i : Range(mparam.optsteps2d))
for(auto k : Range(mesh.GetNFD()))
{
PrintMessage(3, "Optimization step ", i);
meshopt.SetFaceIndex(k+1);
int innerstep = 0;
for(auto optstep : mparam.optimize2d)
{

View File

@ -18,6 +18,27 @@ namespace netgen
{ tnr = atnr; sidenr = asidenr; }
};
// check if element is quad with at least one surface point -> relevant for optimization
// (quads with 4 edge points are not optimized and can be ignored)
bool checkMixedElement(const Mesh & mesh, FlatArray<SurfaceElementIndex> seia)
{
bool mixed = false;
ParallelForRange( Range(seia), [&] (auto myrange) NETGEN_LAMBDA_INLINE
{
for (SurfaceElementIndex i : myrange)
{
const auto & sel = mesh[i];
if(sel.GetNP() == 3)
continue;
for(auto i : Range(sel.GetNP()))
if(mesh[sel[i]].Type() == SURFACEPOINT)
mixed = true;
}
});
return mixed;
}
bool MeshOptimize2d :: EdgeSwapping (const int usemetric,
Array<Neighbour> &neighbors,
@ -181,35 +202,14 @@ namespace netgen
timerstart.Start();
Array<SurfaceElementIndex> seia;
bool mixed = false;
mesh.GetSurfaceElementsOfFace (faceindex, seia);
if(faceindex==0)
{
seia.SetSize(mesh.GetNSE());
ParallelFor( Range(seia), [&] (auto i) NETGEN_LAMBDA_INLINE
{
SurfaceElementIndex sei(i);
seia[i] = sei;
if (mesh[sei].GetNP() != 3)
{
const auto & sel = mesh[sei];
for(auto i : Range(sel.GetNP()))
if(mesh[sel[i]].Type() == INNERPOINT)
mixed = true;
}
});
}
else
{
mesh.GetSurfaceElementsOfFace (faceindex, seia);
for (SurfaceElementIndex sei : seia)
if (mesh[sei].GetNP() != 3)
mixed = true;
}
if(mixed)
if(checkMixedElement(mesh, seia))
{
timerstart.Stop();
return GenericImprove();
}
Array<Neighbour> neighbors(mesh.GetNSE());
auto elements_on_node = mesh.CreatePoint2SurfaceElementTable(faceindex);
@ -595,25 +595,14 @@ namespace netgen
Array<SurfaceElementIndex> seia;
mesh.GetSurfaceElementsOfFace (faceindex, seia);
if(faceindex)
mesh.GetSurfaceElementsOfFace (faceindex, seia);
else
{
seia.SetSize(mesh.GetNSE());
ParallelFor( IntRange(mesh.GetNSE()), [&seia] (auto i) NETGEN_LAMBDA_INLINE
{ seia[i] = i; });
}
bool mixed = false;
ParallelFor( Range(seia), [&] (auto i) NETGEN_LAMBDA_INLINE
{
if (mesh[seia[i]].GetNP() != 3)
mixed = true;
});
if(mixed)
if(checkMixedElement(mesh, seia))
{
timerstart1.Stop();
timerstart.Stop();
return;
}
int np = mesh.GetNP();
@ -625,18 +614,8 @@ namespace netgen
BuildEdgeList( mesh, elementsonnode, edges );
Array<bool,PointIndex> fixed(np);
ParallelFor( fixed.Range(), [&fixed] (auto i) NETGEN_LAMBDA_INLINE
{ fixed[i] = false; });
ParallelFor( edges.Range(), [&] (auto i) NETGEN_LAMBDA_INLINE
{
auto [pi0, pi1] = edges[i];
if (mesh.IsSegment (pi0, pi1))
{
fixed[pi0] = true;
fixed[pi1] = true;
}
});
ParallelFor( fixed.Range(), [&] (auto i) NETGEN_LAMBDA_INLINE
{ fixed[i] = mesh[i].Type() != SURFACEPOINT; });
timerstart1.Stop();

View File

@ -6412,25 +6412,17 @@ namespace netgen
static int timer = NgProfiler::CreateTimer ("GetSurfaceElementsOfFace");
NgProfiler::RegionTimer reg (timer);
/*
sei.SetSize (0);
for (SurfaceElementIndex i = 0; i < GetNSE(); i++)
{
if ( (*this)[i].GetIndex () == facenr && (*this)[i][0] >= PointIndex::BASE &&
!(*this)[i].IsDeleted() )
{
sei.Append (i);
}
}
*/
if(facenr==0)
{
sei.SetSize(GetNSE());
ParallelForRange( IntRange(GetNSE()), [&sei] (auto myrange)
{
for(auto i : myrange)
sei[i] = i;
});
return;
}
/* Philippose - 01/10/2009
Commented out the following lines, and activated the originally
commented out lines above because of a bug which causes corruption
of the variable "facedecoding" when a mesh is converted to second order
*/
// int size1 = sei.Size();
sei.SetSize(0);
SurfaceElementIndex si = facedecoding[facenr-1].firstelement;
@ -6444,16 +6436,6 @@ namespace netgen
si = (*this)[si].next;
}
/*
// *testout << "with list = " << endl << sei << endl;
if (size1 != sei.Size())
{
cout << "size mismatch" << endl;
exit(1);
}
*/
}