ENH: cvMesh: detect and remove indirect patch faces

Find patch faces that do not result from point pairs and aggressively delete
This commit is contained in:
laurence
2013-01-04 14:33:23 +00:00
parent 45ce8ab68d
commit d722378fc4
10 changed files with 375 additions and 98 deletions

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -70,6 +70,12 @@ int main(int argc, char *argv[])
"Collapse small and sliver faces as well as small edges"
);
argList::addBoolOption
(
"collapseIndirectPatchFaces",
"Collapse faces that are in the face zone indirectPatchFaces"
);
# include "addOverwriteOption.H"
# include "setRootCase.H"
# include "createTime.H"
@ -84,6 +90,8 @@ int main(int argc, char *argv[])
const bool overwrite = args.optionFound("overwrite");
const bool collapseFaces = args.optionFound("collapseFaces");
const bool collapseIndirectPatchFaces =
args.optionFound("collapseIndirectPatchFaces");
forAll(timeDirs, timeI)
{
@ -105,6 +113,18 @@ int main(int argc, char *argv[])
meshMod.changeMesh(mesh, false);
}
if (collapseIndirectPatchFaces)
{
// Filter faces. Pass in the number of bad faces that are present
// from the previous edge filtering to use as a stopping criterion.
meshFilter.filterIndirectPatchFaces();
{
polyTopoChange meshMod(newMesh);
meshMod.changeMesh(mesh, false);
}
}
if (collapseFaces)
{
// Filter faces. Pass in the number of bad faces that are present

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -73,11 +73,7 @@ void Foam::PrintTable<KeyType, DataType>::print
{
HashTable<HashTable<DataType, label>, KeyType> combinedTable;
List<HashTable<DataType, KeyType> > procData
(
Pstream::nProcs(),
HashTable<DataType, KeyType>()
);
List<HashTableData> procData(Pstream::nProcs(), HashTableData());
procData[Pstream::myProcNo()] = table_;
@ -92,13 +88,11 @@ void Foam::PrintTable<KeyType, DataType>::print
forAll(procData, procI)
{
const HashTable<DataType, KeyType>& procIData
= procData[procI];
const HashTableData& procIData = procData[procI];
for
(
typename HashTable<DataType, KeyType>
::const_iterator iter = procIData.begin();
typename HashTableData::const_iterator iter = procIData.begin();
iter != procIData.end();
++iter
)
@ -112,8 +106,7 @@ void Foam::PrintTable<KeyType, DataType>::print
);
}
HashTable<DataType, label>& key
= combinedTable[iter.key()];
HashTable<DataType, label>& key = combinedTable[iter.key()];
key.insert(procI, iter());

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -68,10 +68,13 @@ namespace Foam
template<class KeyType, class DataType>
class PrintTable
{
typedef HashTable<DataType, KeyType> HashTableData;
// Private data
//- Hash table holding the data
HashTable<DataType, KeyType> table_;
HashTableData table_;
//- Title of the table
string title_;

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -1191,6 +1191,36 @@ void Foam::conformalVoronoiMesh::writeMesh
}
}
// Add indirectPatchFaces to a face zone
{
labelList addr(boundaryFacesToRemove.count());
label count = 0;
forAll(boundaryFacesToRemove, faceI)
{
if (boundaryFacesToRemove[faceI])
{
addr[count++] = faceI;
}
}
label sz = mesh.faceZones().size();
boolList flip(addr.size(), false);
mesh.faceZones().setSize(sz + 1);
mesh.faceZones().set
(
sz,
new faceZone
(
"indirectPatchFaces",
addr,
flip,
sz,
mesh.faceZones()
)
);
}
patches.setSize(nValidPatches);
mesh.addFvPatches(patches);

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -1086,6 +1086,106 @@ Foam::label Foam::polyMeshFilter::filterEdges
}
Foam::label Foam::polyMeshFilter::filterIndirectPatchFaces()
{
newMeshPtr_ = copyMesh(mesh_);
fvMesh& newMesh = newMeshPtr_();
label nIterations = 0;
label nBadFaces = 0;
while (true)
{
Info<< nl << indent << "Iteration = "
<< nIterations++ << nl << incrIndent << endl;
// Per edge collapse status
PackedBoolList collapseEdge(newMesh.nEdges());
Map<point> collapsePointToLocation(newMesh.nPoints());
labelList boundaryPoint(newMesh.nPoints());
edgeCollapser collapser(newMesh, collapseFacesCoeffDict_);
collapser.markIndirectPatchFaces
(
collapseEdge,
collapsePointToLocation
);
// Merge edge collapses into consistent collapse-network.
// Make sure no cells get collapsed.
List<pointEdgeCollapse> allPointInfo;
const globalIndex globalPoints(newMesh.nPoints());
collapser.consistentCollapse
(
globalPoints,
boundaryPoint,
collapsePointToLocation,
collapseEdge,
allPointInfo
);
label nLocalCollapse = collapseEdge.count();
reduce(nLocalCollapse, sumOp<label>());
Info<< nl << indent << "Collapsing " << nLocalCollapse
<< " edges after synchronisation and PointEdgeWave" << endl;
if (nLocalCollapse == 0)
{
break;
}
// Apply collapses to current mesh
polyTopoChange newMeshMod(newMesh);
// Insert mesh refinement into polyTopoChange.
collapser.setRefinement(allPointInfo, newMeshMod);
Info<< indent << "Apply changes to the current mesh"
<< decrIndent << endl;
// Apply changes to current mesh
autoPtr<mapPolyMesh> newMapPtr = newMeshMod.changeMesh
(
newMesh,
false
);
const mapPolyMesh& newMap = newMapPtr();
// Update fields
newMesh.updateMesh(newMap);
if (newMap.hasMotionPoints())
{
newMesh.movePoints(newMap.preMotionPoints());
}
// Mesh check
// ~~~~~~~~~~~~~~~~~~
// Do not allow collapses in regions of error.
// Updates minEdgeLen, nRelaxedEdges
PackedBoolList isErrorPoint(newMesh.nPoints());
nBadFaces = edgeCollapser::checkMeshQuality
(
newMesh,
meshQualityCoeffDict_,
isErrorPoint
);
Info<< nl << " Number of bad faces : " << nBadFaces << nl
<< " Number of marked points : "
<< returnReduce(isErrorPoint.count(), sumOp<unsigned int>())
<< endl;
}
return nBadFaces;
}
const Foam::autoPtr<Foam::fvMesh>& Foam::polyMeshFilter::filteredMesh() const
{
return newMeshPtr_;

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -224,6 +224,8 @@ public:
//- Filter edges only.
label filterEdges(const label nOriginalBadFaces);
label filterIndirectPatchFaces();
};

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -803,11 +803,7 @@ void Foam::edgeCollapser::checkBoundaryPointMergeEdges
{
const pointField& points = mesh_.points();
if
(
pointPriority[pointI] == 0
&& pointPriority[otherPointI] < 0
)
if (pointPriority[pointI] >= 0 && pointPriority[otherPointI] < 0)
{
collapsePointToLocation.set
(
@ -1254,6 +1250,44 @@ bool Foam::edgeCollapser::setRefinement
const labelListList& pointFaces = mesh_.pointFaces();
const pointZoneMesh& pointZones = mesh_.pointZones();
// // Dump point collapses
// label count = 0;
// forAll(allPointInfo, ptI)
// {
// const pointEdgeCollapse& pec = allPointInfo[ptI];
//
// if (mesh_.points()[ptI] != pec.collapsePoint())
// {
// count++;
// }
// }
//
// OFstream str("collapses_" + name(count) + ".obj");
// // Dump point collapses
// forAll(allPointInfo, ptI)
// {
// const pointEdgeCollapse& pec = allPointInfo[ptI];
//
// if
// (
// mesh_.points()[ptI] != pec.collapsePoint()
// && pec.collapsePoint() != vector(GREAT, GREAT, GREAT)
// )
// {
// meshTools::writeOBJ
// (
// str,
// mesh_.points()[ptI],
// pec.collapsePoint()
// );
// }
// }
bool meshChanged = false;
PackedBoolList removedPoints(mesh_.nPoints());
@ -1301,6 +1335,29 @@ bool Foam::edgeCollapser::setRefinement
}
}
// OFstream str2("collapseStrings_" + name(count) + ".obj");
// // Dump point collapses
// forAllConstIter(Map<DynamicList<label> >, collapseStrings, iter)
// {
// const label masterPoint = iter.key();
// const DynamicList<label>& edgeCollapses = iter();
//
// forAll(edgeCollapses, eI)
// {
// meshTools::writeOBJ
// (
// str2,
// mesh_.points()[edgeCollapses[eI]],
// mesh_.points()[masterPoint]
// );
// }
// }
// Current faces (is also collapseStatus: f.size() < 3)
faceList newFaces(mesh_.faces());
@ -1346,7 +1403,6 @@ bool Foam::edgeCollapser::setRefinement
do
{
// Update face collapse from edge collapses
forAll(newFaces, faceI)
{
filterFace(collapseStrings, allPointInfo, newFaces[faceI]);
@ -1857,68 +1913,29 @@ Foam::label Foam::edgeCollapser::markMergeEdges
if (e0length <= e1length)
{
if (edges[e0].start() == pointI)
{
collapseEdge[e0] = true;
collapseEdge[e0] = true;
checkBoundaryPointMergeEdges
(
pointI,
edges[e0].end(),
pointPriority,
collapsePointToLocation
);
}
else
{
collapseEdge[e0] = true;
checkBoundaryPointMergeEdges
(
pointI,
edges[e0].start(),
pointPriority,
collapsePointToLocation
);
}
checkBoundaryPointMergeEdges
(
pointI,
edges[e0].otherVertex(pointI),
pointPriority,
collapsePointToLocation
);
}
else
{
if (edges[e1].start() == pointI)
{
collapseEdge[e1] = true;
collapseEdge[e1] = true;
checkBoundaryPointMergeEdges
(
pointI,
edges[e1].end(),
pointPriority,
collapsePointToLocation
);
}
else
{
collapseEdge[e1] = true;
checkBoundaryPointMergeEdges
(
pointI,
edges[e1].start(),
pointPriority,
collapsePointToLocation
);
}
checkBoundaryPointMergeEdges
(
pointI,
edges[e1].otherVertex(pointI),
pointPriority,
collapsePointToLocation
);
}
// if (boundaryPoint[leftV] == -1)
// {
// collapseEdge[e0] = findIndex(edges[e0], leftV);
// }
// else
// {
// collapseEdge[e1] = findIndex(edges[e1], rightV);
// }
nCollapsed++;
}
}
@ -1991,4 +2008,117 @@ Foam::labelPair Foam::edgeCollapser::markSmallSliverFaces
}
void Foam::edgeCollapser::markIndirectPatchFaces
(
PackedBoolList& collapseEdge,
Map<point>& collapsePointToLocation
) const
{
const faceZone& indirectFaceZone = mesh_.faceZones()["indirectPatchFaces"];
const edgeList& edges = mesh_.edges();
const pointField& points = mesh_.points();
const labelListList& edgeFaces = mesh_.edgeFaces();
const polyBoundaryMesh& bMesh = mesh_.boundaryMesh();
forAll(edges, eI)
{
const edge& e = edges[eI];
const labelList& eFaces = edgeFaces[eI];
bool keepEdge = false;
label nInternalFaces = 0;
label nPatchFaces = 0;
label nIndirectFaces = 0;
bool coupled = false;
forAll(eFaces, eFaceI)
{
const label eFaceIndex = eFaces[eFaceI];
if (mesh_.isInternalFace(eFaceIndex))
{
nInternalFaces++;
}
else
{
const label patchIndex = bMesh.whichPatch(eFaceIndex);
const polyPatch& pPatch = bMesh[patchIndex];
if (pPatch.coupled())
{
coupled = true;
nInternalFaces++;
}
else
{
// Keep the edge if an attached face is not in the face zone
if (indirectFaceZone.whichFace(eFaceIndex) == -1)
{
nPatchFaces++;
}
else
{
nIndirectFaces++;
}
}
}
}
if (eFaces.size() != nInternalFaces + nPatchFaces + nIndirectFaces)
{
Pout<< eFaces.size() << " ("
<< nInternalFaces << "/" << nPatchFaces << "/" << nIndirectFaces
<< ")" << endl;
}
if
(
eFaces.size() == nInternalFaces
|| nIndirectFaces < (coupled ? 1 : 2)
)
{
keepEdge = true;
}
if (!keepEdge)
{
collapseEdge[eI] = true;
const Foam::point collapsePoint =
0.5*(points[e.end()] + points[e.start()]);
collapsePointToLocation.insert(e.start(), collapsePoint);
collapsePointToLocation.insert(e.end(), collapsePoint);
}
}
// OFstream str
// (
// mesh_.time().path()
// /"markedEdges_" + name(collapseEdge.count()) + ".obj"
// );
// label count = 0;
//
// forAll(collapseEdge, eI)
// {
// if (collapseEdge[eI])
// {
// const edge& e = edges[eI];
//
// meshTools::writeOBJ
// (
// str,
// points[e.start()],
// points[e.end()],
// count
// );
// }
// }
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -331,6 +331,12 @@ public:
PackedBoolList& collapseEdge,
Map<point>& collapsePointToLocation
) const;
void markIndirectPatchFaces
(
PackedBoolList& collapseEdge,
Map<point>& collapsePointToLocation
) const;
};

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -75,8 +75,7 @@ inline bool Foam::pointEdgeCollapse::update
{
bool identicalPoint = samePoint(w2.collapsePoint_);
bool nearer = magSqr(w2.collapsePoint_)
< magSqr(collapsePoint_);
bool nearer = (magSqr(w2.collapsePoint_) < magSqr(collapsePoint_));
if (nearer)
{

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -579,9 +579,7 @@ void Foam::extendedFeatureEdgeMesh::allNearestFeaturePoints
label ptI = pointTree().shapes().pointLabels()[index];
const point& pt = points()[ptI];
pointIndexHit nearHit;
nearHit = pointIndexHit(true, pt, index);
pointIndexHit nearHit(true, pt, index);
dynPointHit.append(nearHit);
}
@ -631,16 +629,12 @@ void Foam::extendedFeatureEdgeMesh::allNearestFeatureEdges
label hitIndex = index + sliceStarts[i];
pointIndexHit nearHit;
if (!hitPoint.hit())
{
nearHit = pointIndexHit(false, hitPoint.missPoint(), hitIndex);
}
else
{
nearHit = pointIndexHit(true, hitPoint.hitPoint(), hitIndex);
}
pointIndexHit nearHit
(
hitPoint.hit(),
hitPoint.rawPoint(),
hitIndex
);
dynEdgeHit.append(nearHit);
}