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);
100 <<
"' which clashes with patch " << patchi
101 <<
" of the same name." 108 void Foam::polyBoundaryMesh::populate(PtrList<entry>&& entries)
110 clearLocalAddressing();
125 entries[patchi].keyword(),
126 entries[patchi].
dict(),
137 bool Foam::polyBoundaryMesh::readIOcontents(
const bool allowOptionalRead)
139 bool updated =
false;
140 PtrList<entry> entries;
144 this->isReadRequired()
145 || (allowOptionalRead && this->isReadOptional() && this->headerOk())
149 warnNoRereading<polyBoundaryMesh>();
152 Istream& is = readStream(typeName);
164 populate(std::move(entries));
183 readIOcontents(
false);
224 if (!readIOcontents(
true))
242 PtrList<entry>&& entries
249 if (!readIOcontents(
true))
251 populate(std::move(entries));
278 void Foam::polyBoundaryMesh::clearLocalAddressing()
280 neighbourEdgesPtr_.reset(
nullptr);
281 patchIDPtr_.reset(
nullptr);
282 groupIDsPtr_.reset(
nullptr);
288 clearLocalAddressing();
301 void Foam::polyBoundaryMesh::calcGeometry()
316 operator[](patchi).initGeometry(pBufs);
319 pBufs.finishedSends();
323 operator[](patchi).calcGeometry(pBufs);
331 pBufs.finishedSends();
333 for (
const auto& schedEval : patchSchedule)
335 const label patchi = schedEval.patch;
339 operator[](patchi).initGeometry(pBufs);
343 operator[](patchi).calcGeometry(pBufs);
358 mesh_.nBoundaryFaces(),
359 mesh_.nInternalFaces()
369 mesh_.nBoundaryFaces(),
370 mesh_.nInternalFaces()
403 <<
"Neighbour edge addressing not correct across parallel" 404 <<
" boundaries." <<
endl;
407 if (!neighbourEdgesPtr_)
409 neighbourEdgesPtr_.emplace(size());
410 auto& neighbourEdges = *neighbourEdgesPtr_;
413 label nEdgePairs = 0;
416 const polyPatch&
pp = operator[](patchi);
420 for (
labelPair& edgeInfo : neighbourEdges[patchi])
431 EdgeMap<labelPair> pointsToEdge(nEdgePairs);
435 const polyPatch&
pp = operator[](patchi);
442 edgei < edges.size();
447 const edge&
e = edges[edgei];
452 auto fnd = pointsToEdge.find(meshEdge);
476 neighbourEdges[edgeInfo[0]][edgeInfo[1]]
482 pointsToEdge.erase(meshEdge);
487 if (pointsToEdge.size())
490 <<
"Not all boundary edges of patches match up." <<
nl 491 <<
"Is the outside of your mesh multiply connected?" 497 const polyPatch&
pp = operator[](patchi);
505 if (edgeInfo[0] == -1 || edgeInfo[1] == -1)
511 <<
"Not all boundary edges of patches match up." <<
nl 512 <<
"Edge " << edgei <<
" on patch " <<
pp.name()
515 <<
" edge on any other patch." <<
nl 516 <<
"Is the outside of your mesh multiply connected?" 523 return *neighbourEdgesPtr_;
531 patchIDPtr_.emplace(mesh_.nBoundaryFaces());
532 auto& list = *patchIDPtr_;
553 const label bndFacei = (meshFacei - mesh_.nInternalFaces());
557 (bndFacei >= 0 && bndFacei < mesh_.nBoundaryFaces())
568 forAll(meshFaceIndices, i)
584 return *groupIDsPtr_;
590 const word& groupName,
594 groupIDsPtr_.reset(
nullptr);
603 if (pending.test(patchi))
605 pending.
unset(patchi);
606 patches[patchi].addGroup(groupName);
613 if (pending.test(patchi))
615 patches[patchi].removeGroup(groupName);
629 if (isA<processorPolyPatch>(
p))
649 if (isA<processorPolyPatch>(
p))
674 PtrListOps::get<word>
677 [](
const polyPatch&
p) {
return p.physicalType(); }
685 PtrListOps::get<label>
696 PtrListOps::get<label>
707 PtrListOps::get<labelRange>
717 return this->groupPatchIDs().sortedToc();
723 return mesh_.nInternalFaces();
729 return mesh_.nBoundaryFaces();
735 return labelRange(mesh_.nInternalFaces(), mesh_.nBoundaryFaces());
747 return (*
this)[patchi].range();
763 const bool checkGroups = (useGroups && this->hasGroupIDs());
771 const auto& groupLookup = groupPatchIDs();
774 if (matcher(iter.key()))
777 ids.insert(iter.val());
802 else if (checkGroups)
804 const auto iter = groupPatchIDs().cfind(matcher);
809 ids.insert(iter.val());
814 return ids.sortedToc();
820 const wordRes& matcher,
828 else if (matcher.size() == 1)
830 return this->indices(matcher.front(), useGroups);
836 if (useGroups && this->hasGroupIDs())
838 ids.reserve(this->size());
840 const auto& groupLookup = groupPatchIDs();
843 if (matcher(iter.key()))
846 ids.insert(iter.val());
860 return ids.sortedToc();
867 const wordRes& ignore,
873 return this->indices(
select, useGroups);
876 const wordRes::filter matcher(
select, ignore);
881 if (useGroups && this->hasGroupIDs())
883 ids.reserve(this->size());
885 const auto& groupLookup = groupPatchIDs();
888 if (matcher(iter.key()))
891 ids.insert(iter.val());
905 return ids.sortedToc();
921 const word& patchName,
925 if (patchName.empty())
940 <<
"Patch '" << patchName <<
"' not found. " 941 <<
"Available patch names";
946 <<
" in region '" << mesh_.name() <<
"'";
957 Pout<<
"label polyBoundaryMesh::findPatchID(const word&) const" 958 <<
"Patch named " << patchName <<
" not found. " 959 <<
"Available patch names: " <<
names() <<
endl;
970 if (meshFacei <
mesh().nInternalFaces())
975 else if (meshFacei >=
mesh().nFaces())
979 <<
"Face " << meshFacei
980 <<
" out of bounds. Number of geometric faces " <<
mesh().
nFaces()
1004 const label patchi =
1011 [](
const polyPatch&
p, label val) {
return (
p.start() <= val); }
1014 if (patchi < 0 || !
patches[patchi].
range().contains(meshFacei))
1018 <<
"Face " << meshFacei <<
" not found in any of the patches " 1020 <<
"The patches appear to be inconsistent with the mesh :" 1022 <<
" total number of faces:" <<
mesh().
nFaces()
1037 forAll(meshFaceIndices, i)
1039 output[i] = whichPatchFace(meshFaceIndices[i]);
1047 const UList<wordRe>&
select,
1048 const bool warnNotFound,
1049 const bool useGroups
1065 const bool checkGroups = (useGroups && this->hasGroupIDs());
1067 for (
const wordRe& matcher :
select)
1071 for (label i = 0; i < len; ++i)
1080 if (missed && checkGroups)
1083 if (matcher.isPattern())
1087 if (matcher.match(iter.key()))
1090 ids.insert(iter.val());
1097 const auto iter = groupPatchIDs().cfind(matcher);
1102 ids.insert(iter.val());
1108 if (missed && warnNotFound)
1113 <<
"Cannot find any patch or group names matching " 1119 <<
"Cannot find any patch names matching " 1137 DynamicList<word> matchedGroups(1);
1142 const HashTable<labelList>& groupLookup = this->groupPatchIDs();
1152 label nMatch = nonGroupPatches.
erase(groupPatchSet);
1154 if (nMatch == groupPatchSet.size())
1156 matchedGroups.push_back(iter.key());
1158 else if (nMatch != 0)
1161 nonGroupPatches.transfer(oldNonGroupPatches);
1165 groups.transfer(matchedGroups);
1176 const polyBoundaryMesh& bm = *
this;
1178 bool hasError =
false;
1188 if (!isA<processorPolyPatch>(bm[patchi]))
1190 if (nonProci != patchi)
1195 if (
debug || report)
1197 Pout<<
" ***Problem with boundary patch " << patchi
1198 <<
" name:" << bm[patchi].
name()
1199 <<
" type:" << bm[patchi].
type()
1200 <<
" - seems to be preceeded by processor patches." 1201 <<
" This is usually a problem." <<
endl;
1206 localNames[nonProci] = bm[patchi].
name();
1207 localTypes[nonProci] = bm[patchi].
type();
1212 localNames.resize(nonProci);
1213 localTypes.resize(nonProci);
1218 const globalIndex
procAddr(globalIndex::gatherNonLocal{}, nonProci);
1226 const auto procNames(allNames.slice(
procAddr.
range(proci)));
1227 const auto procTypes(allTypes.slice(
procAddr.
range(proci)));
1229 if (procNames != localNames || procTypes != localTypes)
1233 if (
debug || report)
1235 Info<<
" ***Inconsistent patches across processors, " 1236 "processor0 has patch names:" << localNames
1237 <<
" patch types:" << localTypes
1238 <<
" processor" << proci
1239 <<
" has patch names:" << procNames
1240 <<
" patch types:" << procTypes
1254 const polyBoundaryMesh& bm = *
this;
1256 bool hasError =
false;
1262 if (bm[patchi].start() != nextPatchStart && !hasError)
1266 Info<<
" ****Problem with boundary patch " << patchi
1267 <<
" named " << bm[patchi].name()
1268 <<
" of type " << bm[patchi].type()
1269 <<
". The patch should start on face no " << nextPatchStart
1270 <<
" and the patch specifies " << bm[patchi].start()
1272 <<
"Possibly consecutive patches have this same problem." 1273 <<
" Suppressing future warnings." <<
endl;
1276 if (!
patchNames.insert(bm[patchi].name()) && !hasError)
1280 Info<<
" ****Duplicate boundary patch " << patchi
1281 <<
" named " << bm[patchi].name()
1282 <<
" of type " << bm[patchi].type()
1284 <<
"Suppressing future warnings." <<
endl;
1287 nextPatchStart += bm[patchi].size();
1292 if (
debug || report)
1296 Pout<<
" ***Boundary definition is in error." <<
endl;
1300 Info<<
" Boundary definition OK." <<
endl;
1320 operator[](patchi).initMovePoints(pBufs,
p);
1323 pBufs.finishedSends();
1327 operator[](patchi).movePoints(pBufs,
p);
1335 pBufs.finishedSends();
1337 for (
const auto& schedEval : patchSchedule)
1339 const label patchi = schedEval.patch;
1343 operator[](patchi).initMovePoints(pBufs,
p);
1347 operator[](patchi).movePoints(pBufs,
p);
1356 neighbourEdgesPtr_.reset(
nullptr);
1357 patchIDPtr_.reset(
nullptr);
1358 groupIDsPtr_.reset(
nullptr);
1370 operator[](patchi).initUpdateMesh(pBufs);
1373 pBufs.finishedSends();
1377 operator[](patchi).updateMesh(pBufs);
1385 pBufs.finishedSends();
1387 for (
const auto& schedEval : patchSchedule)
1389 const label patchi = schedEval.patch;
1393 operator[](patchi).initUpdateMesh(pBufs);
1397 operator[](patchi).updateMesh(pBufs);
1407 const bool validBoundary
1418 patches[patchi].index() = patchi;
1422 groupIDsPtr_.reset(
nullptr);
1435 os << entries.size();
1437 if (entries.empty())
1446 for (
const auto&
pp : entries)
1460 const word& keyword,
1466 if (!keyword.empty())
1488 const bool writeOnProc
1500 const word& patchName
1503 const label patchi = findPatchID(patchName);
1508 <<
"Patch named " << patchName <<
" not found." <<
nl 1509 <<
"Available patch names: " <<
names() <<
endl 1513 return operator[](patchi);
1519 const word& patchName
1522 const label patchi = findPatchID(patchName);
1527 <<
"Patch named " << patchName <<
" not found." <<
nl 1528 <<
"Available patch names: " <<
names() <<
endl 1532 return operator[](patchi);
label findPatchID(const word &patchName, const bool allowNotFound=true) const
Find patch index given a name, return -1 if not found.
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.
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type unset(const label i)
Unset the bool entry at specified position, always false for out-of-range access. ...
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.
static void reduceOr(bool &value, const label communicator=worldComm)
Logical (or) reduction (MPI_AllReduce)
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.
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
Return (sorted) patch indices for all matches.
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 List obtained as a section of another List.
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)
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.
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...
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)
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.
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
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.
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.
static void gather(const labelUList &offsets, const label comm, const ProcIDsContainer &procIDs, const UList< Type > &fld, List< Type > &allFld, const int tag=UPstream::msgType(), const UPstream::commsTypes=UPstream::commsTypes::nonBlocking)
Collect data in processor order on master (== procIDs[0]).
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.
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
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.