Separate function to perform SwapImprove2 on one face of an element

This commit is contained in:
Matthias Hochsteger 2019-09-06 15:26:10 +02:00
parent 728196472e
commit d0586a6366
2 changed files with 166 additions and 165 deletions

View File

@ -2632,6 +2632,170 @@ void MeshOptimize3d :: SwapImproveSurface (Mesh & mesh, OPTIMIZEGOAL goal,
2 -> 3 conversion
*/
bool MeshOptimize3d :: SwapImprove2 ( Mesh & mesh, OPTIMIZEGOAL goal, ElementIndex eli1, int face,
TABLE<ElementIndex, PointIndex::BASE> & elementsonnode,
TABLE<SurfaceElementIndex, PointIndex::BASE> & belementsonnode, bool check_only )
{
PointIndex pi1, pi2, pi3, pi4, pi5;
Element el21(TET), el22(TET), el31(TET), el32(TET), el33(TET);
int j = face;
double bad1, bad2;
Element & elem = mesh[eli1];
if (elem.IsDeleted()) return false;
int mattyp = elem.GetIndex();
switch (j)
{
case 0:
pi1 = elem.PNum(1); pi2 = elem.PNum(2);
pi3 = elem.PNum(3); pi4 = elem.PNum(4);
break;
case 1:
pi1 = elem.PNum(1); pi2 = elem.PNum(4);
pi3 = elem.PNum(2); pi4 = elem.PNum(3);
break;
case 2:
pi1 = elem.PNum(1); pi2 = elem.PNum(3);
pi3 = elem.PNum(4); pi4 = elem.PNum(2);
break;
case 3:
pi1 = elem.PNum(2); pi2 = elem.PNum(4);
pi3 = elem.PNum(3); pi4 = elem.PNum(1);
break;
}
bool bface = 0;
for (int k = 0; k < belementsonnode[pi1].Size(); k++)
{
const Element2d & bel =
mesh[belementsonnode[pi1][k]];
bool bface1 = 1;
for (int l = 0; l < 3; l++)
if (bel[l] != pi1 && bel[l] != pi2 && bel[l] != pi3)
{
bface1 = 0;
break;
}
if (bface1)
{
bface = 1;
break;
}
}
if (bface) return false;
NgFlatArray<ElementIndex> row = elementsonnode[pi1];
for (int k = 0; k < row.Size(); k++)
{
ElementIndex eli2 = row[k];
if ( eli1 != eli2 )
{
Element & elem2 = mesh[eli2];
if (elem2.IsDeleted()) continue;
if (elem2.GetType() != TET)
continue;
int comnodes=0;
for (int l = 1; l <= 4; l++)
if (elem2.PNum(l) == pi1 || elem2.PNum(l) == pi2 ||
elem2.PNum(l) == pi3)
{
comnodes++;
}
else
{
pi5 = elem2.PNum(l);
}
if (comnodes == 3)
{
bad1 = CalcBad (mesh.Points(), elem, 0) +
CalcBad (mesh.Points(), elem2, 0);
if (!mesh.LegalTet(elem) ||
!mesh.LegalTet(elem2))
bad1 += 1e4;
el31.PNum(1) = pi1;
el31.PNum(2) = pi2;
el31.PNum(3) = pi5;
el31.PNum(4) = pi4;
el31.SetIndex (mattyp);
el32.PNum(1) = pi2;
el32.PNum(2) = pi3;
el32.PNum(3) = pi5;
el32.PNum(4) = pi4;
el32.SetIndex (mattyp);
el33.PNum(1) = pi3;
el33.PNum(2) = pi1;
el33.PNum(3) = pi5;
el33.PNum(4) = pi4;
el33.SetIndex (mattyp);
bad2 = CalcBad (mesh.Points(), el31, 0) +
CalcBad (mesh.Points(), el32, 0) +
CalcBad (mesh.Points(), el33, 0);
el31.flags.illegal_valid = 0;
el32.flags.illegal_valid = 0;
el33.flags.illegal_valid = 0;
if (!mesh.LegalTet(el31) ||
!mesh.LegalTet(el32) ||
!mesh.LegalTet(el33))
bad2 += 1e4;
bool do_swap = (bad2 < bad1);
if ( ((bad2 < 1e6) || (bad2 < 10 * bad1)) &&
mesh.BoundaryEdge (pi4, pi5))
do_swap = 1;
if (!check_only && do_swap)
{
el31.flags.illegal_valid = 0;
el32.flags.illegal_valid = 0;
el33.flags.illegal_valid = 0;
mesh[eli1] = el31;
mesh[eli2] = el32;
ElementIndex neli =
mesh.AddVolumeElement (el33);
for (int l = 0; l < 4; l++)
{
elementsonnode.Add (el31[l], eli1);
elementsonnode.Add (el32[l], eli2);
elementsonnode.Add (el33[l], neli);
}
}
return do_swap;
}
}
}
return false;
}
/*
2 -> 3 conversion
*/
void MeshOptimize3d :: SwapImprove2 (Mesh & mesh, OPTIMIZEGOAL goal)
{
@ -2710,171 +2874,7 @@ void MeshOptimize3d :: SwapImprove2 (Mesh & mesh, OPTIMIZEGOAL goal)
for (int j = 0; j < 4; j++)
{
// loop over faces
Element & elem = mesh[eli1];
// if (elem[0] < PointIndex::BASE) continue;
if (elem.IsDeleted()) continue;
int mattyp = elem.GetIndex();
switch (j)
{
case 0:
pi1 = elem.PNum(1); pi2 = elem.PNum(2);
pi3 = elem.PNum(3); pi4 = elem.PNum(4);
break;
case 1:
pi1 = elem.PNum(1); pi2 = elem.PNum(4);
pi3 = elem.PNum(2); pi4 = elem.PNum(3);
break;
case 2:
pi1 = elem.PNum(1); pi2 = elem.PNum(3);
pi3 = elem.PNum(4); pi4 = elem.PNum(2);
break;
case 3:
pi1 = elem.PNum(2); pi2 = elem.PNum(4);
pi3 = elem.PNum(3); pi4 = elem.PNum(1);
break;
}
bool bface = 0;
for (int k = 0; k < belementsonnode[pi1].Size(); k++)
{
const Element2d & bel =
mesh[belementsonnode[pi1][k]];
bool bface1 = 1;
for (int l = 0; l < 3; l++)
if (bel[l] != pi1 && bel[l] != pi2 && bel[l] != pi3)
{
bface1 = 0;
break;
}
if (bface1)
{
bface = 1;
break;
}
}
if (bface) continue;
NgFlatArray<ElementIndex> row = elementsonnode[pi1];
for (int k = 0; k < row.Size(); k++)
{
ElementIndex eli2 = row[k];
// cout << "\rei1 = " << eli1 << ", pi1 = " << pi1 << ", k = " << k << ", ei2 = " << eli2
// << ", getne = " << mesh.GetNE();
if ( eli1 != eli2 )
{
Element & elem2 = mesh[eli2];
if (elem2.IsDeleted()) continue;
if (elem2.GetType() != TET)
continue;
int comnodes=0;
for (int l = 1; l <= 4; l++)
if (elem2.PNum(l) == pi1 || elem2.PNum(l) == pi2 ||
elem2.PNum(l) == pi3)
{
comnodes++;
}
else
{
pi5 = elem2.PNum(l);
}
if (comnodes == 3)
{
bad1 = CalcBad (mesh.Points(), elem, 0) +
CalcBad (mesh.Points(), elem2, 0);
if (!mesh.LegalTet(elem) ||
!mesh.LegalTet(elem2))
bad1 += 1e4;
el31.PNum(1) = pi1;
el31.PNum(2) = pi2;
el31.PNum(3) = pi5;
el31.PNum(4) = pi4;
el31.SetIndex (mattyp);
el32.PNum(1) = pi2;
el32.PNum(2) = pi3;
el32.PNum(3) = pi5;
el32.PNum(4) = pi4;
el32.SetIndex (mattyp);
el33.PNum(1) = pi3;
el33.PNum(2) = pi1;
el33.PNum(3) = pi5;
el33.PNum(4) = pi4;
el33.SetIndex (mattyp);
bad2 = CalcBad (mesh.Points(), el31, 0) +
CalcBad (mesh.Points(), el32, 0) +
CalcBad (mesh.Points(), el33, 0);
el31.flags.illegal_valid = 0;
el32.flags.illegal_valid = 0;
el33.flags.illegal_valid = 0;
if (!mesh.LegalTet(el31) ||
!mesh.LegalTet(el32) ||
!mesh.LegalTet(el33))
bad2 += 1e4;
bool do_swap = (bad2 < bad1);
if ( ((bad2 < 1e6) || (bad2 < 10 * bad1)) &&
mesh.BoundaryEdge (pi4, pi5))
do_swap = 1;
if (do_swap)
{
// cout << "do swap, eli1 = " << eli1 << "; eli2 = " << eli2 << endl;
// (*mycout) << "2->3 " << flush;
cnt++;
el31.flags.illegal_valid = 0;
el32.flags.illegal_valid = 0;
el33.flags.illegal_valid = 0;
mesh[eli1] = el31;
mesh[eli2] = el32;
ElementIndex neli =
mesh.AddVolumeElement (el33);
/*
if (!LegalTet(el31) || !LegalTet(el32) ||
!LegalTet(el33))
{
cout << "Swap to illegal tets !!!" << endl;
}
*/
// cout << "neli = " << neli << endl;
for (int l = 0; l < 4; l++)
{
elementsonnode.Add (el31[l], eli1);
elementsonnode.Add (el32[l], eli2);
elementsonnode.Add (el33[l], neli);
}
break;
}
}
}
}
cnt += SwapImprove2( mesh, goal, eli1, j, elementsonnode, belementsonnode, false);
}
}

View File

@ -29,6 +29,7 @@ public:
const NgBitArray * working_elements = NULL,
const NgArray< NgArray<int,PointIndex::BASE>* > * idmaps = NULL);
void SwapImprove2 (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY);
bool SwapImprove2 ( Mesh & mesh, OPTIMIZEGOAL goal, ElementIndex eli1, int face, TABLE<ElementIndex, PointIndex::BASE> & elementsonnode, TABLE<SurfaceElementIndex, PointIndex::BASE> & belementsonnode, bool check_only=false );
double
CalcBad (const Mesh::T_POINTS & points, const Element & elem, double h)