ENH: snappyHexMesh: early exit of leak detection. See #2403

This commit is contained in:
mattijs 2022-06-01 15:25:14 +01:00
parent 11b0d70b2d
commit 903f45dcdc
6 changed files with 175 additions and 96 deletions

View File

@ -225,6 +225,11 @@ castellatedMeshControls
//- Optional removal of cells in thin gaps. Start removing cells
// if at refinement level 10 we're detecting thin gaps.
//blockLevel 10;
//- Optional early detection of connections between inside and
// outside locations. Default is only after all refinement has
// been done.
//leakLevel 10;
}
}
@ -481,6 +486,9 @@ castellatedMeshControls
//minCellFraction 0.001;
// Optional: same but in absolute number of cells. Default is 0.
//nMinCells 100;
// Optional: disable of automatic leak closure and exit immediately
//useLeakClosure false;
}
// Settings for the snapping.

View File

@ -586,6 +586,7 @@ private:
const pointField& locationsInMesh,
const wordList& regionsInMesh,
const pointField& locationsOutsideMesh,
const bool exitIfLeakPath,
const refPtr<coordSetWriter>& leakPathFormatter,
const labelList& neiLevel,
@ -845,6 +846,7 @@ private:
const pointField& locationsInMesh,
const wordList& zonesInMesh,
const pointField& locationsOutsideMesh,
const bool exitIfLeakPath,
const refPtr<coordSetWriter>& leakPathFormatter,
labelList& cellToZone,
@ -1302,6 +1304,7 @@ public:
const pointField& locationsInMesh,
const wordList& regionsInMesh,
const pointField& locationsOutsideMesh,
const bool exitIfLeakPath,
const refPtr<coordSetWriter>& leakPathFormatter
);
@ -1333,6 +1336,7 @@ public:
const pointField& locationsInMesh,
const wordList& regionsInMesh,
const pointField& locationsOutsideMesh,
const bool exitIfLeakPath,
const refPtr<coordSetWriter>& leakPathFormatter
);
@ -1435,6 +1439,7 @@ public:
const pointField& locationsInMesh,
const wordList& regionsInMesh,
const pointField& locationsOutsideMesh,
const bool exitIfLeakPath,
const refPtr<coordSetWriter>& leakPathFormatter,
wordPairHashTable& zonesToFaceZone
);

View File

@ -292,6 +292,7 @@ void Foam::meshRefinement::getBafflePatches
const pointField& locationsInMesh,
const wordList& zonesInMesh,
const pointField& locationsOutsideMesh,
const bool exitIfLeakPath,
const refPtr<coordSetWriter>& leakPathFormatter,
const labelList& neiLevel,
const pointField& neiCc,
@ -326,6 +327,7 @@ void Foam::meshRefinement::getBafflePatches
locationsInMesh,
zonesInMesh,
locationsOutsideMesh,
exitIfLeakPath,
leakPathFormatter,
cellToZone,
@ -2848,6 +2850,7 @@ void Foam::meshRefinement::zonify
const pointField& locationsInMesh,
const wordList& zonesInMesh,
const pointField& locationsOutsideMesh,
const bool exitIfLeakPath,
const refPtr<coordSetWriter>& leakPathFormatter,
labelList& cellToZone,
@ -2961,11 +2964,6 @@ void Foam::meshRefinement::zonify
// Add to unnamedRegion1, unnamedRegion2
if (unnamedMapPtr.valid())
{
WarningInFunction
<< "Detected and closed leak path from "
<< locationsInMesh << " to " << locationsOutsideMesh
<< endl;
// Dump leak path
if (leakPathFormatter)
{
@ -2985,6 +2983,23 @@ void Foam::meshRefinement::zonify
Info<< "Dumped leak path to " << fName << endl;
}
auto& err =
(
exitIfLeakPath
? FatalErrorInFunction
: WarningInFunction
);
err << "Locations in mesh " << locationsInMesh
<< " connect to one of the locations outside mesh "
<< locationsOutsideMesh << endl;
if (exitIfLeakPath)
{
FatalError << exit(FatalError);
}
labelList packedRegion1
(
UIndirectList<label>(unnamedRegion1, unnamedFaces)
@ -3034,96 +3049,119 @@ void Foam::meshRefinement::zonify
posOrientation
);
if (locationsOutsideMesh.size())
{
namedFaces = ListOps::findIndices
(
namedSurfaceRegion,
[](const label x){return x != -1;}
);
// Ideally we'd like to close 'cellZone' surfaces. The problem is
// that we don't (easily) know which locationsInMesh should be inside
// the surface and which aren't. With 'insidePoint' definition of
// cellZone we have a location inside the cellZone but how do we
// know where the locationsInMesh are? Are they inside the cellZone
// as well? Only with the 'locationsInMesh' notation where we specify
// the cellZone and the seedpoint could we make sure that we cannot
// walk from one to the other.
// For now disable hole closure on cellZones
const globalIndex globalNamedFaces(namedFaces.size());
namedMapPtr = holeToFace::calcClosure
(
mesh_,
allLocations,
namedFaces,
globalNamedFaces,
true, // allow erosion
namedClosureFaces,
namedToClosure
);
if (debug)
{
Pout<< "meshRefinement::zonify : found faceZone closure faces:"
<< namedClosureFaces.size()
<< " map:" << namedMapPtr.valid() << endl;
}
// Add to namedSurfaceRegion, posOrientation
if (namedMapPtr.valid())
{
WarningInFunction
<< "Detected and closed leak path"
<< " through zoned surfaces from "
<< locationsInMesh << " to " << locationsOutsideMesh
<< endl;
// Dump leak path
if (leakPathFormatter)
{
boolList blockedFace(mesh_.nFaces(), false);
UIndirectList<bool>(blockedFace, unnamedFaces) = true;
UIndirectList<bool>(blockedFace, namedFaces) = true;
const fileName fName
(
writeLeakPath
(
mesh_,
locationsInMesh,
locationsOutsideMesh,
blockedFace,
leakPathFormatter.constCast()
)
);
Info<< "Dumped leak path to " << fName << endl;
}
labelList packedSurfaceRegion
(
UIndirectList<label>(namedSurfaceRegion, namedFaces)
);
namedMapPtr->distribute(packedSurfaceRegion);
boolList packedOrientation(posOrientation.size());
forAll(namedFaces, i)
{
const label facei = namedFaces[i];
packedOrientation[i] = posOrientation[facei];
}
namedMapPtr->distribute(packedOrientation);
forAll(namedClosureFaces, i)
{
const label sloti = namedToClosure[i];
if (sloti != -1)
{
const label facei = namedClosureFaces[i];
const label regioni = namedSurfaceRegion[facei];
const label slotRegioni = packedSurfaceRegion[sloti];
const bool orient = posOrientation[facei];
const bool slotOrient = packedOrientation[sloti];
if (slotRegioni != regioni || slotOrient != orient)
{
namedSurfaceRegion[facei] = slotRegioni;
posOrientation[facei] = slotOrient;
}
}
}
}
}
//if (locationsOutsideMesh.size())
//{
// namedFaces = ListOps::findIndices
// (
// namedSurfaceRegion,
// [](const label x){return x != -1;}
// );
//
// {
// OBJstream str(mesh_.time().timePath()/"namedFaces.obj");
// Pout<< "Writing " << namedFaces.size() << " zone faces to "
// << str.name() << endl;
// str.write
// (
// UIndirectList<face>(mesh_.faces(), namedFaces)(),
// mesh_.points()
// );
// }
//
//
// const globalIndex globalNamedFaces(namedFaces.size());
//
// namedMapPtr = holeToFace::calcClosure
// (
// mesh_,
// allLocations,
// namedFaces, // or also unnamedFaces?
// globalNamedFaces,
// true, // allow erosion
//
// namedClosureFaces,
// namedToClosure
// );
//
// if (debug)
// {
// Pout<< "meshRefinement::zonify :"
// << " found faceZone closure faces:"
// << namedClosureFaces.size()
// << " map:" << namedMapPtr.valid() << endl;
// }
//
// // Add to namedSurfaceRegion, posOrientation
// if (namedMapPtr.valid())
// {
// WarningInFunction
// << "Detected and closed leak path"
// << " through zoned surfaces from "
// << locationsInMesh << " to " << locationsOutsideMesh
// << endl;
//
// // Dump leak path
// if (leakPathFormatter)
// {
// boolList blockedFace(mesh_.nFaces(), false);
// UIndirectList<bool>(blockedFace, unnamedFaces) = true;
// UIndirectList<bool>(blockedFace, namedFaces) = true;
// const fileName fName
// (
// writeLeakPath
// (
// mesh_,
// locationsInMesh,
// locationsOutsideMesh,
// blockedFace,
// leakPathFormatter.constCast()
// )
// );
// Info<< "Dumped leak path to " << fName << endl;
// }
//
// labelList packedSurfaceRegion
// (
// UIndirectList<label>(namedSurfaceRegion, namedFaces)
// );
// namedMapPtr->distribute(packedSurfaceRegion);
// boolList packedOrientation(posOrientation.size());
// forAll(namedFaces, i)
// {
// const label facei = namedFaces[i];
// packedOrientation[i] = posOrientation[facei];
// }
// namedMapPtr->distribute(packedOrientation);
// forAll(namedClosureFaces, i)
// {
// const label sloti = namedToClosure[i];
// if (sloti != -1)
// {
// const label facei = namedClosureFaces[i];
// const label regioni = namedSurfaceRegion[facei];
// const label slotRegioni = packedSurfaceRegion[sloti];
// const bool orient = posOrientation[facei];
// const bool slotOrient = packedOrientation[sloti];
//
// if (slotRegioni != regioni || slotOrient != orient)
// {
// namedSurfaceRegion[facei] = slotRegioni;
// posOrientation[facei] = slotOrient;
// }
// }
// }
// }
//}
}
@ -4505,6 +4543,7 @@ void Foam::meshRefinement::baffleAndSplitMesh
const pointField& locationsInMesh,
const wordList& zonesInMesh,
const pointField& locationsOutsideMesh,
const bool exitIfLeakPath,
const refPtr<coordSetWriter>& leakPathFormatter
)
{
@ -4532,6 +4571,7 @@ void Foam::meshRefinement::baffleAndSplitMesh
locationsInMesh,
zonesInMesh,
locationsOutsideMesh,
exitIfLeakPath,
refPtr<coordSetWriter>(nullptr),
neiLevel,
@ -4606,6 +4646,7 @@ void Foam::meshRefinement::baffleAndSplitMesh
locationsInMesh,
zonesInMesh,
locationsOutsideMesh,
exitIfLeakPath,
refPtr<coordSetWriter>(nullptr),
neiLevel,
@ -4781,12 +4822,14 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::splitMesh
const pointField& locationsInMesh,
const wordList& zonesInMesh,
const pointField& locationsOutsideMesh,
const bool exitIfLeakPath,
const refPtr<coordSetWriter>& leakPathFormatter
)
{
// Determine patches to put intersections into
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Swap neighbouring cell centres and cell level
labelList neiLevel(mesh_.nBoundaryFaces());
pointField neiCc(mesh_.nBoundaryFaces());
@ -4802,6 +4845,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::splitMesh
locationsInMesh,
zonesInMesh,
locationsOutsideMesh,
exitIfLeakPath,
leakPathFormatter,
neiLevel,
@ -5269,6 +5313,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::removeLimitShells
locationsInMesh,
zonesInMesh,
locationsOutsideMesh,
false, // do not exit. Use leak-closure instead.
refPtr<coordSetWriter>(nullptr),
neiLevel,
@ -5579,6 +5624,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
const pointField& locationsInMesh,
const wordList& zonesInMesh,
const pointField& locationsOutsideMesh,
const bool exitIfLeakPath,
const refPtr<coordSetWriter>& leakPathFormatter,
wordPairHashTable& zonesToFaceZone
)
@ -5660,6 +5706,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
locationsInMesh,
zonesInMesh,
locationsOutsideMesh,
exitIfLeakPath,
leakPathFormatter,
cellToZone,

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2015-2020 OpenCFD Ltd.
Copyright (C) 2015-2020,2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -74,6 +74,7 @@ Foam::refinementParameters::refinementParameters
pointField(0)
)
),
useLeakClosure_(dict.getOrDefault<bool>("useLeakClosure", true)),
faceZoneControls_(dict.subOrEmptyDict("faceZoneControls")),
allowFreeStandingZoneFaces_
(

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2014 OpenFOAM Foundation
Copyright (C) 2015-2020 OpenCFD Ltd.
Copyright (C) 2015-2020,2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -87,6 +87,9 @@ class refinementParameters
//- Areas to keep
pointField locationsInMesh_;
//- How to handle connections between inside and outside points
const bool useLeakClosure_;
//- Region for location
wordList zonesInMesh_;
@ -195,6 +198,16 @@ public:
return locationsOutsideMesh_;
}
//- Whether to attempt to close any 'leak' between
// locationsInsideMesh and locationsOutsideMesh or exit with
// error. Default is true.
// (see also refinementSurfaces::leakLevel to force surfaces to
// be checked for leaks early-on in the refinement)
bool useLeakClosure() const
{
return useLeakClosure_;
}
//- Are zone faces allowed only inbetween different cell zones
// or also just free standing?
bool allowFreeStandingZoneFaces() const

View File

@ -1824,6 +1824,7 @@ void Foam::snappyRefineDriver::removeInsideCells
);
}
// Fix any additional (e.g. locationsOutsideMesh). Note: probably not
// necessary.
meshRefiner_.splitMesh
@ -1835,6 +1836,7 @@ void Foam::snappyRefineDriver::removeInsideCells
refineParams.locationsInMesh(),
refineParams.zonesInMesh(),
refineParams.locationsOutsideMesh(),
!refineParams.useLeakClosure(),
setFormatter_
);
@ -2822,6 +2824,7 @@ void Foam::snappyRefineDriver::baffleAndSplitMesh
refineParams.locationsInMesh(),
refineParams.zonesInMesh(),
refineParams.locationsOutsideMesh(),
!refineParams.useLeakClosure(),
setFormatter_
);
@ -2886,6 +2889,7 @@ void Foam::snappyRefineDriver::zonify
refineParams.locationsInMesh(),
refineParams.zonesInMesh(),
refineParams.locationsOutsideMesh(),
!refineParams.useLeakClosure(),
setFormatter_,
zonesToFaceZone
);
@ -2958,6 +2962,7 @@ void Foam::snappyRefineDriver::splitAndMergeBaffles
refineParams.locationsInMesh(),
refineParams.zonesInMesh(),
refineParams.locationsOutsideMesh(),
!refineParams.useLeakClosure(),
setFormatter_
);