51 bool Foam::polyBoundaryMesh::hasGroupIDs()
const 56 return !groupIDsPtr_->empty();
63 if (!
p.inGroups().empty())
73 void Foam::polyBoundaryMesh::calcGroupIDs()
const 80 groupIDsPtr_.emplace(16);
81 auto& groupLookup = *groupIDsPtr_;
87 for (
const word& groupName :
patches[patchi].inGroups())
89 groupLookup(groupName).push_back(patchi);
96 if (groupLookup.empty())
100 else if (groupLookup.erase(
patches[patchi].
name()))
104 <<
"' which clashes with patch " << patchi
105 <<
" of the same name." 112 void Foam::polyBoundaryMesh::populate(PtrList<entry>&& entries)
114 clearLocalAddressing();
129 entries[patchi].keyword(),
130 entries[patchi].
dict(),
141 bool Foam::polyBoundaryMesh::readIOcontents(
const bool allowOptionalRead)
143 bool updated =
false;
144 PtrList<entry> entries;
148 this->isReadRequired()
149 || (allowOptionalRead && this->isReadOptional() && this->headerOk())
153 warnNoRereading<polyBoundaryMesh>();
156 Istream& is = readStream(typeName);
168 populate(std::move(entries));
187 readIOcontents(
false);
228 if (!readIOcontents(
true))
246 PtrList<entry>&& entries
253 if (!readIOcontents(
true))
255 populate(std::move(entries));
282 void Foam::polyBoundaryMesh::clearLocalAddressing()
284 neighbourEdgesPtr_.reset(
nullptr);
285 patchIDPtr_.reset(
nullptr);
286 groupIDsPtr_.reset(
nullptr);
292 clearLocalAddressing();
305 void Foam::polyBoundaryMesh::calcGeometry()
320 operator[](patchi).initGeometry(pBufs);
323 pBufs.finishedSends();
327 operator[](patchi).calcGeometry(pBufs);
335 pBufs.finishedSends();
337 for (
const auto& schedEval : patchSchedule)
339 const label patchi = schedEval.patch;
343 operator[](patchi).initGeometry(pBufs);
347 operator[](patchi).calcGeometry(pBufs);
362 mesh_.nBoundaryFaces(),
363 mesh_.nInternalFaces()
373 mesh_.nBoundaryFaces(),
374 mesh_.nInternalFaces()
407 <<
"Neighbour edge addressing not correct across parallel" 408 <<
" boundaries." <<
endl;
411 if (!neighbourEdgesPtr_)
413 neighbourEdgesPtr_.emplace(size());
414 auto& neighbourEdges = *neighbourEdgesPtr_;
417 label nEdgePairs = 0;
420 const polyPatch&
pp = operator[](patchi);
424 for (
labelPair& edgeInfo : neighbourEdges[patchi])
435 EdgeMap<labelPair> pointsToEdge(nEdgePairs);
439 const polyPatch&
pp = operator[](patchi);
446 edgei < edges.size();
451 const edge&
e = edges[edgei];
456 auto fnd = pointsToEdge.find(meshEdge);
480 neighbourEdges[edgeInfo[0]][edgeInfo[1]]
486 pointsToEdge.erase(meshEdge);
491 if (pointsToEdge.size())
494 <<
"Not all boundary edges of patches match up." <<
nl 495 <<
"Is the outside of your mesh multiply connected?" 501 const polyPatch&
pp = operator[](patchi);
509 if (edgeInfo[0] == -1 || edgeInfo[1] == -1)
515 <<
"Not all boundary edges of patches match up." <<
nl 516 <<
"Edge " << edgei <<
" on patch " <<
pp.name()
519 <<
" edge on any other patch." <<
nl 520 <<
"Is the outside of your mesh multiply connected?" 527 return *neighbourEdgesPtr_;
535 patchIDPtr_.emplace(mesh_.nBoundaryFaces());
536 auto& list = *patchIDPtr_;
557 const label bndFacei = (meshFacei - mesh_.nInternalFaces());
561 (bndFacei >= 0 && bndFacei < mesh_.nBoundaryFaces())
572 forAll(meshFaceIndices, i)
588 return *groupIDsPtr_;
594 const word& groupName,
598 groupIDsPtr_.reset(
nullptr);
607 if (pending.test(patchi))
609 pending.
unset(patchi);
610 patches[patchi].addGroup(groupName);
617 if (pending.test(patchi))
619 patches[patchi].removeGroup(groupName);
633 if (isA<processorPolyPatch>(
p))
653 if (isA<processorPolyPatch>(
p))
671 if (isA<processorPolyPatch>(
p))
698 PtrListOps::get<word>
701 [](
const polyPatch&
p) {
return p.physicalType(); }
709 PtrListOps::get<label>
720 PtrListOps::get<label>
731 PtrListOps::get<labelRange>
741 return this->groupPatchIDs().sortedToc();
747 return mesh_.nInternalFaces();
753 return mesh_.nBoundaryFaces();
759 return labelRange(mesh_.nInternalFaces(), mesh_.nBoundaryFaces());
771 return (*
this)[patchi].range();
787 const bool checkGroups = (useGroups && this->hasGroupIDs());
795 const auto& groupLookup = groupPatchIDs();
798 if (matcher(iter.key()))
801 ids.insert(iter.val());
826 else if (checkGroups)
828 const auto iter = groupPatchIDs().cfind(matcher);
833 ids.insert(iter.val());
838 return ids.sortedToc();
844 const wordRes& matcher,
852 else if (matcher.size() == 1)
854 return this->indices(matcher.front(), useGroups);
860 if (useGroups && this->hasGroupIDs())
864 const auto& groupLookup = groupPatchIDs();
867 if (matcher(iter.key()))
870 ids.insert(iter.val());
884 return ids.sortedToc();
890 const wordRes& allow,
895 if (allow.empty() && deny.empty())
901 const wordRes::filter matcher(allow, deny);
906 if (useGroups && this->hasGroupIDs())
910 const auto& groupLookup = groupPatchIDs();
913 if (matcher(iter.key()))
916 ids.insert(iter.val());
930 return ids.sortedToc();
946 const word& patchName,
950 if (patchName.empty())
965 <<
"Patch '" << patchName <<
"' not found. " 966 <<
"Available patch names";
971 <<
" in region '" << mesh_.name() <<
"'";
982 Pout<<
"label polyBoundaryMesh::findPatchID(const word&) const" 983 <<
"Patch named " << patchName <<
" not found. " 984 <<
"Available patch names: " <<
names() <<
endl;
995 if (meshFacei <
mesh().nInternalFaces())
1000 else if (meshFacei >=
mesh().nFaces())
1004 <<
"Face " << meshFacei
1005 <<
" out of bounds. Number of geometric faces " <<
mesh().
nFaces()
1017 const label patchi =
1029 const label patchi =
1036 [](
const polyPatch&
p, label val) {
return (
p.start() <= val); }
1039 if (patchi < 0 || !
patches[patchi].
range().contains(meshFacei))
1043 <<
"Face " << meshFacei <<
" not found in any of the patches " 1045 <<
"The patches appear to be inconsistent with the mesh :" 1047 <<
" total number of faces:" <<
mesh().
nFaces()
1062 forAll(meshFaceIndices, i)
1064 output[i] = whichPatchFace(meshFaceIndices[i]);
1072 const UList<wordRe>&
select,
1073 const bool warnNotFound,
1074 const bool useGroups
1090 const bool checkGroups = (useGroups && this->hasGroupIDs());
1092 for (
const wordRe& matcher :
select)
1096 for (label i = 0; i < len; ++i)
1105 if (missed && checkGroups)
1108 if (matcher.isPattern())
1112 if (matcher.match(iter.key()))
1115 ids.insert(iter.val());
1122 const auto iter = groupPatchIDs().cfind(matcher);
1127 ids.insert(iter.val());
1133 if (missed && warnNotFound)
1138 <<
"Cannot find any patch or group names matching " 1144 <<
"Cannot find any patch names matching " 1162 DynamicList<word> matchedGroups(1);
1167 const HashTable<labelList>& groupLookup = this->groupPatchIDs();
1177 label nMatch = nonGroupPatches.
erase(groupPatchSet);
1179 if (nMatch == groupPatchSet.size())
1181 matchedGroups.push_back(iter.key());
1183 else if (nMatch != 0)
1186 nonGroupPatches.transfer(oldNonGroupPatches);
1190 groups.transfer(matchedGroups);
1201 const polyBoundaryMesh& bm = *
this;
1203 bool hasError =
false;
1213 if (!isA<processorPolyPatch>(bm[patchi]))
1215 if (nonProci != patchi)
1220 if (
debug || report)
1222 Pout<<
" ***Problem with boundary patch " << patchi
1223 <<
" name:" << bm[patchi].
name()
1224 <<
" type:" << bm[patchi].
type()
1225 <<
" - seems to be preceeded by processor patches." 1226 <<
" This is usually a problem." <<
endl;
1231 localNames[nonProci] = bm[patchi].
name();
1232 localTypes[nonProci] = bm[patchi].
type();
1237 localNames.resize(nonProci);
1238 localTypes.resize(nonProci);
1243 const globalIndex
procAddr(globalIndex::gatherNonLocal{}, nonProci);
1251 const auto procNames(allNames.slice(
procAddr.
range(proci)));
1252 const auto procTypes(allTypes.slice(
procAddr.
range(proci)));
1254 if (procNames != localNames || procTypes != localTypes)
1258 if (
debug || report)
1260 Info<<
" ***Inconsistent patches across processors, " 1261 "processor0 has patch names:" << localNames
1262 <<
" patch types:" << localTypes
1263 <<
" processor" << proci
1264 <<
" has patch names:" << procNames
1265 <<
" patch types:" << procTypes
1279 const polyBoundaryMesh& bm = *
this;
1281 bool hasError =
false;
1287 if (bm[patchi].start() != nextPatchStart && !hasError)
1291 Info<<
" ****Problem with boundary patch " << patchi
1292 <<
" named " << bm[patchi].name()
1293 <<
" of type " << bm[patchi].type()
1294 <<
". The patch should start on face no " << nextPatchStart
1295 <<
" and the patch specifies " << bm[patchi].start()
1297 <<
"Possibly consecutive patches have this same problem." 1298 <<
" Suppressing future warnings." <<
endl;
1301 if (!
patchNames.insert(bm[patchi].name()) && !hasError)
1305 Info<<
" ****Duplicate boundary patch " << patchi
1306 <<
" named " << bm[patchi].name()
1307 <<
" of type " << bm[patchi].type()
1309 <<
"Suppressing future warnings." <<
endl;
1312 nextPatchStart += bm[patchi].size();
1317 if (
debug || report)
1321 Pout<<
" ***Boundary definition is in error." <<
endl;
1325 Info<<
" Boundary definition OK." <<
endl;
1345 operator[](patchi).initMovePoints(pBufs,
p);
1348 pBufs.finishedSends();
1352 operator[](patchi).movePoints(pBufs,
p);
1360 pBufs.finishedSends();
1362 for (
const auto& schedEval : patchSchedule)
1364 const label patchi = schedEval.patch;
1368 operator[](patchi).initMovePoints(pBufs,
p);
1372 operator[](patchi).movePoints(pBufs,
p);
1381 neighbourEdgesPtr_.reset(
nullptr);
1382 patchIDPtr_.reset(
nullptr);
1383 groupIDsPtr_.reset(
nullptr);
1395 operator[](patchi).initUpdateMesh(pBufs);
1398 pBufs.finishedSends();
1402 operator[](patchi).updateMesh(pBufs);
1410 pBufs.finishedSends();
1412 for (
const auto& schedEval : patchSchedule)
1414 const label patchi = schedEval.patch;
1418 operator[](patchi).initUpdateMesh(pBufs);
1422 operator[](patchi).updateMesh(pBufs);
1432 const bool validBoundary
1443 patches[patchi].index() = patchi;
1447 groupIDsPtr_.reset(
nullptr);
1460 os << entries.size();
1462 if (entries.empty())
1471 for (
const auto&
pp : entries)
1485 const word& keyword,
1491 if (!keyword.empty())
1513 const bool writeOnProc
1525 const word& patchName
1528 const label patchi = findPatchID(patchName);
1533 <<
"Patch named " << patchName <<
" not found." <<
nl 1534 <<
"Available patch names: " <<
names() <<
endl 1538 return operator[](patchi);
1544 const word& patchName
1547 const label patchi = findPatchID(patchName);
1552 <<
"Patch named " << patchName <<
" not found." <<
nl 1553 <<
"Available patch names: " <<
names() <<
endl 1557 return operator[](patchi);
label findPatchID(const word &patchName, const bool allowNotFound=true) const
Find patch index given a name, return -1 if not found.
label nNonProcessorFaces() const
The number of boundary faces before the first processor patch.
labelRange range(const label proci) const
Return start/size range of proci data.
const labelList patchIDs(pbm.indices(polyPatchNames, true))
const polyBoundaryMesh & pbm
labelList patchSizes() const
Return a list of patch sizes.
const List< labelPairList > & neighbourEdges() const
Per patch the edges on the neighbouring patch.
void size(const label n)
Older name for setAddressableSize.
autoPtr< IOobject > clone() const
Clone.
labelList findMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Extract list indices for all items with 'name()' that matches.
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
Binary search to find the index of the last element in a sorted list that is less than value...
List< word > names(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
List of names generated by calling name() for each list item and filtered for matches.
virtual const fileName & name() const
The name of the stream.
errorManipArg< error, int > exit(error &err, const int errNo=1)
static int incrMsgType(int val=1) noexcept
Increment the message tag for standard messages.
const Field< point_type > & localPoints() const
Return pointField of points in patch.
virtual Ostream & write(const char c) override
Write character.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
virtual bool check(const char *operation) const
Check IOstream status for given operation.
List< edge > edgeList
List of edge.
void setGroup(const word &groupName, const labelUList &patchIDs)
Set/add group with patches.
const word & name() const noexcept
Return the object name.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
labelHashSet patchSet(const UList< wordRe > &select, const bool warnNotFound=true, const bool useGroups=true) const
Return the set of patch IDs corresponding to the given names.
A range or interval of labels defined by a start and a size.
polyBoundaryMesh(const polyBoundaryMesh &)=delete
No copy construct.
List< bool > select(const label n, const labelUList &locations)
Construct a selection list of bools (all false) with the given pre-size, subsequently add specified l...
constexpr char nl
The newline '\n' character (0x0a)
label start() const noexcept
The start label of boundary faces in the polyMesh face list.
bool empty() const noexcept
True if List is empty (ie, size() is zero)
Type type(bool followLink=true, bool checkGzip=false) const
Return the directory entry type: UNDEFINED, FILE, DIRECTORY (or SYMLINK).
virtual bool writeData(Ostream &os) const
The writeData member function required by regIOobject.
void reorder(const labelUList &oldToNew, const bool validBoundary)
Reorders patches. Ordering does not have to be done in.
Ostream & endl(Ostream &os)
Add newline and flush stream.
labelPair whichPatchFace(const label meshFacei) const
Lookup mesh face index and return (patchi, patchFacei) tuple or (-1, meshFacei) for internal faces...
const labelList & patchID() const
Per boundary face label the patch index.
static bool & parRun() noexcept
Test if this a parallel run.
void reorder(const labelUList &oldToNew, const bool check=false)
Reorder elements. Reordering must be unique (ie, shuffle).
wordList groupNames() const
A list of the group names (if any)
label nInternalEdges() const
Number of internal edges.
void clearGeom()
Clear geometry at this level and at patches.
Begin list [isseparator].
static int & msgType() noexcept
Message tag of standard messages.
labelRange range() const noexcept
The face range for all boundary faces.
List< lduScheduleEntry > lduSchedule
A List of lduSchedule entries.
List< labelPair > labelPairList
List of labelPair.
Functions to operate on Pointer Lists.
A simple container for options an IOstream can normally have.
static void gather(const labelUList &offsets, const label comm, const ProcIDsContainer &procIDs, const UList< Type > &fld, UList< Type > &allFld, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking)
Collect data in processor order on master (== procIDs[0]).
SubList< face > subList
Declare type of subList.
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc) const
Write using stream options.
Smooth ATC in cells next to a set of patches supplied by type.
wordList types() const
Return a list of patch types.
label nFaces() const noexcept
Number of mesh faces.
virtual const fileName & name() const override
Get the name of the output serial stream. (eg, the name of the Fstream file name) ...
void movePoints(const pointField &p)
Correct polyBoundaryMesh after moving points.
UList< label > labelUList
A UList of labels.
const labelList & meshPoints() const
Return labelList of mesh points in patch.
Extract name (as a word) from an object, typically using its name() method.
label nProcessorPatches() const
The number of processorPolyPatch patches.
#define forAll(list, i)
Loop across all elements in list.
labelList indices(const wordRe &matcher, const bool useGroups=true) const
The (sorted) patch indices for all matches, optionally matching patch groups.
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
PtrList< polyPatch > polyPatchList
Store lists of polyPatch as a PtrList.
void matchGroups(const labelUList &patchIDs, wordList &groups, labelHashSet &nonGroupPatches) const
Match the patches to groups.
void resize_null(const label newLen)
Set the addressed list to the given size, deleting all existing entries. Afterwards the list contains...
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
A non-owning sub-view of a List (allocated or unallocated storage).
UPtrList< const labelUList > faceCells() const
Return a list of faceCells for each patch.
vectorField pointField
pointField is a vectorField.
const dimensionedScalar e
Elementary charge.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
"scheduled" (MPI standard) : (MPI_Send, MPI_Recv)
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
A class for handling words, derived from Foam::string.
static word defaultRegion
Return the default region name.
bool checkDefinition(const bool report=false) const
Check boundary definition.
wordList names() const
Return a list of patch names.
label size() const noexcept
The number of entries in the list.
virtual Ostream & endBlock()
Write end block group.
wordList patchNames(nPatches)
const globalMeshData & globalData() const
Return parallel info (demand-driven)
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
label nInternalFaces() const noexcept
Number of internal faces.
auto key(const Type &t) -> std::enable_if_t< std::is_enum_v< Type >, std::underlying_type_t< Type > >
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
wordList physicalTypes() const
Return a list of physical types.
friend Ostream & operator(Ostream &os, const UPtrList< T > &list)
Write UPtrList to Ostream.
A HashTable similar to std::unordered_map.
const HashTable< labelList > & groupPatchIDs() const
The patch indices per patch group.
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
bool returnReduceOr(const bool value, const int communicator=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
errorManip< error > abort(error &err)
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings...
const faceList::subList faces() const
Return mesh faces for the entire boundary.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
void clear()
Clear the patch list and all demand-driven data.
bool checkParallelSync(const bool report=false) const
Check whether all procs have all patches and in same order.
label nEdges() const
Number of edges in patch.
void writeEntry(Ostream &os) const
Write as a plain list of entries.
int debug
Static debugging option.
void updateMesh()
Correct polyBoundaryMesh after topology update.
Pair< label > labelPair
A pair of labels.
OBJstream os(runTime.globalPath()/outputName)
std::enable_if_t< std::is_same_v< bool, TypeT >, bool > unset(const label i)
Unset the bool entry at specified position, always false for out-of-range access. ...
defineTypeNameAndDebug(combustionModel, 0)
compressionType compression() const noexcept
Get the stream compression.
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
labelList patchStarts() const
Return a list of patch start face indices.
labelRange subProcs() const noexcept
Range of process indices for addressed sub-offsets (processes)
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
List< word > wordList
List of word.
label nFaces() const noexcept
The number of boundary faces in the underlying mesh.
static commsTypes defaultCommsType
Default commsType.
#define WarningInFunction
Report a warning using Foam::Warning.
globalIndex procAddr(aMesh.nFaces())
List< labelRange > patchRanges() const
Return a list of patch ranges.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
void clearAddressing()
Clear addressing at this level and at patches.
bool good() const noexcept
True if next operation might succeed.
void reserve(label numEntries)
Reserve space for at least the specified number of elements (not the number of buckets) and regenerat...
const lduSchedule & patchSchedule() const noexcept
Order in which the patches should be initialised/evaluated corresponding to the schedule.
const polyBoundaryMesh & patches
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
void clear()
Clear the PtrList. Delete allocated entries and set size to zero.
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
static Ostream & output(Ostream &os, const IntRange< T > &range)
static autoPtr< polyPatch > New(const word &patchType, const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm)
Return pointer to a new patch created on freestore from components.
Mesh consisting of general polyhedral cells.
List< label > labelList
A List of labels.
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc=true) const
Write using stream options, but always UNCOMPRESSED.
virtual Ostream & endEntry()
Write end entry (';') followed by newline.
"buffered" : (MPI_Bsend, MPI_Recv)
A patch is a list of labels that address the faces in the global face list.
label nNonProcessor() const
The number of patches before the first processor patch.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
static void reduceOr(bool &value, const int communicator=worldComm)
Logical (or) reduction (MPI_AllReduce)
Defines the attributes of an object for which implicit objectRegistry management is supported...
List< bool > boolList
A List of bools.
bool isPattern() const noexcept
The wordRe is a pattern, not a literal string.
label findIndex(const wordRe &key) const
Return patch index for the first match, return -1 if not found.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Extract type (as a word) from an object, typically using its type() method.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
forAllConstIters(mixture.phases(), phase)
label firstMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Find first list item with 'name()' that matches, -1 on failure.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
const labelList::subList faceOwner() const
Return face owner for the entire boundary.