/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see .
Description
Checks for multiple patch faces on same cell and combines them. These
result from e.g. refined neighbouring cells getting removed, leaving 4
exposed faces with same owner.
Rules for merging:
- only boundary faces (since multiple internal faces between two cells
not allowed anyway)
- faces have to have same owner
- faces have to be connected via edge which are not features (so angle
between them < feature angle)
- outside of faces has to be single loop
- outside of face should not be (or just slightly) concave (so angle
between consecutive edges < concaveangle
E.g. to allow all faces on same patch to be merged:
combinePatchFaces 180 -concaveAngle 90
\*---------------------------------------------------------------------------*/
#include "PstreamReduceOps.H"
#include "argList.H"
#include "Time.H"
#include "polyTopoChange.H"
#include "polyModifyFace.H"
#include "polyAddFace.H"
#include "combineFaces.H"
#include "removePoints.H"
#include "polyMesh.H"
#include "mapPolyMesh.H"
#include "unitConversion.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Same check as snapMesh
void checkSnapMesh
(
const Time& runTime,
const polyMesh& mesh,
labelHashSet& wrongFaces
)
{
IOdictionary snapDict
(
IOobject
(
"snapMeshDict",
runTime.system(),
mesh,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
);
// Max nonorthogonality allowed
scalar maxNonOrtho(readScalar(snapDict.lookup("maxNonOrtho")));
// Max concaveness allowed.
scalar maxConcave(readScalar(snapDict.lookup("maxConcave")));
// Min volume allowed (factor of minimum cellVolume)
scalar relMinVol(readScalar(snapDict.lookup("minVol")));
const scalar minCellVol = min(mesh.cellVolumes());
const scalar minPyrVol = relMinVol*minCellVol;
// Min area
scalar minArea(readScalar(snapDict.lookup("minArea")));
if (maxNonOrtho < 180.0-SMALL)
{
Pout<< "Checking non orthogonality" << endl;
label nOldSize = wrongFaces.size();
mesh.setNonOrthThreshold(maxNonOrtho);
mesh.checkFaceOrthogonality(false, &wrongFaces);
Pout<< "Detected " << wrongFaces.size() - nOldSize
<< " faces with non-orthogonality > " << maxNonOrtho << " degrees"
<< endl;
}
if (minPyrVol > -GREAT)
{
Pout<< "Checking face pyramids" << endl;
label nOldSize = wrongFaces.size();
mesh.checkFacePyramids(false, minPyrVol, &wrongFaces);
Pout<< "Detected additional " << wrongFaces.size() - nOldSize
<< " faces with illegal face pyramids" << endl;
}
if (maxConcave < 180.0-SMALL)
{
Pout<< "Checking face angles" << endl;
label nOldSize = wrongFaces.size();
mesh.checkFaceAngles(false, maxConcave, &wrongFaces);
Pout<< "Detected additional " << wrongFaces.size() - nOldSize
<< " faces with concavity > " << maxConcave << " degrees"
<< endl;
}
if (minArea > -SMALL)
{
Pout<< "Checking face areas" << endl;
label nOldSize = wrongFaces.size();
const scalarField magFaceAreas(mag(mesh.faceAreas()));
forAll(magFaceAreas, faceI)
{
if (magFaceAreas[faceI] < minArea)
{
wrongFaces.insert(faceI);
}
}
Pout<< "Detected additional " << wrongFaces.size() - nOldSize
<< " faces with area < " << minArea << " m^2" << endl;
}
}
// Merge faces on the same patch (usually from exposing refinement)
// Can undo merges if these cause problems.
label mergePatchFaces
(
const scalar minCos,
const scalar concaveSin,
const bool snapMeshDict,
const Time& runTime,
polyMesh& mesh
)
{
// Patch face merging engine
combineFaces faceCombiner(mesh);
// Get all sets of faces that can be merged
labelListList allFaceSets(faceCombiner.getMergeSets(minCos, concaveSin));
label nFaceSets = returnReduce(allFaceSets.size(), sumOp