mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
BUG: snappyHexMesh: trying to extrude non-manifold patches fails.
The typical topology is the one where boundary faces share non-consecutive points (checkMesh reports this as 'Number of faces with non-consecutive shared points') This is handled by no-extruding any of the vertices of both faces. Fixes #391.
This commit is contained in:
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
\\/ M anipulation | Copyright (C) 2015-2017 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -495,13 +495,18 @@ void Foam::addPatchCellLayer::setFaceProps
|
|||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
//FatalErrorInFunction
|
||||||
|
WarningInFunction
|
||||||
<< "Problem: cannot find patch edge " << ppEdgeI
|
<< "Problem: cannot find patch edge " << ppEdgeI
|
||||||
<< " with mesh vertices " << patchEdge
|
<< " with mesh vertices " << patchEdge
|
||||||
<< " at " << patchEdge.line(mesh.points())
|
<< " at " << patchEdge.line(mesh.points())
|
||||||
<< " is not in face " << faceI << " with mesh vertices "
|
<< " in face " << faceI << " with mesh vertices "
|
||||||
<< f
|
<< f
|
||||||
<< exit(FatalError);
|
<< " at " << pointField(mesh.points(), f)
|
||||||
|
<< endl
|
||||||
|
<< "Continuing with potentially incorrect faceZone orientation"
|
||||||
|
//<< exit(FatalError);
|
||||||
|
<< endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||||
\\/ M anipulation | Copyright (C) 2015-2016 OpenCFD Ltd.
|
\\/ M anipulation | Copyright (C) 2015-2017 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -272,6 +272,267 @@ bool Foam::snappyLayerDriver::unmarkExtrusion
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::snappyLayerDriver::constrainFp(const label sz, const label fp)
|
||||||
|
{
|
||||||
|
if (fp >= sz)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (fp < 0)
|
||||||
|
{
|
||||||
|
return sz-1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::snappyLayerDriver::countCommonPoints
|
||||||
|
(
|
||||||
|
const indirectPrimitivePatch& pp,
|
||||||
|
const label facei,
|
||||||
|
|
||||||
|
Map<label>& nCommonPoints
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const faceList& localFaces = pp.localFaces();
|
||||||
|
const labelListList& pointFaces = pp.pointFaces();
|
||||||
|
|
||||||
|
const face& f = localFaces[facei];
|
||||||
|
|
||||||
|
nCommonPoints.clear();
|
||||||
|
|
||||||
|
forAll(f, fp)
|
||||||
|
{
|
||||||
|
label pointi = f[fp];
|
||||||
|
const labelList& pFaces = pointFaces[pointi];
|
||||||
|
|
||||||
|
forAll(pFaces, pFacei)
|
||||||
|
{
|
||||||
|
label nbFacei = pFaces[pFacei];
|
||||||
|
|
||||||
|
if (facei < nbFacei)
|
||||||
|
{
|
||||||
|
// Only check once for each combination of two faces.
|
||||||
|
|
||||||
|
Map<label>::iterator fnd = nCommonPoints.find(nbFacei);
|
||||||
|
|
||||||
|
if (fnd == nCommonPoints.end())
|
||||||
|
{
|
||||||
|
// First common vertex found.
|
||||||
|
nCommonPoints.insert(nbFacei, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fnd()++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::snappyLayerDriver::checkCommonOrder
|
||||||
|
(
|
||||||
|
const label nCommon,
|
||||||
|
const face& curFace,
|
||||||
|
const face& nbFace
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
forAll(curFace, fp)
|
||||||
|
{
|
||||||
|
// Get the index in the neighbouring face shared with curFace
|
||||||
|
const label nb = findIndex(nbFace, curFace[fp]);
|
||||||
|
|
||||||
|
if (nb != -1)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Check the whole face from nb onwards for shared vertices
|
||||||
|
// with neighbouring face. Rule is that any shared vertices
|
||||||
|
// should be consecutive on both faces i.e. if they are
|
||||||
|
// vertices fp,fp+1,fp+2 on one face they should be
|
||||||
|
// vertices nb, nb+1, nb+2 (or nb+2, nb+1, nb) on the
|
||||||
|
// other face.
|
||||||
|
|
||||||
|
|
||||||
|
// Vertices before and after on curFace
|
||||||
|
label fpPlus1 = curFace.fcIndex(fp);
|
||||||
|
label fpMin1 = curFace.rcIndex(fp);
|
||||||
|
|
||||||
|
// Vertices before and after on nbFace
|
||||||
|
label nbPlus1 = nbFace.fcIndex(nb);
|
||||||
|
label nbMin1 = nbFace.rcIndex(nb);
|
||||||
|
|
||||||
|
// Find order of walking by comparing next points on both
|
||||||
|
// faces.
|
||||||
|
label curInc = labelMax;
|
||||||
|
label nbInc = labelMax;
|
||||||
|
|
||||||
|
if (nbFace[nbPlus1] == curFace[fpPlus1])
|
||||||
|
{
|
||||||
|
curInc = 1;
|
||||||
|
nbInc = 1;
|
||||||
|
}
|
||||||
|
else if (nbFace[nbPlus1] == curFace[fpMin1])
|
||||||
|
{
|
||||||
|
curInc = -1;
|
||||||
|
nbInc = 1;
|
||||||
|
}
|
||||||
|
else if (nbFace[nbMin1] == curFace[fpMin1])
|
||||||
|
{
|
||||||
|
curInc = -1;
|
||||||
|
nbInc = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
curInc = 1;
|
||||||
|
nbInc = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Pass1: loop until start of common vertices found.
|
||||||
|
label curNb = nb;
|
||||||
|
label curFp = fp;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
curFp = constrainFp(curFace.size(), curFp+curInc);
|
||||||
|
curNb = constrainFp(nbFace.size(), curNb+nbInc);
|
||||||
|
} while (curFace[curFp] == nbFace[curNb]);
|
||||||
|
|
||||||
|
// Pass2: check equality walking from curFp, curNb
|
||||||
|
// in opposite order.
|
||||||
|
|
||||||
|
curInc = -curInc;
|
||||||
|
nbInc = -nbInc;
|
||||||
|
|
||||||
|
for (label commonI = 0; commonI < nCommon; commonI++)
|
||||||
|
{
|
||||||
|
curFp = constrainFp(curFace.size(), curFp+curInc);
|
||||||
|
curNb = constrainFp(nbFace.size(), curNb+nbInc);
|
||||||
|
|
||||||
|
if (curFace[curFp] != nbFace[curNb])
|
||||||
|
{
|
||||||
|
// Error: gap in string of connected vertices
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done the curFace - nbFace combination.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::snappyLayerDriver::checkCommonOrder
|
||||||
|
(
|
||||||
|
const indirectPrimitivePatch& pp,
|
||||||
|
const label facei,
|
||||||
|
const Map<label>& nCommonPoints,
|
||||||
|
pointField& patchDisp,
|
||||||
|
labelList& patchNLayers,
|
||||||
|
List<extrudeMode>& extrudeStatus
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
forAllConstIter(Map<label>, nCommonPoints, iter)
|
||||||
|
{
|
||||||
|
label nbFacei = iter.key();
|
||||||
|
label nCommon = iter();
|
||||||
|
|
||||||
|
const face& curFace = pp[facei];
|
||||||
|
const face& nbFace = pp[nbFacei];
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
nCommon >= 2
|
||||||
|
&& nCommon != nbFace.size()
|
||||||
|
&& nCommon != curFace.size()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
bool stringOk = checkCommonOrder(nCommon, curFace, nbFace);
|
||||||
|
|
||||||
|
if (!stringOk)
|
||||||
|
{
|
||||||
|
// Note: unmark whole face or just the common points?
|
||||||
|
// For now unmark the whole face
|
||||||
|
unmarkExtrusion
|
||||||
|
(
|
||||||
|
pp.localFaces()[facei],
|
||||||
|
patchDisp,
|
||||||
|
patchNLayers,
|
||||||
|
extrudeStatus
|
||||||
|
);
|
||||||
|
unmarkExtrusion
|
||||||
|
(
|
||||||
|
pp.localFaces()[nbFacei],
|
||||||
|
patchDisp,
|
||||||
|
patchNLayers,
|
||||||
|
extrudeStatus
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::snappyLayerDriver::handleNonStringConnected
|
||||||
|
(
|
||||||
|
const indirectPrimitivePatch& pp,
|
||||||
|
pointField& patchDisp,
|
||||||
|
labelList& patchNLayers,
|
||||||
|
List<extrudeMode>& extrudeStatus
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Detect faces which are connected on non-consecutive vertices.
|
||||||
|
// This is the "<<Number of faces with non-consecutive shared points"
|
||||||
|
// warning from checkMesh. These faces cannot be extruded so
|
||||||
|
// there is no need to even attempt it.
|
||||||
|
|
||||||
|
List<extrudeMode> oldExtrudeStatus(extrudeStatus);
|
||||||
|
OBJstream str(meshRefiner_.mesh().time().path()/"nonStringConnected.obj");
|
||||||
|
Pout<< "Dumping string edges to " << str.name();
|
||||||
|
|
||||||
|
// 1) Local
|
||||||
|
Map<label> nCommonPoints(100);
|
||||||
|
|
||||||
|
forAll(pp, facei)
|
||||||
|
{
|
||||||
|
countCommonPoints(pp, facei, nCommonPoints);
|
||||||
|
|
||||||
|
// Faces share pointi. Find any more shared points
|
||||||
|
// and if not in single string unmark all. See
|
||||||
|
// primitiveMesh::checkCommonOrder
|
||||||
|
checkCommonOrder
|
||||||
|
(
|
||||||
|
pp,
|
||||||
|
facei,
|
||||||
|
nCommonPoints,
|
||||||
|
|
||||||
|
patchDisp,
|
||||||
|
patchNLayers,
|
||||||
|
extrudeStatus
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) TDB. Other face remote
|
||||||
|
|
||||||
|
forAll(extrudeStatus, pointi)
|
||||||
|
{
|
||||||
|
if (extrudeStatus[pointi] != oldExtrudeStatus[pointi])
|
||||||
|
{
|
||||||
|
str.write(meshRefiner_.mesh().points()[pp.meshPoints()[pointi]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// No extrusion at non-manifold points.
|
// No extrusion at non-manifold points.
|
||||||
void Foam::snappyLayerDriver::handleNonManifolds
|
void Foam::snappyLayerDriver::handleNonManifolds
|
||||||
(
|
(
|
||||||
@ -3333,6 +3594,19 @@ void Foam::snappyLayerDriver::addLayers
|
|||||||
// Precalculate mesh edge labels for patch edges
|
// Precalculate mesh edge labels for patch edges
|
||||||
labelList meshEdges(pp().meshEdges(mesh.edges(), mesh.pointEdges()));
|
labelList meshEdges(pp().meshEdges(mesh.edges(), mesh.pointEdges()));
|
||||||
|
|
||||||
|
|
||||||
|
// Disable extrusion on split strings of common points
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
handleNonStringConnected
|
||||||
|
(
|
||||||
|
pp,
|
||||||
|
patchDisp,
|
||||||
|
patchNLayers,
|
||||||
|
extrudeStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Disable extrusion on non-manifold points
|
// Disable extrusion on non-manifold points
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user