mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: GeometricField: support patch groups
This commit is contained in:
@ -248,15 +248,81 @@ GeometricBoundaryField
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
||||
// Check for groups first. (using non-wild card entries of dictionaries)
|
||||
forAllConstIter(dictionary, dict, iter)
|
||||
{
|
||||
if (iter().isDict())
|
||||
{
|
||||
const labelList patchIDs = bmesh_.findIndices
|
||||
(
|
||||
iter().keyword(),
|
||||
true
|
||||
);
|
||||
|
||||
forAll(patchIDs, i)
|
||||
{
|
||||
label patchi = patchIDs[i];
|
||||
this->set
|
||||
(
|
||||
patchi,
|
||||
PatchField<Type>::New
|
||||
(
|
||||
bmesh_[patchi],
|
||||
field,
|
||||
iter().dict()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for explicit patch overrides
|
||||
forAll(bmesh_, patchi)
|
||||
{
|
||||
if (bmesh_[patchi].type() != emptyPolyPatch::typeName)
|
||||
if (bmesh_[patchi].type() == emptyPolyPatch::typeName)
|
||||
{
|
||||
if
|
||||
(
|
||||
bmesh_[patchi].type() == cyclicPolyPatch::typeName
|
||||
&& !dict.found(bmesh_[patchi].name())
|
||||
)
|
||||
if (!this->set(patchi))
|
||||
{
|
||||
this->set
|
||||
(
|
||||
patchi,
|
||||
PatchField<Type>::New
|
||||
(
|
||||
emptyPolyPatch::typeName,
|
||||
bmesh_[patchi],
|
||||
field
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool found = dict.found(bmesh_[patchi].name());
|
||||
|
||||
if (found)
|
||||
{
|
||||
this->set
|
||||
(
|
||||
patchi,
|
||||
PatchField<Type>::New
|
||||
(
|
||||
bmesh_[patchi],
|
||||
field,
|
||||
dict.subDict(bmesh_[patchi].name())
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check for any unset patches
|
||||
forAll(bmesh_, patchi)
|
||||
{
|
||||
if (!this->set(patchi))
|
||||
{
|
||||
if (bmesh_[patchi].type() == cyclicPolyPatch::typeName)
|
||||
{
|
||||
FatalIOErrorIn
|
||||
(
|
||||
@ -274,30 +340,21 @@ GeometricBoundaryField
|
||||
<< "Run foamUpgradeCyclics to convert mesh and fields"
|
||||
<< " to split cyclics." << exit(FatalIOError);
|
||||
}
|
||||
|
||||
this->set
|
||||
(
|
||||
patchi,
|
||||
PatchField<Type>::New
|
||||
else
|
||||
{
|
||||
FatalIOErrorIn
|
||||
(
|
||||
bmesh_[patchi],
|
||||
field,
|
||||
dict.subDict(bmesh_[patchi].name())
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->set
|
||||
(
|
||||
patchi,
|
||||
PatchField<Type>::New
|
||||
(
|
||||
emptyPolyPatch::typeName,
|
||||
bmesh_[patchi],
|
||||
field
|
||||
)
|
||||
);
|
||||
"GeometricField<Type, PatchField, GeoMesh>::\n"
|
||||
"GeometricBoundaryField::GeometricBoundaryField\n"
|
||||
"(\n"
|
||||
" const BoundaryMesh&,\n"
|
||||
" const DimensionedField<Type, GeoMesh>&,\n"
|
||||
" const dictionary&\n"
|
||||
")",
|
||||
dict
|
||||
) << "Cannot find patchField entry for "
|
||||
<< bmesh_[patchi].name() << exit(FatalIOError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,12 +32,14 @@ Foam::patchIdentifier::patchIdentifier
|
||||
(
|
||||
const word& name,
|
||||
const label index,
|
||||
const word& physicalType
|
||||
const word& physicalType,
|
||||
const wordList& inGroups
|
||||
)
|
||||
:
|
||||
name_(name),
|
||||
index_(index),
|
||||
physicalType_(physicalType)
|
||||
physicalType_(physicalType),
|
||||
inGroups_(inGroups)
|
||||
{}
|
||||
|
||||
|
||||
@ -52,6 +54,7 @@ Foam::patchIdentifier::patchIdentifier
|
||||
index_(index)
|
||||
{
|
||||
dict.readIfPresent("physicalType", physicalType_);
|
||||
dict.readIfPresent("inGroups", inGroups_);
|
||||
}
|
||||
|
||||
|
||||
@ -63,7 +66,8 @@ Foam::patchIdentifier::patchIdentifier
|
||||
:
|
||||
name_(p.name_),
|
||||
index_(index),
|
||||
physicalType_(p.physicalType_)
|
||||
physicalType_(p.physicalType_),
|
||||
inGroups_(p.inGroups_)
|
||||
{}
|
||||
|
||||
|
||||
@ -82,6 +86,11 @@ void Foam::patchIdentifier::write(Ostream& os) const
|
||||
os.writeKeyword("physicalType") << physicalType_
|
||||
<< token::END_STATEMENT << nl;
|
||||
}
|
||||
if (inGroups_.size())
|
||||
{
|
||||
os.writeKeyword("inGroups") << inGroups_
|
||||
<< token::END_STATEMENT << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ SourceFiles
|
||||
#ifndef patchIdentifier_H
|
||||
#define patchIdentifier_H
|
||||
|
||||
#include "word.H"
|
||||
#include "wordList.H"
|
||||
#include "label.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -68,6 +68,8 @@ class patchIdentifier
|
||||
//- Optional physical type
|
||||
mutable word physicalType_;
|
||||
|
||||
//- Optional groups patch belongs to
|
||||
wordList inGroups_;
|
||||
|
||||
public:
|
||||
|
||||
@ -78,7 +80,8 @@ public:
|
||||
(
|
||||
const word& name,
|
||||
const label index,
|
||||
const word& physicalType = word::null
|
||||
const word& physicalType = word::null,
|
||||
const wordList& inGroups = wordList()
|
||||
);
|
||||
|
||||
//- Construct from dictionary
|
||||
@ -139,6 +142,19 @@ public:
|
||||
return index_;
|
||||
}
|
||||
|
||||
//- Return the optional groups patch belongs to
|
||||
const wordList& inGroups() const
|
||||
{
|
||||
return inGroups_;
|
||||
}
|
||||
|
||||
//- Return the optional groups patch belongs to for modification
|
||||
wordList& inGroups()
|
||||
{
|
||||
return inGroups_;
|
||||
}
|
||||
|
||||
|
||||
//- Write patchIdentifier as a dictionary
|
||||
void write(Ostream&) const;
|
||||
|
||||
|
||||
@ -58,6 +58,16 @@ Foam::pointBoundaryMesh::pointBoundaryMesh
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::labelList Foam::pointBoundaryMesh::findIndices
|
||||
(
|
||||
const keyType& key,
|
||||
const bool usePatchGroups
|
||||
) const
|
||||
{
|
||||
return mesh()().boundaryMesh().findIndices(key, usePatchGroups);
|
||||
}
|
||||
|
||||
|
||||
void Foam::pointBoundaryMesh::calcGeometry()
|
||||
{
|
||||
PstreamBuffers pBufs(Pstream::defaultCommsType);
|
||||
|
||||
@ -96,6 +96,9 @@ public:
|
||||
return mesh_;
|
||||
}
|
||||
|
||||
//- Find patch indices given a name
|
||||
labelList findIndices(const keyType&, const bool useGroups) const;
|
||||
|
||||
//- Correct polyBoundaryMesh after moving points
|
||||
void movePoints(const pointField&);
|
||||
|
||||
|
||||
@ -151,6 +151,7 @@ void Foam::polyBoundaryMesh::clearAddressing()
|
||||
{
|
||||
neighbourEdgesPtr_.clear();
|
||||
patchIDPtr_.clear();
|
||||
groupPatchIDsPtr_.clear();
|
||||
|
||||
forAll(*this, patchI)
|
||||
{
|
||||
@ -369,6 +370,54 @@ const Foam::labelList& Foam::polyBoundaryMesh::patchID() const
|
||||
}
|
||||
|
||||
|
||||
const Foam::HashTable<Foam::labelList, Foam::word>&
|
||||
Foam::polyBoundaryMesh::groupPatchIDs() const
|
||||
{
|
||||
if (!groupPatchIDsPtr_.valid())
|
||||
{
|
||||
groupPatchIDsPtr_.reset(new HashTable<labelList, word>(10));
|
||||
HashTable<labelList, word>& groupPatchIDs = groupPatchIDsPtr_();
|
||||
|
||||
const polyBoundaryMesh& bm = *this;
|
||||
|
||||
forAll(bm, patchI)
|
||||
{
|
||||
const wordList& groups = bm[patchI].inGroups();
|
||||
|
||||
forAll(groups, i)
|
||||
{
|
||||
const word& name = groups[i];
|
||||
|
||||
if (findPatchID(name) != -1)
|
||||
{
|
||||
WarningIn("polyBoundaryMesh::groupPatchIDs() const")
|
||||
<< "Patch " << bm[patchI].name()
|
||||
<< " specifies a group " << name
|
||||
<< " which is also a patch name."
|
||||
<< " This might give problems later on." << endl;
|
||||
}
|
||||
|
||||
|
||||
HashTable<labelList, word>::iterator iter = groupPatchIDs.find
|
||||
(
|
||||
name
|
||||
);
|
||||
|
||||
if (iter != groupPatchIDs.end())
|
||||
{
|
||||
iter().append(patchI);
|
||||
}
|
||||
else
|
||||
{
|
||||
groupPatchIDs.insert(name, labelList(1, patchI));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return groupPatchIDsPtr_();
|
||||
}
|
||||
|
||||
|
||||
Foam::wordList Foam::polyBoundaryMesh::names() const
|
||||
{
|
||||
const polyPatchList& patches = *this;
|
||||
@ -414,28 +463,74 @@ Foam::wordList Foam::polyBoundaryMesh::physicalTypes() const
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::polyBoundaryMesh::findIndices(const keyType& key) const
|
||||
Foam::labelList Foam::polyBoundaryMesh::findIndices
|
||||
(
|
||||
const keyType& key,
|
||||
const bool usePatchGroups
|
||||
) const
|
||||
{
|
||||
labelList indices;
|
||||
DynamicList<label> indices;
|
||||
|
||||
if (!key.empty())
|
||||
{
|
||||
if (key.isPattern())
|
||||
{
|
||||
indices = findStrings(key, this->names());
|
||||
|
||||
if (usePatchGroups && groupPatchIDs().size())
|
||||
{
|
||||
labelHashSet indexSet(indices);
|
||||
|
||||
const wordList allGroupNames = groupPatchIDs().toc();
|
||||
labelList groupIDs = findStrings(key, allGroupNames);
|
||||
forAll(groupIDs, i)
|
||||
{
|
||||
const word& grpName = allGroupNames[groupIDs[i]];
|
||||
const labelList& patchIDs = groupPatchIDs()[grpName];
|
||||
forAll(patchIDs, j)
|
||||
{
|
||||
if (indexSet.insert(patchIDs[j]))
|
||||
{
|
||||
indices.append(patchIDs[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
indices.setSize(this->size());
|
||||
label nFound = 0;
|
||||
// Literal string. Special version of above to avoid
|
||||
// unnecessary memory allocations
|
||||
|
||||
indices.setCapacity(1);
|
||||
forAll(*this, i)
|
||||
{
|
||||
if (key == operator[](i).name())
|
||||
{
|
||||
indices[nFound++] = i;
|
||||
indices.append(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (usePatchGroups && groupPatchIDs().size())
|
||||
{
|
||||
const HashTable<labelList, word>::const_iterator iter =
|
||||
groupPatchIDs().find(key);
|
||||
|
||||
if (iter != groupPatchIDs().end())
|
||||
{
|
||||
labelHashSet indexSet(indices);
|
||||
|
||||
const labelList& patchIDs = iter();
|
||||
forAll(patchIDs, j)
|
||||
{
|
||||
if (indexSet.insert(patchIDs[j]))
|
||||
{
|
||||
indices.append(patchIDs[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
indices.setSize(nFound);
|
||||
}
|
||||
}
|
||||
|
||||
@ -552,7 +647,8 @@ Foam::label Foam::polyBoundaryMesh::whichPatch(const label faceIndex) const
|
||||
Foam::labelHashSet Foam::polyBoundaryMesh::patchSet
|
||||
(
|
||||
const UList<wordRe>& patchNames,
|
||||
const bool warnNotFound
|
||||
const bool warnNotFound,
|
||||
const bool usePatchGroups
|
||||
) const
|
||||
{
|
||||
const wordList allPatchNames(this->names());
|
||||
@ -560,24 +656,58 @@ Foam::labelHashSet Foam::polyBoundaryMesh::patchSet
|
||||
|
||||
forAll(patchNames, i)
|
||||
{
|
||||
const word& patchName = patchNames[i];
|
||||
|
||||
// Treat the given patch names as wild-cards and search the set
|
||||
// of all patch names for matches
|
||||
labelList patchIDs = findStrings(patchNames[i], allPatchNames);
|
||||
|
||||
if (patchIDs.empty() && warnNotFound)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"polyBoundaryMesh::patchSet"
|
||||
"(const wordReList&, const bool) const"
|
||||
) << "Cannot find any patch names matching " << patchNames[i]
|
||||
<< endl;
|
||||
}
|
||||
labelList patchIDs = findStrings(patchName, allPatchNames);
|
||||
|
||||
forAll(patchIDs, j)
|
||||
{
|
||||
ids.insert(patchIDs[j]);
|
||||
}
|
||||
|
||||
if (patchIDs.empty())
|
||||
{
|
||||
if (usePatchGroups)
|
||||
{
|
||||
const wordList allGroupNames = groupPatchIDs().toc();
|
||||
|
||||
// Regard as group name
|
||||
labelList groupIDs = findStrings(patchName, allGroupNames);
|
||||
|
||||
forAll(groupIDs, i)
|
||||
{
|
||||
const word& name = allGroupNames[groupIDs[i]];
|
||||
const labelList& extraPatchIDs = groupPatchIDs()[name];
|
||||
|
||||
forAll(extraPatchIDs, extraI)
|
||||
{
|
||||
ids.insert(extraPatchIDs[extraI]);
|
||||
}
|
||||
}
|
||||
|
||||
if (groupIDs.empty() && warnNotFound)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"polyBoundaryMesh::patchSet"
|
||||
"(const wordReList&, const bool, const bool) const"
|
||||
) << "Cannot find any patch or group names matching "
|
||||
<< patchName
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
else if (warnNotFound)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"polyBoundaryMesh::patchSet"
|
||||
"(const wordReList&, const bool, const bool) const"
|
||||
) << "Cannot find any patch names matching " << patchName
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ids;
|
||||
@ -778,6 +908,7 @@ void Foam::polyBoundaryMesh::updateMesh()
|
||||
{
|
||||
neighbourEdgesPtr_.clear();
|
||||
patchIDPtr_.clear();
|
||||
groupPatchIDsPtr_.clear();
|
||||
|
||||
PstreamBuffers pBufs(Pstream::defaultCommsType);
|
||||
|
||||
|
||||
@ -70,6 +70,8 @@ class polyBoundaryMesh
|
||||
|
||||
mutable autoPtr<labelList> patchIDPtr_;
|
||||
|
||||
mutable autoPtr<HashTable<labelList, word> > groupPatchIDsPtr_;
|
||||
|
||||
//- Edges of neighbouring patches
|
||||
mutable autoPtr<List<labelPairList> > neighbourEdgesPtr_;
|
||||
|
||||
@ -153,8 +155,12 @@ public:
|
||||
//- Return a list of physical types
|
||||
wordList physicalTypes() const;
|
||||
|
||||
//- Return patch indices for all matches
|
||||
labelList findIndices(const keyType&) const;
|
||||
//- Return patch indices for all matches. Optionally matches patchGroups
|
||||
labelList findIndices
|
||||
(
|
||||
const keyType&,
|
||||
const bool usePatchGroups = false
|
||||
) const;
|
||||
|
||||
//- Return patch index for the first match, return -1 if not found
|
||||
label findIndex(const keyType&) const;
|
||||
@ -168,12 +174,17 @@ public:
|
||||
//- Per boundary face label the patch index
|
||||
const labelList& patchID() const;
|
||||
|
||||
//- Per patch group the patch indices
|
||||
const HashTable<labelList, word>& groupPatchIDs() const;
|
||||
|
||||
//- Return the set of patch IDs corresponding to the given names
|
||||
// By default warns if given names are not found.
|
||||
// By default warns if given names are not found. Optionally
|
||||
// matches to patchGroups as well as patchNames
|
||||
labelHashSet patchSet
|
||||
(
|
||||
const UList<wordRe>& patchNames,
|
||||
const bool warnNotFound = true
|
||||
const bool warnNotFound = true,
|
||||
const bool usePatchGroups = false
|
||||
) const;
|
||||
|
||||
//- Check whether all procs have all patches and in same order. Return
|
||||
|
||||
@ -23,8 +23,8 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvMesh.H"
|
||||
#include "fvBoundaryMesh.H"
|
||||
#include "fvMesh.H"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
@ -87,6 +87,16 @@ Foam::label Foam::fvBoundaryMesh::findPatchID(const word& patchName) const
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::fvBoundaryMesh::findIndices
|
||||
(
|
||||
const keyType& key,
|
||||
const bool usePatchGroups
|
||||
) const
|
||||
{
|
||||
return mesh().boundaryMesh().findIndices(key, usePatchGroups);
|
||||
}
|
||||
|
||||
|
||||
void Foam::fvBoundaryMesh::movePoints()
|
||||
{
|
||||
forAll(*this, patchI)
|
||||
|
||||
@ -109,6 +109,9 @@ public:
|
||||
//- Find patch index given a name
|
||||
label findPatchID(const word& patchName) const;
|
||||
|
||||
//- Find patch indices given a name
|
||||
labelList findIndices(const keyType&, const bool useGroups) const;
|
||||
|
||||
|
||||
//- Correct patches after moving points
|
||||
void movePoints();
|
||||
|
||||
Reference in New Issue
Block a user