40 template<
class ZoneType,
class MeshType>
50 template<
class ZoneType,
class MeshType>
54 const PtrList<ZoneType>& zones = *
this;
57 for (
const ZoneType& zn : zones)
66 template<
class ZoneType,
class MeshType>
72 <<
"zone map already calculated" 77 zoneMapPtr_.reset(
new Map<label>());
78 auto& map = *zoneMapPtr_;
83 map.reserve(this->totalSize());
85 const PtrList<ZoneType>& zones = *
this;
89 for (
const ZoneType& zn : zones)
91 for (
const label
id : static_cast<const labelList&>(zn))
94 const auto fnd = map.cfind(
id);
97 map.insert(
id, zonei);
99 else if (fnd.val() != zonei)
103 if (!additionalMapPtr_)
107 for (
const ZoneType& zn : zones)
112 : static_cast<const labelList&>(zn)
120 auto& additionalMap = *additionalMapPtr_;
121 additionalMap[id].push_uniq(zonei);
129 if (additionalMapPtr_)
131 auto& additionalMap = *additionalMapPtr_;
139 const label zonei = map[id];
140 const label index =
findLower(zones, zonei);
147 map.set(
id, zones[0]);
148 for (label i = 0; i < zones.size() && i <= index; i++)
150 zones[i] = zones[i+1];
152 zones[index+1] = zonei;
161 template<
class ZoneType,
class MeshType>
167 return !groupIDsPtr_->
empty();
170 const PtrList<ZoneType>& zones = *
this;
172 for (
const ZoneType& zn : zones)
174 if (!zn.inGroups().empty())
184 template<
class ZoneType,
class MeshType>
192 groupIDsPtr_.reset(
new HashTable<labelList>(16));
193 auto& groupLookup = *groupIDsPtr_;
195 const PtrList<ZoneType>& zones = *
this;
199 for (
const word& groupName : zones[zonei].inGroups())
201 groupLookup(groupName).push_back(zonei);
208 if (groupLookup.empty())
212 else if (groupLookup.erase(zones[zonei].name()))
215 <<
"Removed group '" << zones[zonei].name()
216 <<
"' which clashes with zone " << zonei
217 <<
" of the same name." 224 template<
class ZoneType,
class MeshType>
227 PtrList<entry>&& entries
230 clearLocalAddressing();
232 PtrList<ZoneType>& zones = *
this;
234 zones.resize_null(entries.size());
252 entries[zonei].keyword(),
253 entries[zonei].
dict(),
264 template<
class ZoneType,
class MeshType>
267 const bool allowOptionalRead
270 bool updated =
false;
271 PtrList<entry> entries;
276 || (allowOptionalRead && isReadOptional() && headerOk())
280 warnNoRereading<ZoneMesh<ZoneType, MeshType>>();
283 Istream& is = readStream(typeName);
296 populate(std::move(entries));
305 template<
class ZoneType,
class MeshType>
318 readIOcontents(
true);
322 template<
class ZoneType,
class MeshType>
326 const MeshType&
mesh,
336 template<
class ZoneType,
class MeshType>
340 const MeshType&
mesh,
350 readIOcontents(
true);
354 template<
class ZoneType,
class MeshType>
358 const MeshType&
mesh,
366 if (!readIOcontents(
true))
374 zones.
set(zonei, list[zonei].clone(*
this));
380 template<
class ZoneType,
class MeshType>
384 const MeshType&
mesh,
385 PtrList<entry>&& entries
392 if (!readIOcontents(
true))
394 populate(std::move(entries));
402 template<
class ZoneType,
class MeshType>
415 template<
class ZoneType,
class MeshType>
418 const label objectIndex
421 return zoneMap().lookup(objectIndex, -1);
425 template<
class ZoneType,
class MeshType>
428 const label objectIndex,
433 const auto fnd = zoneMap().cfind(objectIndex);
438 if (additionalMapPtr_)
440 const auto& additionalMap = *additionalMapPtr_;
441 if (objectIndex < additionalMap.size())
443 for (
const label zonei : additionalMap[objectIndex])
454 template<
class ZoneType,
class MeshType>
461 template<
class ZoneType,
class MeshType>
468 template<
class ZoneType,
class MeshType>
471 return this->groupZoneIDs().sortedToc();
475 template<
class ZoneType,
class MeshType>
485 template<
class ZoneType,
class MeshType>
496 template<
class ZoneType,
class MeshType>
506 template<
class ZoneType,
class MeshType>
519 template<
class ZoneType,
class MeshType>
533 template<
class ZoneType,
class MeshType>
546 const bool checkGroups = (useGroups && this->hasGroupIDs());
559 const auto& groupLookup = groupZoneIDs();
562 if (matcher(iter.key()))
565 ids.insert(iter.val());
590 else if (checkGroups)
592 const auto iter = groupZoneIDs().cfind(matcher);
597 ids.insert(iter.val());
602 return ids.sortedToc();
606 template<
class ZoneType,
class MeshType>
617 else if (matcher.
size() == 1)
619 return this->indices(matcher.
front(), useGroups);
625 if (useGroups && this->hasGroupIDs())
629 const auto& groupLookup = groupZoneIDs();
632 if (matcher(iter.key()))
635 ids.insert(iter.val());
649 return ids.sortedToc();
653 template<
class ZoneType,
class MeshType>
667 const wordRes::filter matcher(allow, deny);
672 if (useGroups && this->hasGroupIDs())
676 const auto& groupLookup = groupZoneIDs();
679 if (matcher(iter.key()))
682 ids.insert(iter.val());
696 return ids.sortedToc();
700 template<
class ZoneType,
class MeshType>
714 template<
class ZoneType,
class MeshType>
717 const wordRes& matcher
728 template<
class ZoneType,
class MeshType>
734 if (zoneName.empty())
744 <<
"Zone named " << zoneName <<
" not found. " 745 <<
"List of available zone names: " <<
names() <<
endl;
748 if (disallowGenericZones != 0)
750 Info<<
"Creating dummy zone " << zoneName <<
endl;
751 auto& zm =
const_cast<ZoneMesh<ZoneType, MeshType>&
>(*this);
752 zm.emplace_back(zoneName, zm.size(), zm);
760 template<
class ZoneType,
class MeshType>
766 if (zoneName.empty())
771 const PtrList<ZoneType>& zones = *
this;
773 for (
auto iter = zones.begin(); iter != zones.end(); ++iter)
775 const ZoneType* ptr = iter.
get();
777 if (ptr && zoneName == ptr->name())
784 if (disallowGenericZones != 0)
786 Info<<
"Creating dummy zone " << zoneName <<
endl;
787 auto& zm =
const_cast<ZoneMesh<ZoneType, MeshType>&
>(*this);
788 zm.emplace_back(zoneName, zm.size(), zm);
795 template<
class ZoneType,
class MeshType>
801 return const_cast<ZoneType*
>(this->cfindZone(zoneName));
805 template<
class ZoneType,
class MeshType>
813 for (
const label zonei : zoneIds)
816 if (zonei < 0 || zonei >= this->size())
819 << ZoneType::typeName <<
" " 820 << zonei <<
" out of range [0," << this->size() <<
")" 827 static_cast<const labelList&>(this->
operator[](zonei))
835 template<
class ZoneType,
class MeshType>
843 return this->selection(this->indices(matcher, useGroups));
847 template<
class ZoneType,
class MeshType>
855 return this->selection(this->indices(matcher, useGroups));
859 template<
class ZoneType,
class MeshType>
868 return *groupIDsPtr_;
872 template<
class ZoneType,
class MeshType>
875 const word& groupName,
879 groupIDsPtr_.reset(
nullptr);
886 for (
const label zonei :
zoneIDs)
888 if (pending.test(zonei))
890 pending.
unset(zonei);
891 zones[zonei].addGroup(groupName);
898 if (pending.test(zonei))
900 zones[zonei].removeGroup(groupName);
907 template<
class ZoneType,
class MeshType>
910 zoneMapPtr_.reset(
nullptr);
911 additionalMapPtr_.reset(
nullptr);
912 groupIDsPtr_.reset(
nullptr);
916 template<
class ZoneType,
class MeshType>
919 clearLocalAddressing();
923 for (ZoneType& zn : zones)
925 zn.clearAddressing();
930 template<
class ZoneType,
class MeshType>
933 PtrList<ZoneType>& zones = *
this;
935 for (ZoneType& zn : zones)
937 zn.clearPrimitives();
942 template<
class ZoneType,
class MeshType>
950 template<
class ZoneType,
class MeshType>
956 bool hasError =
false;
960 for (
const ZoneType& zn : zones)
962 hasError |= zn.checkDefinition(report);
969 template<
class ZoneType,
class MeshType>
975 if (!UPstream::parRun())
980 const PtrList<ZoneType>& zones = *
this;
982 bool hasError =
false;
985 const wordList localTypes(this->types());
992 globalIndex::gatherNonLocal{},
1000 for (
const int proci :
procAddr.subProcs())
1002 const auto procNames(allNames.slice(
procAddr.range(proci)));
1003 const auto procTypes(allTypes.slice(
procAddr.range(proci)));
1005 if (procNames != localNames || procTypes != localTypes)
1009 if (
debug || report)
1011 Info<<
" ***Inconsistent zones across processors, " 1012 "processor 0 has zone names:" << localNames
1013 <<
" zone types:" << localTypes
1014 <<
" processor " << proci
1015 <<
" has zone names:" << procNames
1016 <<
" zone types:" << procTypes
1027 for (
const ZoneType& zn : zones)
1029 if (zn.checkParallelSync(
false))
1033 if (
debug || (report && UPstream::master()))
1035 Info<<
" ***Zone " << zn.name()
1036 <<
" of type " << zn.type()
1037 <<
" is not correctly synchronised" 1038 <<
" across coupled boundaries." 1039 <<
" (coupled faces are either not both" 1040 <<
" present in set or have same flipmap)" <<
endl;
1050 template<
class ZoneType,
class MeshType>
1053 PtrList<ZoneType>& zones = *
this;
1055 for (ZoneType& zn : zones)
1062 template<
class ZoneType,
class MeshType>
1066 if (zoneNames.empty())
1068 this->removeMetaData();
1073 meta.
set(
"names", zoneNames);
1078 template<
class ZoneType,
class MeshType>
1088 template<
class ZoneType,
class MeshType>
1091 const word& zoneName
1094 const label zonei = findZoneID(zoneName);
1099 <<
"Zone named " << zoneName <<
" not found." <<
nl 1100 <<
"Available zone names: " <<
names() <<
endl 1104 return operator[](zonei);
1108 template<
class ZoneType,
class MeshType>
1111 const word& zoneName
1114 const label zonei = findZoneID(zoneName);
1119 <<
"Zone named " << zoneName <<
" not found." <<
nl 1120 <<
"Available zone names: " <<
names() <<
endl 1124 return operator[](zonei);
1128 template<
class ZoneType,
class MeshType>
1131 const word& zoneName,
1135 ZoneType* ptr = findZone(zoneName);
1137 const bool existing = bool(ptr);
1141 ptr =
new ZoneType(zoneName, this->size(), *
this);
1142 this->push_back(ptr);
1147 Info<< ZoneType::typeName <<
' ' << zoneName
1148 <<
" (" << (existing ?
"existing" :
"new")
1149 <<
" at index " << ptr->index() <<
')' 1159 template<
class ZoneType,
class MeshType>
1163 const ZoneMesh<ZoneType, MeshType>& zones
1166 const label sz = zones.size();
1170 os << sz <<
nl << token::BEGIN_LIST;
1172 for (label i=0; i < sz; ++i)
1174 zones[i].writeDict(
os);
1177 os << token::END_LIST;
1181 os << sz << token::BEGIN_LIST << token::END_LIST;
bool checkParallelSync(const bool report=false) const
Check whether all procs have all zones and in same order.
void size(const label n)
Older name for setAddressableSize.
const labelIOList & zoneIDs
wordList types() const
Return a list of zone types.
labelList findMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Extract list indices for all items with 'name()' that matches.
void clearAddressing()
Clear addressing.
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...
ZoneType * findZone(const word &zoneName)
Find zone by name and return pointer, nullptr on error.
void set(const bitSet &bitset)
Set specified bits from another bitset.
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.
void clear()
Clear the zones.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
label findIndex(const wordRe &key) const
Zone index for the first match, return -1 if not found.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
const Map< label > & zoneMap() const
Map of zones containing zone index for all zoned elements.
constexpr char nl
The newline '\n' character (0x0a)
int debugSwitch(const char *name, const int deflt=0)
Lookup debug switch or add default value.
bool empty() const noexcept
True if List is empty (ie, size() is zero)
T & front()
Access first element of the list, position [0].
Ostream & endl(Ostream &os)
Add newline and flush stream.
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
void stableSort(UList< T > &list)
Stable sort the list.
bool broadcast(Type *values, int count, MPI_Datatype datatype, const int communicator)
Functions to operate on Pointer Lists.
List< labelList > labelListList
List of labelList.
void movePoints(const pointField &pts)
Correct zone mesh after moving points.
Extract name (as a word) from an object, typically using its name() method.
#define forAll(list, i)
Loop across all elements in list.
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
vectorField pointField
pointField is a vectorField.
labelList indices(const wordRe &matcher, const bool useGroups=true) const
The (sorted) patch indices for all matches, optionally matching zone groups.
label findZoneID(const word &zoneName) const
Find zone index by name, return -1 if not found.
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...
friend Ostream & operator(Ostream &os, const ZoneMesh< ZoneType, MeshType > &zones)
A class for handling words, derived from Foam::string.
#define DebugInFunction
Report an information message using Foam::Info.
void sort(UList< T > &list)
Sort the list.
void setGroup(const word &groupName, const labelUList &zoneIDs)
Set/add group with zones.
label size() const noexcept
The number of entries in the list.
A List of wordRe with additional matching capabilities.
void clearPrimitives()
Clear primitive addressing.
auto key(const Type &t) -> std::enable_if_t< std::is_enum_v< Type >, std::underlying_type_t< Type > >
A HashTable similar to std::unordered_map.
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...
An Ostream is an abstract base class for all output systems (streams, files, token lists...
int debug
Static debugging option.
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. ...
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
void push_back(const T &val)
Copy append an element to the end of this list.
void resize(const label newLen)
Adjust size of PtrList.
label whichZone(const label objectIndex) const
Given a global object index, return the zone it is in.
label push_uniq(const T &val)
Append an element if not already in the list.
ZoneMesh(const ZoneMesh &)=delete
No copy construct.
bool empty() const noexcept
True if the list is empty (ie, size() is zero)
List< word > wordList
List of word.
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
#define WarningInFunction
Report a warning using Foam::Warning.
globalIndex procAddr(aMesh.nFaces())
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
std::enable_if_t< std::is_same_v< bool, TypeT >, bool > get(const label i) const
Return bool value at specified position, always false for out-of-range access.
void reserve(label numEntries)
Reserve space for at least the specified number of elements (not the number of buckets) and regenerat...
wordList groupNames() const
A list of the zone group names (if any)
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
bool checkDefinition(const bool report=false) const
Check zone definition. Return true if in error.
wordList names() const
A list of the zone names.
messageStream Info
Information stream (stdout output on master, null elsewhere)
bitSet selection(const labelUList &zoneIds) const
Return all elements (cells, faces, points) contained in the listed zones.
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
entry * set(entry *entryPtr)
Assign a new entry, overwriting any existing entry.
wordList sortedNames() const
Sorted list of the zone names.
List< label > labelList
A List of labels.
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
label whichZones(const label objectIndex, DynamicList< label > &zones) const
Given a global object index, return (in argument) its zones.
Defines the attributes of an object for which implicit objectRegistry management is supported...
static int disallowGenericZones
Debug switch to disallow the use of generic zones.
bitSet bitset(const labelHashSet &locations)
Transform the on locations to a bitSet.
const ZoneType * cfindZone(const word &zoneName) const
Find zone by name and return const pointer, nullptr on error.
bool isPattern() const noexcept
The wordRe is a pattern, not a literal string.
bool writeData(Ostream &os) const
The writeData member function required by regIOobject.
Extract type (as a word) from an object, typically using its type() method.
forAllConstIters(mixture.phases(), phase)
label firstMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Find first list item with 'name()' that matches, -1 on failure.
A HashTable to objects of type <T> with a label key.
const HashTable< labelList > & groupZoneIDs() const
The zone indices per zone group.
void updateMetaData()
Update internal meta-data (eg, prior to writing)