mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: more flexible finiteArea patch selection (#2084)
- support wordRes for selecting patch names
- ownerPolyPatch specification is now optional, which simplifies input
and also supports a faMesh spanning different patches but with a
single boundary condition.
Alternatively, can specify more granularity if required.
```
polyMeshPatches ( "top.*" );
boundary
{
inlet1
{
type patch;
ownerPolyPatch top1; // <- specific to this portion
neighbourPolyPatch inlet;
}
inlet2
{
type patch;
ownerPolyPatch top2; // <- specific to this portion
neighbourPolyPatch inlet;
}
outlet
{
type patch;
neighbourPolyPatch outflow;
}
bound
{
type symmetry;
neighbourPolyPatch bound;
}
}
```
This commit is contained in:
@ -64,35 +64,41 @@ namespace Foam
|
||||
static labelList selectPatchFaces
|
||||
(
|
||||
const polyBoundaryMesh& pbm,
|
||||
const wordList& polyPatchNames
|
||||
const wordRes& polyPatchNames
|
||||
)
|
||||
{
|
||||
labelHashSet patchIDs;
|
||||
//- Return the set of patch IDs corresponding to the given names
|
||||
// By default warns if given names are not found.
|
||||
// Optionally matches to patchGroups as well as patchNames.
|
||||
const labelList patchIDs
|
||||
(
|
||||
pbm.patchSet
|
||||
(
|
||||
polyPatchNames,
|
||||
false, // warnNotFound
|
||||
true // useGroups
|
||||
).sortedToc()
|
||||
);
|
||||
|
||||
if (patchIDs.empty())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No matching patches: " << polyPatchNames << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
label nFaceLabels = 0;
|
||||
for (const word& patchName : polyPatchNames)
|
||||
for (const label patchi : patchIDs)
|
||||
{
|
||||
const label polyPatchi = pbm.findPatchID(patchName);
|
||||
|
||||
if (polyPatchi < 0)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Patch " << patchName << " not found"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
if (patchIDs.insert(polyPatchi))
|
||||
{
|
||||
nFaceLabels += pbm[polyPatchi].size();
|
||||
}
|
||||
nFaceLabels += pbm[patchi].size();
|
||||
}
|
||||
|
||||
labelList faceLabels(nFaceLabels);
|
||||
|
||||
nFaceLabels = 0;
|
||||
for (const label polyPatchi : patchIDs.sortedToc())
|
||||
for (const label patchi : patchIDs)
|
||||
{
|
||||
for (const label facei : pbm[polyPatchi].range())
|
||||
for (const label facei : pbm[patchi].range())
|
||||
{
|
||||
faceLabels[nFaceLabels] = facei;
|
||||
++nFaceLabels;
|
||||
@ -413,7 +419,7 @@ Foam::faMesh::faMesh
|
||||
selectPatchFaces
|
||||
(
|
||||
pMesh.boundaryMesh(),
|
||||
faMeshDefinition.get<wordList>("polyMeshPatches")
|
||||
faMeshDefinition.get<wordRes>("polyMeshPatches")
|
||||
)
|
||||
)
|
||||
{
|
||||
|
||||
@ -697,23 +697,30 @@ Foam::PtrList<Foam::faPatch> Foam::faMesh::createPatchList
|
||||
patchDef.name_ = dEntry.keyword();
|
||||
patchDef.type_ = patchDict.get<word>("type");
|
||||
|
||||
const word ownName(patchDict.get<word>("ownerPolyPatch"));
|
||||
const word neiName(patchDict.get<word>("neighbourPolyPatch"));
|
||||
word patchName;
|
||||
|
||||
patchDef.ownerPolyPatchId_ = pbm.findPatchID(ownName);
|
||||
patchDef.neighPolyPatchId_ = pbm.findPatchID(neiName);
|
||||
|
||||
if (patchDef.ownerPolyPatchId_ < 0)
|
||||
// Optional: ownerPolyPatch
|
||||
if (patchDict.readIfPresent("ownerPolyPatch", patchName))
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "ownerPolyPatch " << ownName << " not found"
|
||||
<< exit(FatalError);
|
||||
patchDef.ownerPolyPatchId_ = pbm.findPatchID(patchName);
|
||||
if (patchDef.ownerPolyPatchId_ < 0)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "ownerPolyPatch " << patchName << " not found"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
if (patchDef.neighPolyPatchId_ < 0)
|
||||
|
||||
// Mandatory: neighbourPolyPatch
|
||||
patchDict.readEntry("neighbourPolyPatch", patchName);
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "neighbourPolyPatch " << neiName << " not found"
|
||||
<< exit(FatalError);
|
||||
patchDef.neighPolyPatchId_ = pbm.findPatchID(patchName);
|
||||
if (patchDef.neighPolyPatchId_ < 0)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "neighbourPolyPatch " << patchName << " not found"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -756,20 +763,28 @@ Foam::PtrList<Foam::faPatch> Foam::faMesh::createPatchList
|
||||
{
|
||||
const patchPairInfo& patchPair = bndEdgePatchPairs[bndEdgei];
|
||||
|
||||
if (patchPair.valid())
|
||||
{
|
||||
// Non-negative, unique pairing
|
||||
// - find corresponding definition
|
||||
// Find first definition with a matching neighbour and
|
||||
// possibly with a matching owner.
|
||||
|
||||
for (label patchi = 0; patchi < faPatchDefs.size(); ++patchi)
|
||||
label bestPatchi = -1;
|
||||
|
||||
for (label patchi = 0; patchi < faPatchDefs.size(); ++patchi)
|
||||
{
|
||||
const int match = faPatchDefs[patchi].matchPatchPair(patchPair);
|
||||
if (match == 3)
|
||||
{
|
||||
if (faPatchDefs[patchi].foundPatchPair(patchPair))
|
||||
{
|
||||
bndEdgeFaPatchIDs[bndEdgei] = patchi;
|
||||
break;
|
||||
}
|
||||
// Match (owner/neighbour) - done!
|
||||
bestPatchi = patchi;
|
||||
break;
|
||||
}
|
||||
else if (match == 2 && bestPatchi < 0)
|
||||
{
|
||||
// Match (neighbour) - keep looking for exact match
|
||||
bestPatchi = patchi;
|
||||
}
|
||||
}
|
||||
|
||||
bndEdgeFaPatchIDs[bndEdgei] = bestPatchi;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -26,7 +26,6 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "faPatchData.H"
|
||||
#include "edge.H"
|
||||
#include "dictionary.H"
|
||||
#include "processorFaPatch.H"
|
||||
|
||||
@ -109,21 +108,53 @@ void Foam::faPatchData::assign(const faPatch& fap)
|
||||
}
|
||||
|
||||
|
||||
bool Foam::faPatchData::foundPatchPair(const edge& patchPair) const
|
||||
int Foam::faPatchData::matchPatchPair
|
||||
(
|
||||
const labelPair& patchPair
|
||||
) const noexcept
|
||||
{
|
||||
// Same as edge::compare
|
||||
return
|
||||
(
|
||||
int ret = 0;
|
||||
if (patchPair.first() >= 0 && patchPair.first() == ownerPolyPatchId_)
|
||||
{
|
||||
ret |= 1;
|
||||
}
|
||||
if (patchPair.second() >= 0 && patchPair.second() == neighPolyPatchId_)
|
||||
{
|
||||
ret |= 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int Foam::faPatchData::comparePatchPair
|
||||
(
|
||||
const labelPair& patchPair
|
||||
) const noexcept
|
||||
{
|
||||
// As per edge::compare, with validity check
|
||||
|
||||
if (patchPair.first() >= 0 || patchPair.second() >= 0)
|
||||
{
|
||||
if
|
||||
(
|
||||
ownerPolyPatchId_ == patchPair.first()
|
||||
&& neighPolyPatchId_ == patchPair.second()
|
||||
)
|
||||
||
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
ownerPolyPatchId_ == patchPair.second()
|
||||
&& neighPolyPatchId_ == patchPair.first()
|
||||
)
|
||||
);
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -37,6 +37,7 @@ Description
|
||||
#define faPatchData_H
|
||||
|
||||
#include "labelList.H"
|
||||
#include "labelPair.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -44,7 +45,6 @@ namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class edge;
|
||||
class faPatch;
|
||||
class dictionary;
|
||||
|
||||
@ -116,8 +116,17 @@ public:
|
||||
return !owner();
|
||||
}
|
||||
|
||||
//- True it matches the owner/neighbour patch pair (any order)
|
||||
bool foundPatchPair(const edge& patchPair) const;
|
||||
//- Ordered match with owner/neighbour patchPair.
|
||||
// \return
|
||||
// - 0: matched none
|
||||
// - 1: matched first only (owner)
|
||||
// - 2: matched second only (neighbour)
|
||||
// - 3: matched both (owner/neighbour)
|
||||
// .
|
||||
int matchPatchPair(const labelPair& patchPair) const noexcept;
|
||||
|
||||
//- Unordered comparison with owner/neighbour patchPair.
|
||||
int comparePatchPair(const labelPair& patchPair) const noexcept;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user