Loading...
Searching...
No Matches
ZoneMesh.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2016-2025 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "ZoneMesh.H"
30#include "entry.H"
31#include "DynamicList.H"
32#include "Pstream.H"
33#include "PtrListOps.H"
34#include "globalIndex.H"
35
36// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37
38namespace Foam
39{
40 template<class ZoneType, class MeshType>
42 (
43 debug::debugSwitch("disallowGenericZones", 0)
44 );
45}
46
47
48// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
49
50template<class ZoneType, class MeshType>
51Foam::label Foam::ZoneMesh<ZoneType, MeshType>::totalSize() const
52{
53 // Count number of objects in all zones
54 const PtrList<ZoneType>& zones = *this;
55
56 label total = 0;
57 for (const ZoneType& zn : zones)
58 {
59 total += zn.size();
60 }
61
62 return total;
63}
64
65
66template<class ZoneType, class MeshType>
67void Foam::ZoneMesh<ZoneType, MeshType>::calcZoneMap() const
68{
69 if (zoneMapPtr_)
70 {
72 << "zone map already calculated"
73 << abort(FatalError);
74 }
75 else
76 {
77 zoneMapPtr_.reset(new Map<label>());
78 auto& map = *zoneMapPtr_;
79
80 // Fill in objects of all zones into the map.
81 // The key is the global object index, value is the zone index
82
83 map.reserve(this->totalSize());
84
85 const PtrList<ZoneType>& zones = *this;
86
87 label zonei = 0;
88
89 for (const ZoneType& zn : zones)
90 {
91 for (const label id : static_cast<const labelList&>(zn))
92 {
93 //map.insert(id, zonei);
94 const auto fnd = map.cfind(id);
95 if (!fnd)
96 {
97 map.insert(id, zonei);
98 }
99 else if (fnd.val() != zonei)
100 {
101 // Multiple zones for same id
102
103 if (!additionalMapPtr_)
104 {
105 // First occurrence
106 label maxIndex = -1;
107 for (const ZoneType& zn : zones)
108 {
109 for
110 (
111 const label id
112 : static_cast<const labelList&>(zn)
113 )
114 {
115 maxIndex = Foam::max(maxIndex, id);
116 }
117 }
118 additionalMapPtr_.reset(new labelListList(maxIndex+1));
119 }
120 auto& additionalMap = *additionalMapPtr_;
121 additionalMap[id].push_uniq(zonei);
122 }
123 }
124
125 ++zonei;
126 }
127
128 // Sort such that map contains lowest zoneID
129 if (additionalMapPtr_)
130 {
131 auto& additionalMap = *additionalMapPtr_;
132 forAll(additionalMap, id)
133 {
134 labelList& zones = additionalMap[id];
135
136 if (zones.size())
137 {
138 Foam::stableSort(zones);
139 const label zonei = map[id];
140 const label index = findLower(zones, zonei);
141 if (index == -1)
142 {
143 // Already first
144 }
145 else
146 {
147 map.set(id, zones[0]);
148 for (label i = 0; i < zones.size() && i <= index; i++)
149 {
150 zones[i] = zones[i+1];
151 }
152 zones[index+1] = zonei;
153 }
154 }
155 }
156 }
157 }
158}
159
160
161template<class ZoneType, class MeshType>
162bool Foam::ZoneMesh<ZoneType, MeshType>::hasGroupIDs() const
163{
164 if (groupIDsPtr_)
165 {
166 // Use existing cache
167 return !groupIDsPtr_->empty();
168 }
169
170 const PtrList<ZoneType>& zones = *this;
171
172 for (const ZoneType& zn : zones)
173 {
174 if (!zn.inGroups().empty())
175 {
176 return true;
177 }
178 }
179
180 return false;
181}
182
183
184template<class ZoneType, class MeshType>
185void Foam::ZoneMesh<ZoneType, MeshType>::calcGroupIDs() const
186{
187 if (groupIDsPtr_)
188 {
189 return; // Or FatalError
190 }
191
192 groupIDsPtr_.reset(new HashTable<labelList>(16));
193 auto& groupLookup = *groupIDsPtr_;
194
195 const PtrList<ZoneType>& zones = *this;
196
197 forAll(zones, zonei)
198 {
199 for (const word& groupName : zones[zonei].inGroups())
200 {
201 groupLookup(groupName).push_back(zonei);
202 }
203 }
204
205 // Remove groups that clash with zone names
206 forAll(zones, zonei)
207 {
208 if (groupLookup.empty())
209 {
210 break; // Early termination
211 }
212 else if (groupLookup.erase(zones[zonei].name()))
213 {
215 << "Removed group '" << zones[zonei].name()
216 << "' which clashes with zone " << zonei
217 << " of the same name."
218 << endl;
219 }
220 }
221}
222
223
224template<class ZoneType, class MeshType>
225void Foam::ZoneMesh<ZoneType, MeshType>::populate
226(
227 PtrList<entry>&& entries
228)
229{
230 clearLocalAddressing();
231
232 PtrList<ZoneType>& zones = *this;
233
234 zones.resize_null(entries.size());
235
236 // Transcribe
237 // Does not handle nullptr at all
238 forAll(zones, zonei)
239 {
240 // Possible handling for nullptr:
241 // zones.emplace_set
242 // (
243 // zonei,
244 // "missing_" + ::Foam::name(zonei), zonei, *this
245 // );
246
247 zones.set
248 (
249 zonei,
250 ZoneType::New
251 (
252 entries[zonei].keyword(),
253 entries[zonei].dict(),
254 zonei,
255 *this
256 )
257 );
258 }
259
260 entries.clear();
261}
262
263
264template<class ZoneType, class MeshType>
265bool Foam::ZoneMesh<ZoneType, MeshType>::readIOcontents
266(
267 const bool allowOptionalRead
268)
269{
270 bool updated = false;
271 PtrList<entry> entries;
272
273 if
274 (
275 isReadRequired()
276 || (allowOptionalRead && isReadOptional() && headerOk())
277 )
278 {
279 // Warn for MUST_READ_IF_MODIFIED
280 warnNoRereading<ZoneMesh<ZoneType, MeshType>>();
281
282 // Read entries
283 Istream& is = readStream(typeName);
284
285 is >> entries;
286
287 is.check(FUNCTION_NAME);
288 close();
289 updated = true;
290 }
291
292 // Future: support master-only and broadcast?
293
294 if (updated)
295 {
296 populate(std::move(entries));
297 }
298
299 return updated;
300}
301
302
303// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
304
305template<class ZoneType, class MeshType>
307(
308 const IOobject& io,
309 const MeshType& mesh
310)
311:
312 PtrList<ZoneType>(),
314 mesh_(mesh)
315{
316 // Note: this is inconsistent with polyBoundaryMesh
317 // which does not permit optional reading
318 readIOcontents(true); // allowOptionalRead = true
319}
320
321
322template<class ZoneType, class MeshType>
324(
325 const IOobject& io,
326 const MeshType& mesh,
328)
329:
330 PtrList<ZoneType>(),
332 mesh_(mesh)
333{}
334
335
336template<class ZoneType, class MeshType>
338(
339 const IOobject& io,
340 const MeshType& mesh,
341 const label size
342)
343:
344 PtrList<ZoneType>(size),
346 mesh_(mesh)
347{
348 // Note: this is inconsistent with polyBoundaryMesh
349 // which does not read all
350 readIOcontents(true); // allowOptionalRead = true
351}
352
353
354template<class ZoneType, class MeshType>
356(
357 const IOobject& io,
358 const MeshType& mesh,
359 const PtrList<ZoneType>& list
360)
361:
362 PtrList<ZoneType>(),
364 mesh_(mesh)
365{
366 if (!readIOcontents(true)) // allowOptionalRead = true
367 {
368 // Nothing read. Use supplied zones
369 PtrList<ZoneType>& zones = *this;
370 zones.resize(list.size());
371
372 forAll(zones, zonei)
373 {
374 zones.set(zonei, list[zonei].clone(*this));
375 }
376 }
377}
378
379
380template<class ZoneType, class MeshType>
382(
383 const IOobject& io,
384 const MeshType& mesh,
385 PtrList<entry>&& entries
386)
387:
388 PtrList<ZoneType>(),
390 mesh_(mesh)
391{
392 if (!readIOcontents(true)) // allowOptionalRead = true
393 {
394 populate(std::move(entries));
395 }
396 entries.clear();
398
399
400// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
401
402template<class ZoneType, class MeshType>
405{
406 if (!zoneMapPtr_)
407 {
408 calcZoneMap();
410
411 return *zoneMapPtr_;
412}
413
414
415template<class ZoneType, class MeshType>
417(
418 const label objectIndex
419) const
420{
421 return zoneMap().lookup(objectIndex, -1);
422}
423
424
425template<class ZoneType, class MeshType>
427(
428 const label objectIndex,
429 DynamicList<label>& zones
430) const
431{
432 zones.clear();
433 const auto fnd = zoneMap().cfind(objectIndex);
434 if (fnd)
435 {
436 // Add main element
437 zones.push_back(fnd.val());
438 if (additionalMapPtr_)
439 {
440 const auto& additionalMap = *additionalMapPtr_;
441 if (objectIndex < additionalMap.size())
442 {
443 for (const label zonei : additionalMap[objectIndex])
444 {
445 zones.push_uniq(zonei);
446 }
447 }
449 }
450 return zones.size();
451}
452
453
454template<class ZoneType, class MeshType>
457 return
458 PtrListOps::get<label>(*this, [](const auto& z) { return z.size(); });
459}
460
461
462template<class ZoneType, class MeshType>
467
468
469template<class ZoneType, class MeshType>
474
475
476template<class ZoneType, class MeshType>
478{
479 return this->groupZoneIDs().sortedToc();
480}
481
482
483template<class ZoneType, class MeshType>
485(
486 const wordRe& matcher
487) const
488{
489 return PtrListOps::names(*this, matcher);
490}
491
492
493template<class ZoneType, class MeshType>
495(
496 const wordRes& matcher
497)
498const
499{
500 return PtrListOps::names(*this, matcher);
501}
502
503
504template<class ZoneType, class MeshType>
506{
507 wordList sorted(this->names());
508 Foam::sort(sorted);
509
510 return sorted;
511}
512
513
514template<class ZoneType, class MeshType>
516(
517 const wordRe& matcher
518) const
519{
520 wordList sorted(this->names(matcher));
521 Foam::sort(sorted);
522
523 return sorted;
524}
525
526
527template<class ZoneType, class MeshType>
529(
530 const wordRes& matcher
531)
532const
533{
534 wordList sorted(this->names(matcher));
535 Foam::sort(sorted);
536
537 return sorted;
538}
539
540
541template<class ZoneType, class MeshType>
543{
544 PtrList<ZoneType>& zones = *this;
545
546 bool changed = false;
547
548 // Adapt indices
549 forAll(zones, zonei)
550 {
551 if (zones[zonei].index() != zonei)
552 {
553 zones[zonei].index() = zonei;
554 changed = true;
555 }
556 }
557
558 if (changed)
559 {
560 this->clearLocalAddressing();
562
563 return changed;
564}
565
566
567template<class ZoneType, class MeshType>
569(
570 const wordRe& matcher,
571 const bool useGroups
572) const
573{
574 if (matcher.empty())
575 {
576 return labelList();
577 }
578
579 // Only check groups if requested and they exist
580 const bool checkGroups = (useGroups && this->hasGroupIDs());
581
582 labelHashSet ids;
583
584 if (checkGroups)
585 {
586 ids.reserve(this->size());
587 }
588
589 if (matcher.isPattern())
590 {
591 if (checkGroups)
592 {
593 const auto& groupLookup = groupZoneIDs();
594 forAllConstIters(groupLookup, iter)
595 {
596 if (matcher(iter.key()))
597 {
598 // Add ids associated with the group
599 ids.insert(iter.val());
600 }
601 }
602 }
603
604 if (ids.empty())
605 {
606 return PtrListOps::findMatching(*this, matcher);
607 }
608 else
609 {
610 ids.insert(PtrListOps::findMatching(*this, matcher));
611 }
612 }
613 else
614 {
615 // Literal string.
616 // Special version of above for reduced memory footprint
617
618 const label zoneId = PtrListOps::firstMatching(*this, matcher);
619
620 if (zoneId >= 0)
621 {
622 return labelList(one{}, zoneId);
623 }
624 else if (checkGroups)
625 {
626 const auto iter = groupZoneIDs().cfind(matcher);
627
628 if (iter.good())
629 {
630 // Add ids associated with the group
631 ids.insert(iter.val());
632 }
633 }
635
636 return ids.sortedToc();
637}
638
639
640template<class ZoneType, class MeshType>
642(
643 const wordRes& matcher,
644 const bool useGroups
645) const
646{
647 if (matcher.empty())
648 {
649 return labelList();
650 }
651 else if (matcher.size() == 1)
652 {
653 return this->indices(matcher.front(), useGroups);
654 }
655
656 labelHashSet ids;
657
658 // Only check groups if requested and they exist
659 if (useGroups && this->hasGroupIDs())
660 {
661 ids.reserve(this->size());
662
663 const auto& groupLookup = groupZoneIDs();
664 forAllConstIters(groupLookup, iter)
665 {
666 if (matcher(iter.key()))
667 {
668 // Add ids associated with the group
669 ids.insert(iter.val());
670 }
671 }
672 }
673
674 if (ids.empty())
675 {
676 return PtrListOps::findMatching(*this, matcher);
677 }
678 else
679 {
680 ids.insert(PtrListOps::findMatching(*this, matcher));
682
683 return ids.sortedToc();
684}
685
686
687template<class ZoneType, class MeshType>
689(
690 const wordRes& allow,
691 const wordRes& deny,
692 const bool useGroups
693) const
694{
695 if (allow.empty() && deny.empty())
696 {
697 // Fast-path: select all
698 return identity(this->size());
699 }
700
701 const wordRes::filter matcher(allow, deny);
702
703 labelHashSet ids;
704
705 // Only check groups if requested and they exist
706 if (useGroups && this->hasGroupIDs())
707 {
708 ids.reserve(this->size());
709
710 const auto& groupLookup = groupZoneIDs();
711 forAllConstIters(groupLookup, iter)
712 {
713 if (matcher(iter.key()))
714 {
715 // Add ids associated with the group
716 ids.insert(iter.val());
717 }
718 }
719 }
720
721 if (ids.empty())
722 {
723 return PtrListOps::findMatching(*this, matcher);
724 }
725 else
726 {
727 ids.insert(PtrListOps::findMatching(*this, matcher));
729
730 return ids.sortedToc();
731}
732
733
734template<class ZoneType, class MeshType>
736(
737 const wordRe& key
738) const
739{
740 if (key.empty())
741 {
742 return -1;
743 }
744 return PtrListOps::firstMatching(*this, key);
745}
746
747
748template<class ZoneType, class MeshType>
750(
751 const wordRes& matcher
752) const
753{
754 if (matcher.empty())
755 {
756 return -1;
757 }
758 return PtrListOps::firstMatching(*this, matcher);
759}
760
761
762template<class ZoneType, class MeshType>
764(
765 const word& zoneName
766) const
767{
768 if (zoneName.empty())
769 {
770 return -1;
771 }
772
773 label zoneId = PtrListOps::firstMatching(*this, zoneName);
774
775 if (zoneId < 0)
776 {
778 << "Zone named " << zoneName << " not found. "
779 << "List of available zone names: " << names() << endl;
780
781 // Used for -dry-run, for example
782 if (disallowGenericZones != 0)
783 {
784 Info<< "Creating dummy zone " << zoneName << endl;
785 auto& zm = const_cast<ZoneMesh<ZoneType, MeshType>&>(*this);
786 zm.emplace_back(zoneName, zm.size(), zm);
787 }
789
790 return zoneId;
791}
792
793
794template<class ZoneType, class MeshType>
796(
797 const word& zoneName
798) const
799{
800 if (zoneName.empty())
801 {
802 return nullptr;
803 }
804
805 const PtrList<ZoneType>& zones = *this;
806
807 for (auto iter = zones.begin(); iter != zones.end(); ++iter)
808 {
809 const ZoneType* ptr = iter.get();
810
811 if (ptr && zoneName == ptr->name())
812 {
813 return ptr;
814 }
815 }
816
817 // Used for -dry-run, for example
818 if (disallowGenericZones != 0)
819 {
820 Info<< "Creating dummy zone " << zoneName << endl;
821 auto& zm = const_cast<ZoneMesh<ZoneType, MeshType>&>(*this);
822 zm.emplace_back(zoneName, zm.size(), zm);
824
825 return nullptr;
826}
827
828
829template<class ZoneType, class MeshType>
831(
832 const word& zoneName
834{
835 return const_cast<ZoneType*>(this->cfindZone(zoneName));
836}
837
838
839template<class ZoneType, class MeshType>
841(
842 const labelUList& zoneIds
843) const
844{
845 bitSet bitset;
846
847 for (const label zonei : zoneIds)
848 {
849 #ifdef FULLDEBUG
850 if (zonei < 0 || zonei >= this->size())
851 {
853 << ZoneType::typeName << " "
854 << zonei << " out of range [0," << this->size() << ")"
855 << abort(FatalError);
856 }
857 #endif
858
859 bitset.set
860 (
861 static_cast<const labelList&>(this->operator[](zonei))
862 );
864
865 return bitset;
866}
867
868
869template<class ZoneType, class MeshType>
871(
872 const wordRe& matcher,
873 const bool useGroups
874) const
876 // matcher.empty() is handled by indices()
877 return this->selection(this->indices(matcher, useGroups));
878}
879
880
881template<class ZoneType, class MeshType>
883(
884 const wordRes& matcher,
885 const bool useGroups
886) const
887{
888 // matcher.empty() is handled by indices()
889 return this->selection(this->indices(matcher, useGroups));
890}
891
892
893template<class ZoneType, class MeshType>
896{
897 if (!groupIDsPtr_)
898 {
899 calcGroupIDs();
901
902 return *groupIDsPtr_;
903}
904
905
906template<class ZoneType, class MeshType>
908(
909 const word& groupName,
910 const labelUList& zoneIDs
911)
912{
913 groupIDsPtr_.reset(nullptr);
914
915 PtrList<ZoneType>& zones = *this;
916
917 boolList pending(zones.size(), true);
918
919 // Add to specified zones
920 for (const label zonei : zoneIDs)
921 {
922 if (pending.test(zonei))
923 {
924 pending.unset(zonei);
925 zones[zonei].addGroup(groupName);
926 }
927 }
928
929 // Remove from other zones
930 forAll(zones, zonei)
931 {
932 if (pending.test(zonei))
933 {
934 zones[zonei].removeGroup(groupName);
935 }
936 }
937}
938
939
940// Private until it is more generally required (and gets a better name?)
941template<class ZoneType, class MeshType>
942void Foam::ZoneMesh<ZoneType, MeshType>::clearLocalAddressing()
943{
944 zoneMapPtr_.reset(nullptr);
945 additionalMapPtr_.reset(nullptr);
946 groupIDsPtr_.reset(nullptr);
947}
948
949
950template<class ZoneType, class MeshType>
952{
953 clearLocalAddressing();
954
955 PtrList<ZoneType>& zones = *this;
956
957 for (ZoneType& zn : zones)
959 zn.clearAddressing();
960 }
961}
962
963
964template<class ZoneType, class MeshType>
966{
967 PtrList<ZoneType>& zones = *this;
968
969 for (ZoneType& zn : zones)
971 zn.clearPrimitives();
972 }
973}
974
975
976template<class ZoneType, class MeshType>
981}
982
983
984template<class ZoneType, class MeshType>
986(
987 const bool report
988) const
989{
990 bool hasError = false;
991
992 const PtrList<ZoneType>& zones = *this;
993
994 for (const ZoneType& zn : zones)
995 {
996 hasError |= zn.checkDefinition(report);
998
999 return hasError;
1000}
1001
1002
1003template<class ZoneType, class MeshType>
1005(
1006 const bool report
1007) const
1008{
1009 if (!UPstream::parRun())
1010 {
1011 return false;
1012 }
1013
1014 const PtrList<ZoneType>& zones = *this;
1015
1016 bool hasError = false;
1017
1018 const wordList localNames(this->names());
1019 const wordList localTypes(this->types());
1020
1021 // Check and report error(s) on master
1022 // - don't need indexing on master itself
1023
1024 const globalIndex procAddr
1025 (
1027 localNames.size()
1028 );
1029
1030 const wordList allNames(procAddr.gather(localNames));
1031 const wordList allTypes(procAddr.gather(localTypes));
1032
1033 // Automatically restricted to master
1034 for (const int proci : procAddr.subProcs())
1035 {
1036 const auto procNames(allNames.slice(procAddr.range(proci)));
1037 const auto procTypes(allTypes.slice(procAddr.range(proci)));
1038
1039 if (procNames != localNames || procTypes != localTypes)
1040 {
1041 hasError = true;
1042
1043 if (debug || report)
1044 {
1045 Info<< " ***Inconsistent zones across processors, "
1046 "processor 0 has zone names:" << localNames
1047 << " zone types:" << localTypes
1048 << " processor " << proci
1049 << " has zone names:" << procNames
1050 << " zone types:" << procTypes
1051 << endl;
1052 }
1053 }
1054 }
1055
1056 Pstream::broadcast(hasError);
1057
1058 // Check local contents
1059 if (!hasError)
1060 {
1061 for (const ZoneType& zn : zones)
1062 {
1063 if (zn.checkParallelSync(false))
1064 {
1065 hasError = true;
1066
1067 if (debug || (report && UPstream::master()))
1068 {
1069 Info<< " ***Zone " << zn.name()
1070 << " of type " << zn.type()
1071 << " is not correctly synchronised"
1072 << " across coupled boundaries."
1073 << " (coupled faces are either not both"
1074 << " present in set or have same flipmap)" << endl;
1075 }
1076 }
1077 }
1079
1080 return hasError;
1081}
1082
1083
1084template<class ZoneType, class MeshType>
1086{
1087 PtrList<ZoneType>& zones = *this;
1088
1089 for (ZoneType& zn : zones)
1091 zn.movePoints(pts);
1092 }
1093}
1094
1095
1096template<class ZoneType, class MeshType>
1098{
1099 wordList zoneNames(this->names());
1100 if (zoneNames.empty())
1101 {
1102 this->removeMetaData();
1103 }
1104 else
1105 {
1106 // Save as a list of names without the leading size
1107 tokenList toks(2+zoneNames.size());
1108
1109 auto iter = toks.begin();
1110 (*iter).pToken(token::BEGIN_LIST);
1111 iter = std::move(zoneNames.begin(), zoneNames.end(), ++iter);
1112 (*iter).pToken(token::END_LIST);
1113
1114 this->getMetaData().set("names", std::move(toks));
1116}
1117
1118
1119// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
1120
1121template<class ZoneType, class MeshType>
1123{
1124 const PtrList<ZoneType>& entries = *this;
1125
1126 os << entries.size();
1127
1128 if (entries.empty())
1129 {
1130 // 0-sized : can write with less vertical space
1132 }
1133 else
1134 {
1135 os << nl << token::BEGIN_LIST << nl;
1136
1137 for (const auto& zn : entries)
1138 {
1139 os.beginBlock(zn.name());
1140 zn.write(os);
1141 os.endBlock();
1144 }
1145}
1146
1147
1148template<class ZoneType, class MeshType>
1150(
1151 const word& keyword,
1152 Ostream& os
1153) const
1154{
1155 const PtrList<ZoneType>& entries = *this;
1156
1157 if (!keyword.empty())
1158 {
1159 os.write(keyword);
1160 if (entries.empty())
1161 {
1162 os << token::SPACE;
1163 }
1164 }
1165
1167
1168 if (!keyword.empty()) os.endEntry();
1169}
1170
1171
1172template<class ZoneType, class MeshType>
1174{
1175 writeEntry(os);
1176 return os.good();
1177}
1178
1179
1180// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
1181
1182template<class ZoneType, class MeshType>
1184(
1185 const word& zoneName
1186) const
1187{
1188 const label zonei = findZoneID(zoneName);
1189
1190 if (zonei < 0)
1191 {
1193 << "Zone named " << zoneName << " not found." << nl
1194 << "Available zone names: " << names() << endl
1195 << abort(FatalError);
1197
1198 return operator[](zonei);
1199}
1200
1201
1202template<class ZoneType, class MeshType>
1204(
1205 const word& zoneName
1206)
1207{
1208 const label zonei = findZoneID(zoneName);
1209
1210 if (zonei < 0)
1211 {
1213 << "Zone named " << zoneName << " not found." << nl
1214 << "Available zone names: " << names() << endl
1215 << abort(FatalError);
1217
1218 return operator[](zonei);
1219}
1220
1221
1222template<class ZoneType, class MeshType>
1224(
1225 const word& zoneName,
1226 const bool verbose
1227)
1228{
1229 ZoneType* ptr = findZone(zoneName);
1230
1231 const bool existing = bool(ptr);
1232
1233 if (!ptr)
1234 {
1235 ptr = new ZoneType(zoneName, this->size(), *this);
1236 this->push_back(ptr);
1237 }
1238
1239 if (verbose)
1240 {
1241 Info<< ZoneType::typeName << ' ' << zoneName
1242 << " (" << (existing ? "existing" : "new")
1243 << " at index " << ptr->index() << ')'
1244 << endl;
1245 }
1246
1247 return *ptr;
1248}
1249
1250
1251// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
1252
1253template<class ZoneType, class MeshType>
1254Foam::Ostream& Foam::operator<<
1255(
1256 Ostream& os,
1257 const ZoneMesh<ZoneType, MeshType>& zones
1258)
1259{
1260 zones.writeEntry(os);
1261 return os;
1262}
1263
1264
1265// ************************************************************************* //
Functions to operate on Pointer Lists.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
label push_uniq(const T &val)
Append an element if not already in the list.
void push_back(const T &val)
Copy append an element to the end of this list.
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition HashSet.H:229
A HashTable similar to std::unordered_map.
Definition HashTable.H:124
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition HashTable.C:156
bool empty() const noexcept
True if the hash table is empty.
Definition HashTable.H:353
void reserve(label numEntries)
Reserve space for at least the specified number of elements (not the number of buckets) and regenerat...
Definition HashTable.C:729
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition IOobject.H:191
static word groupName(StringType base, const word &group)
Create dot-delimited name.group string.
autoPtr< IOobject > clone() const
Clone.
Definition IOobject.H:641
A HashTable to objects of type <T> with a label key.
Definition Map.H:54
virtual Ostream & write(const char c) override
Write character.
Definition OBJstream.C:69
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
virtual Ostream & endBlock()
Write end block group.
Definition Ostream.C:108
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
Definition Ostream.C:90
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition PtrList.H:67
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie,...
Definition PtrList.H:171
void push_back(ZoneType *ptr)
Definition PtrListI.H:131
T & emplace_back(Args &&... args)
Construct and append an element to the end of the list, return reference to the new list element.
Definition PtrListI.H:122
void clear()
Clear the PtrList. Delete allocated entries and set size to zero.
Definition PtrListI.H:98
constexpr PtrList() noexcept
Definition PtrListI.H:29
void resize(const label newLen)
Adjust size of PtrList.
Definition PtrList.C:124
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition UListI.H:410
bool test(const label i) const
Test bool value at specified position, always false for out-of-range access.
Definition UList.H:852
bool empty() const noexcept
True if List is empty (ie, size() is zero).
Definition UList.H:701
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition UListI.H:454
SubList< T > slice(const label pos, label len=-1)
Return SubList slice (non-const access) - no range checking.
Definition SubList.H:258
T & front()
Access first element of the list, position [0].
Definition UListI.H:239
bool unset(const label i)
Unset the bool entry at specified position, always false for out-of-range access.
Definition UList.H:885
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
Definition UPstream.H:1669
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition UPstream.H:1714
@ broadcast
broadcast [MPI]
Definition UPstream.H:189
static bool & parRun() noexcept
Test if this a parallel run.
Definition UPstream.H:1681
iterator begin()
Return iterator to begin traversal of non-nullptr entries.
Definition UPtrListI.H:416
bool empty() const noexcept
True if the list is empty (ie, size() is zero).
Definition UPtrListI.H:99
label size() const noexcept
Definition UPtrListI.H:106
iterator end() noexcept
Return iterator beyond end of UPtrList traversal.
Definition UPtrListI.H:440
A list of mesh zones.
Definition ZoneMesh.H:65
bool checkDefinition(const bool report=false) const
Check zone definition. Return true if in error.
Definition ZoneMesh.C:979
label findZoneID(const word &zoneName) const
Find zone index by name, return -1 if not found.
Definition ZoneMesh.C:757
friend Ostream & operator(Ostream &os, const ZoneMesh< ZoneType, MeshType > &zones)
wordList sortedNames() const
Sorted list of the zone names.
Definition ZoneMesh.C:498
void setGroup(const word &groupName, const labelUList &zoneIDs)
Set/add group with zones.
Definition ZoneMesh.C:901
wordList types() const
Return a list of zone types.
Definition ZoneMesh.C:456
virtual bool writeData(Ostream &os) const
The writeData member function required by regIOobject.
Definition ZoneMesh.C:1166
ZoneType * findZone(const word &zoneName)
Find zone by name and return pointer, nullptr on error.
Definition ZoneMesh.C:824
const ZoneType * cfindZone(const word &zoneName) const
Find zone by name and return const pointer, nullptr on error.
Definition ZoneMesh.C:789
bool reindex()
Adjust the index of zone entries to be consistent with their position in the list.
Definition ZoneMesh.C:535
void clearPrimitives()
Clear primitive addressing.
Definition ZoneMesh.C:958
const MeshType & mesh() const noexcept
Return the mesh reference.
Definition ZoneMesh.H:232
void updateMetaData()
Update internal meta-data (eg, prior to writing).
Definition ZoneMesh.C:1090
labelList zoneSizes() const
Return a list of zone sizes.
Definition ZoneMesh.C:448
const Map< label > & zoneMap() const
Map of zones containing zone index for all zoned elements.
Definition ZoneMesh.C:397
static int disallowGenericZones
Debug switch to disallow the use of generic zones.
Definition ZoneMesh.H:148
label whichZones(const label objectIndex, DynamicList< label > &zones) const
Given a global object index, return (in argument) its zones.
Definition ZoneMesh.C:420
void clearAddressing()
Clear addressing.
Definition ZoneMesh.C:944
bitSet selection(const labelUList &zoneIds) const
Return all elements (cells, faces, points) contained in the listed zones.
Definition ZoneMesh.C:834
void writeEntry(Ostream &os) const
Write as a plain list of entries.
Definition ZoneMesh.C:1115
const ZoneType & operator[](const word &zoneName) const
Return const reference to zone by name.
Definition ZoneMesh.C:1177
ZoneMesh(const ZoneMesh &)=delete
No copy construct.
void movePoints(const pointField &pts)
Correct zone mesh after moving points.
Definition ZoneMesh.C:1078
void clear()
Clear the zones.
Definition ZoneMesh.C:970
wordList groupNames() const
A list of the zone group names (if any).
Definition ZoneMesh.C:470
const HashTable< labelList > & groupZoneIDs() const
The zone indices per zone group.
Definition ZoneMesh.C:888
label whichZone(const label objectIndex) const
Given a global object index, return the zone it is in.
Definition ZoneMesh.C:410
wordList names() const
A list of the zone names.
Definition ZoneMesh.C:463
bool checkParallelSync(const bool report=false) const
Check whether all procs have all zones and in same order.
Definition ZoneMesh.C:998
labelList indices(const wordRe &matcher, const bool useGroups=true) const
The (sorted) patch indices for all matches, optionally matching zone groups.
Definition ZoneMesh.C:562
label findIndex(const wordRe &key) const
Zone index for the first match, return -1 if not found.
Definition ZoneMesh.C:729
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition bitSet.H:61
void set(const bitSet &bitset)
Set specified bits from another bitset.
Definition bitSetI.H:502
Calculates a non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
Definition globalIndex.H:77
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]).
labelRange range(label proci) const noexcept
Return start/size range of proci data.
labelRange subProcs() const noexcept
Range of process indices for addressed sub-offsets (processes).
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition one.H:57
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition regIOobject.H:71
regIOobject(const IOobject &io, const bool isTimeObject=false)
Construct from IOobject. The optional flag adds special handling if the object is the top-level regIO...
Definition regIOobject.C:43
void removeMetaData()
Remove meta-data.
dictionary & getMetaData() noexcept
Get or create meta-data.
@ BEGIN_LIST
Begin list [isseparator].
Definition token.H:174
@ END_LIST
End list [isseparator].
Definition token.H:175
@ SPACE
Space [isspace].
Definition token.H:144
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings.
Definition wordRe.H:81
bool isPattern() const noexcept
The wordRe is a pattern, not a literal string.
Definition wordReI.H:104
A List of wordRe with additional matching capabilities.
Definition wordRes.H:56
A class for handling words, derived from Foam::string.
Definition word.H:66
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition zero.H:58
dynamicFvMesh & mesh
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
OBJstream os(runTime.globalPath()/outputName)
const auto & io
auto & names
const labelIOList & zoneIDs
Definition correctPhi.H:59
#define WarningInFunction
Report a warning using Foam::Warning.
#define FUNCTION_NAME
#define DebugInFunction
Report an information message using Foam::Info.
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
labelList findMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Extract list indices for all items with 'name()' that matches.
label firstMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Find first list item with 'name()' that matches, -1 on failure.
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.
Namespace for handling debugging switches.
Definition debug.C:45
int debugSwitch(const char *name, const int deflt=0)
Lookup debug switch or add default value.
Definition debug.C:222
Namespace for OpenFOAM.
List< word > wordList
List of word.
Definition fileName.H:60
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:40
List< labelList > labelListList
List of labelList.
Definition labelList.H:38
List< label > labelList
A List of labels.
Definition List.H:62
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition HashSet.H:85
messageStream Info
Information stream (stdout output on master, null elsewhere).
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.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
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...
void sort(UList< T > &list)
Sort the list.
Definition UList.C:283
errorManip< error > abort(error &err)
Definition errorManip.H:139
List< bool > boolList
A List of bools.
Definition List.H:60
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
List< token > tokenList
List of token, used for dictionary primitive entry (for example).
Definition tokenList.H:32
vectorField pointField
pointField is a vectorField.
UList< label > labelUList
A UList of labels.
Definition UList.H:75
void stableSort(UList< T > &list)
Stable sort the list.
Definition UList.C:299
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
dictionary dict
const pointField & pts
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
#define forAllConstIters(container, iter)
Iterate across all elements of the container object with const access.
Definition stdFoam.H:235
Dispatch tag: Construct 'one-sided' from the non-master local sizes using gather but no broadcast.
Extract name (as a word) from an object, typically using its name() method.
Definition word.H:341
Extract type (as a word) from an object, typically using its type() method.
Definition word.H:362
Functor wrapper of allow/deny lists of wordRe for filtering.
Definition wordRes.H:275