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-2024 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
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 
38 namespace Foam
39 {
40  template<class ZoneType, class MeshType>
42  (
43  debug::debugSwitch("disallowGenericZones", 0)
44  );
45 }
46 
47 
48 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
49 
50 template<class ZoneType, class MeshType>
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 
66 template<class ZoneType, class MeshType>
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 
161 template<class ZoneType, class MeshType>
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 
184 template<class ZoneType, class MeshType>
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.erase(zones[zonei].name()))
209  {
211  << "Removed group '" << zones[zonei].name()
212  << "' which clashes with zone " << zonei
213  << " of the same name."
214  << endl;
215  }
216  }
217 }
218 
219 
220 template<class ZoneType, class MeshType>
222 (
223  PtrList<entry>&& entries
224 )
225 {
226  clearLocalAddressing();
227 
228  PtrList<ZoneType>& zones = *this;
229 
230  zones.resize_null(entries.size());
231 
232  // Transcribe
233  // Does not handle nullptr at all
234  forAll(zones, zonei)
235  {
236  // Possible handling for nullptr:
237  // zones.emplace_set
238  // (
239  // zonei,
240  // "missing_" + ::Foam::name(zonei), zonei, *this
241  // );
242 
243  zones.set
244  (
245  zonei,
247  (
248  entries[zonei].keyword(),
249  entries[zonei].dict(),
250  zonei,
251  *this
252  )
253  );
254  }
255 
256  entries.clear();
257 }
258 
259 
260 template<class ZoneType, class MeshType>
262 (
263  const bool allowOptionalRead
264 )
265 {
266  bool updated = false;
267  PtrList<entry> entries;
268 
269  if
270  (
271  isReadRequired()
272  || (allowOptionalRead && isReadOptional() && headerOk())
273  )
274  {
275  // Warn for MUST_READ_IF_MODIFIED
276  warnNoRereading<ZoneMesh<ZoneType, MeshType>>();
277 
278  // Read entries
279  Istream& is = readStream(typeName);
280 
281  is >> entries;
282 
283  is.check(FUNCTION_NAME);
284  close();
285  updated = true;
286  }
287 
288  // Future: support master-only and broadcast?
289 
290  if (updated)
291  {
292  populate(std::move(entries));
293  }
294 
295  return updated;
296 }
297 
298 
299 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
300 
301 template<class ZoneType, class MeshType>
303 (
304  const IOobject& io,
305  const MeshType& mesh
306 )
307 :
308  PtrList<ZoneType>(),
309  regIOobject(io),
310  mesh_(mesh)
311 {
312  // Note: this is inconsistent with polyBoundaryMesh
313  // which does not permit optional reading
314  readIOcontents(true); // allowOptionalRead = true
315 }
316 
317 
318 template<class ZoneType, class MeshType>
320 (
321  const IOobject& io,
322  const MeshType& mesh,
323  Foam::zero
324 )
325 :
326  PtrList<ZoneType>(),
328  mesh_(mesh)
329 {}
330 
331 
332 template<class ZoneType, class MeshType>
334 (
335  const IOobject& io,
336  const MeshType& mesh,
337  const label size
338 )
339 :
340  PtrList<ZoneType>(size),
341  regIOobject(io),
342  mesh_(mesh)
343 {
344  // Note: this is inconsistent with polyBoundaryMesh
345  // which does not read all
346  readIOcontents(true); // allowOptionalRead = true
347 }
348 
349 
350 template<class ZoneType, class MeshType>
352 (
353  const IOobject& io,
354  const MeshType& mesh,
355  const PtrList<ZoneType>& list
356 )
357 :
358  PtrList<ZoneType>(),
359  regIOobject(io),
360  mesh_(mesh)
361 {
362  if (!readIOcontents(true)) // allowOptionalRead = true
363  {
364  // Nothing read. Use supplied zones
365  PtrList<ZoneType>& zones = *this;
366  zones.resize(list.size());
367 
368  forAll(zones, zonei)
369  {
370  zones.set(zonei, list[zonei].clone(*this));
371  }
372  }
373 }
374 
375 
376 template<class ZoneType, class MeshType>
378 (
379  const IOobject& io,
380  const MeshType& mesh,
381  PtrList<entry>&& entries
382 )
383 :
384  PtrList<ZoneType>(),
385  regIOobject(io),
386  mesh_(mesh)
387 {
388  if (!readIOcontents(true)) // allowOptionalRead = true
389  {
390  populate(std::move(entries));
391  }
392  entries.clear();
393 }
394 
395 
396 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
397 
398 template<class ZoneType, class MeshType>
401 {
402  if (!zoneMapPtr_)
403  {
404  calcZoneMap();
405  }
407  return *zoneMapPtr_;
408 }
409 
410 
411 template<class ZoneType, class MeshType>
413 (
414  const label objectIndex
415 ) const
416 {
417  return zoneMap().lookup(objectIndex, -1);
418 }
419 
420 
421 template<class ZoneType, class MeshType>
423 (
424  const label objectIndex,
425  DynamicList<label>& zones
426 ) const
427 {
428  zones.clear();
429  const auto fnd = zoneMap().cfind(objectIndex);
430  if (fnd)
431  {
432  // Add main element
433  zones.push_back(fnd.val());
434  if (additionalMapPtr_)
435  {
436  const auto& additionalMap = *additionalMapPtr_;
437  if (objectIndex < additionalMap.size())
438  {
439  for (const label zonei : additionalMap[objectIndex])
440  {
441  zones.push_uniq(zonei);
442  }
443  }
444  }
445  }
446  return zones.size();
447 }
448 
449 
450 template<class ZoneType, class MeshType>
452 {
453  return PtrListOps::get<word>(*this, typeOp<ZoneType>());
454 }
455 
456 
457 template<class ZoneType, class MeshType>
459 {
460  return PtrListOps::get<word>(*this, nameOp<ZoneType>());
461 }
462 
463 
464 template<class ZoneType, class MeshType>
466 {
467  return this->groupZoneIDs().sortedToc();
468 }
469 
470 
471 template<class ZoneType, class MeshType>
473 (
474  const wordRe& matcher
475 ) const
476 {
477  return PtrListOps::names(*this, matcher);
478 }
479 
480 
481 template<class ZoneType, class MeshType>
483 (
484  const wordRes& matcher
485 )
486 const
487 {
488  return PtrListOps::names(*this, matcher);
489 }
490 
491 
492 template<class ZoneType, class MeshType>
494 {
495  wordList sorted(this->names());
496  Foam::sort(sorted);
498  return sorted;
499 }
500 
501 
502 template<class ZoneType, class MeshType>
504 (
505  const wordRe& matcher
506 ) const
507 {
508  wordList sorted(this->names(matcher));
509  Foam::sort(sorted);
511  return sorted;
512 }
513 
514 
515 template<class ZoneType, class MeshType>
517 (
518  const wordRes& matcher
519 )
520 const
521 {
522  wordList sorted(this->names(matcher));
523  Foam::sort(sorted);
525  return sorted;
526 }
527 
528 
529 template<class ZoneType, class MeshType>
531 (
532  const wordRe& matcher,
533  const bool useGroups
534 ) const
535 {
536  if (matcher.empty())
537  {
538  return labelList();
539  }
540 
541  // Only check groups if requested and they exist
542  const bool checkGroups = (useGroups && this->hasGroupIDs());
543 
544  labelHashSet ids(0);
545 
546  if (checkGroups)
547  {
548  ids.reserve(this->size());
549  }
550 
551  if (matcher.isPattern())
552  {
553  if (checkGroups)
554  {
555  const auto& groupLookup = groupZoneIDs();
556  forAllConstIters(groupLookup, iter)
557  {
558  if (matcher(iter.key()))
559  {
560  // Hash ids associated with the group
561  ids.insert(iter.val());
562  }
563  }
564  }
565 
566  if (ids.empty())
567  {
568  return PtrListOps::findMatching(*this, matcher);
569  }
570  else
571  {
572  ids.insert(PtrListOps::findMatching(*this, matcher));
573  }
574  }
575  else
576  {
577  // Literal string.
578  // Special version of above for reduced memory footprint
579 
580  const label zoneId = PtrListOps::firstMatching(*this, matcher);
581 
582  if (zoneId >= 0)
583  {
584  return labelList(one{}, zoneId);
585  }
586  else if (checkGroups)
587  {
588  const auto iter = groupZoneIDs().cfind(matcher);
589 
590  if (iter.good())
591  {
592  // Hash ids associated with the group
593  ids.insert(iter.val());
594  }
595  }
596  }
598  return ids.sortedToc();
599 }
600 
601 
602 template<class ZoneType, class MeshType>
604 (
605  const wordRes& matcher,
606  const bool useGroups
607 ) const
608 {
609  if (matcher.empty())
610  {
611  return labelList();
612  }
613  else if (matcher.size() == 1)
614  {
615  return this->indices(matcher.front(), useGroups);
616  }
617 
618  labelHashSet ids(0);
619 
620  // Only check groups if requested and they exist
621  if (useGroups && this->hasGroupIDs())
622  {
623  ids.reserve(this->size());
624 
625  const auto& groupLookup = groupZoneIDs();
626  forAllConstIters(groupLookup, iter)
627  {
628  if (matcher(iter.key()))
629  {
630  // Hash the ids associated with the group
631  ids.insert(iter.val());
632  }
633  }
634  }
635 
636  if (ids.empty())
637  {
638  return PtrListOps::findMatching(*this, matcher);
639  }
640  else
641  {
642  ids.insert(PtrListOps::findMatching(*this, matcher));
643  }
645  return ids.sortedToc();
646 }
647 
648 
649 template<class ZoneType, class MeshType>
651 (
652  const wordRes& select,
653  const wordRes& ignore,
654  const bool useGroups
655 ) const
656 {
657  if (ignore.empty())
658  {
659  return this->indices(select, useGroups);
660  }
661 
662  const wordRes::filter matcher(select, ignore);
663 
664  labelHashSet ids(0);
665 
666  // Only check groups if requested and they exist
667  if (useGroups && this->hasGroupIDs())
668  {
669  ids.reserve(this->size());
670 
671  const auto& groupLookup = groupZoneIDs();
672  forAllConstIters(groupLookup, iter)
673  {
674  if (matcher(iter.key()))
675  {
676  // Add patch ids associated with the group
677  ids.insert(iter.val());
678  }
679  }
680  }
681 
682  if (ids.empty())
683  {
684  return PtrListOps::findMatching(*this, matcher);
685  }
686  else
687  {
688  ids.insert(PtrListOps::findMatching(*this, matcher));
689  }
691  return ids.sortedToc();
692 }
693 
694 
695 template<class ZoneType, class MeshType>
697 (
698  const wordRe& key
699 ) const
700 {
701  if (key.empty())
702  {
703  return -1;
704  }
705  return PtrListOps::firstMatching(*this, key);
706 }
707 
708 
709 template<class ZoneType, class MeshType>
711 (
712  const wordRes& matcher
713 ) const
714 {
715  if (matcher.empty())
716  {
717  return -1;
718  }
719  return PtrListOps::firstMatching(*this, matcher);
720 }
721 
722 
723 template<class ZoneType, class MeshType>
725 (
726  const word& zoneName
727 ) const
728 {
729  if (zoneName.empty())
730  {
731  return -1;
732  }
733 
734  label zoneId = PtrListOps::firstMatching(*this, zoneName);
735 
736  if (zoneId < 0)
737  {
739  << "Zone named " << zoneName << " not found. "
740  << "List of available zone names: " << names() << endl;
741 
742  // Used for -dry-run, for example
743  if (disallowGenericZones != 0)
744  {
745  Info<< "Creating dummy zone " << zoneName << endl;
746  auto& zm = const_cast<ZoneMesh<ZoneType, MeshType>&>(*this);
747  zm.emplace_back(zoneName, zm.size(), zm);
748  }
749  }
751  return zoneId;
752 }
753 
754 
755 template<class ZoneType, class MeshType>
757 (
758  const word& zoneName
759 ) const
760 {
761  if (zoneName.empty())
762  {
763  return nullptr;
764  }
765 
766  const PtrList<ZoneType>& zones = *this;
767 
768  for (auto iter = zones.begin(); iter != zones.end(); ++iter)
769  {
770  const ZoneType* ptr = iter.get();
771 
772  if (ptr && zoneName == ptr->name())
773  {
774  return ptr;
775  }
776  }
777 
778  // Used for -dry-run, for example
779  if (disallowGenericZones != 0)
780  {
781  Info<< "Creating dummy zone " << zoneName << endl;
782  auto& zm = const_cast<ZoneMesh<ZoneType, MeshType>&>(*this);
783  zm.emplace_back(zoneName, zm.size(), zm);
784  }
786  return nullptr;
787 }
788 
789 
790 template<class ZoneType, class MeshType>
792 (
793  const word& zoneName
794 )
795 {
796  return const_cast<ZoneType*>(this->cfindZone(zoneName));
797 }
798 
799 
800 template<class ZoneType, class MeshType>
802 (
803  const labelUList& zoneIds
804 ) const
805 {
806  bitSet bitset;
807 
808  for (const label zonei : zoneIds)
809  {
810  #ifdef FULLDEBUG
811  if (zonei < 0 || zonei >= this->size())
812  {
814  << ZoneType::typeName << " "
815  << zonei << " out of range [0," << this->size() << ")"
816  << abort(FatalError);
817  }
818  #endif
819 
820  bitset.set
821  (
822  static_cast<const labelList&>(this->operator[](zonei))
823  );
824  }
826  return bitset;
827 }
828 
829 
830 template<class ZoneType, class MeshType>
832 (
833  const wordRe& matcher,
834  const bool useGroups
835 ) const
836 {
837  // matcher.empty() is handled by indices()
838  return this->selection(this->indices(matcher, useGroups));
839 }
840 
841 
842 template<class ZoneType, class MeshType>
844 (
845  const wordRes& matcher,
846  const bool useGroups
847 ) const
848 {
849  // matcher.empty() is handled by indices()
850  return this->selection(this->indices(matcher, useGroups));
851 }
852 
853 
854 template<class ZoneType, class MeshType>
857 {
858  if (!groupIDsPtr_)
859  {
860  calcGroupIDs();
861  }
863  return *groupIDsPtr_;
864 }
865 
866 
867 template<class ZoneType, class MeshType>
869 (
870  const word& groupName,
871  const labelUList& zoneIDs
872 )
873 {
874  groupIDsPtr_.reset(nullptr);
875 
876  PtrList<ZoneType>& zones = *this;
877 
878  boolList pending(zones.size(), true);
879 
880  // Add to specified zones
881  for (const label zonei : zoneIDs)
882  {
883  if (pending.test(zonei))
884  {
885  pending.unset(zonei);
886  zones[zonei].addGroup(groupName);
887  }
888  }
889 
890  // Remove from other zones
891  forAll(zones, zonei)
892  {
893  if (pending.test(zonei))
894  {
895  zones[zonei].removeGroup(groupName);
896  }
897  }
898 }
899 
900 
901 // Private until it is more generally required (and gets a better name?)
902 template<class ZoneType, class MeshType>
904 {
905  zoneMapPtr_.reset(nullptr);
906  additionalMapPtr_.reset(nullptr);
907  groupIDsPtr_.reset(nullptr);
908 }
909 
910 
911 template<class ZoneType, class MeshType>
913 {
914  clearLocalAddressing();
915 
916  PtrList<ZoneType>& zones = *this;
917 
918  for (ZoneType& zn : zones)
919  {
920  zn.clearAddressing();
921  }
922 }
923 
924 
925 template<class ZoneType, class MeshType>
927 {
928  PtrList<ZoneType>& zones = *this;
929 
930  for (ZoneType& zn : zones)
931  {
932  zn.clearPrimitives();
933  }
934 }
935 
936 
937 template<class ZoneType, class MeshType>
939 {
940  clearAddressing();
942 }
943 
944 
945 template<class ZoneType, class MeshType>
947 (
948  const bool report
949 ) const
950 {
951  bool hasError = false;
952 
953  const PtrList<ZoneType>& zones = *this;
954 
955  for (const ZoneType& zn : zones)
956  {
957  hasError |= zn.checkDefinition(report);
958  }
960  return hasError;
961 }
962 
963 
964 template<class ZoneType, class MeshType>
966 (
967  const bool report
968 ) const
969 {
970  if (!UPstream::parRun())
971  {
972  return false;
973  }
974 
975  const PtrList<ZoneType>& zones = *this;
976 
977  bool hasError = false;
978 
979  const wordList localNames(this->names());
980  const wordList localTypes(this->types());
981 
982  // Check and report error(s) on master
983  // - don't need indexing on master itself
984 
985  const globalIndex procAddr
986  (
987  globalIndex::gatherNonLocal{},
988  localNames.size()
989  );
990 
991  const wordList allNames(procAddr.gather(localNames));
992  const wordList allTypes(procAddr.gather(localTypes));
993 
994  // Automatically restricted to master
995  for (const int proci : procAddr.subProcs())
996  {
997  const auto procNames(allNames.slice(procAddr.range(proci)));
998  const auto procTypes(allTypes.slice(procAddr.range(proci)));
999 
1000  if (procNames != localNames || procTypes != localTypes)
1001  {
1002  hasError = true;
1003 
1004  if (debug || report)
1005  {
1006  Info<< " ***Inconsistent zones across processors, "
1007  "processor 0 has zone names:" << localNames
1008  << " zone types:" << localTypes
1009  << " processor " << proci
1010  << " has zone names:" << procNames
1011  << " zone types:" << procTypes
1012  << endl;
1013  }
1014  }
1015  }
1016 
1017  Pstream::broadcast(hasError);
1018 
1019  // Check local contents
1020  if (!hasError)
1021  {
1022  for (const ZoneType& zn : zones)
1023  {
1024  if (zn.checkParallelSync(false))
1025  {
1026  hasError = true;
1027 
1028  if (debug || (report && UPstream::master()))
1029  {
1030  Info<< " ***Zone " << zn.name()
1031  << " of type " << zn.type()
1032  << " is not correctly synchronised"
1033  << " across coupled boundaries."
1034  << " (coupled faces are either not both"
1035  << " present in set or have same flipmap)" << endl;
1036  }
1037  }
1038  }
1039  }
1040 
1041  return hasError;
1042 }
1043 
1044 
1045 template<class ZoneType, class MeshType>
1047 {
1048  PtrList<ZoneType>& zones = *this;
1049 
1050  for (ZoneType& zn : zones)
1051  {
1052  zn.movePoints(pts);
1053  }
1054 }
1055 
1056 
1057 template<class ZoneType, class MeshType>
1059 {
1060  wordList zoneNames(this->names());
1061  if (zoneNames.empty())
1062  {
1063  this->removeMetaData();
1064  }
1065  else
1066  {
1067  dictionary& meta = this->getMetaData();
1068  meta.set("names", zoneNames);
1069  }
1070 }
1071 
1072 
1073 template<class ZoneType, class MeshType>
1075 {
1076  os << *this;
1077  return os.good();
1079 
1080 
1081 // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
1082 
1083 template<class ZoneType, class MeshType>
1085 (
1086  const word& zoneName
1087 ) const
1088 {
1089  const label zonei = findZoneID(zoneName);
1090 
1091  if (zonei < 0)
1092  {
1094  << "Zone named " << zoneName << " not found." << nl
1095  << "Available zone names: " << names() << endl
1096  << abort(FatalError);
1097  }
1099  return operator[](zonei);
1100 }
1101 
1102 
1103 template<class ZoneType, class MeshType>
1105 (
1106  const word& zoneName
1107 )
1108 {
1109  const label zonei = findZoneID(zoneName);
1110 
1111  if (zonei < 0)
1112  {
1114  << "Zone named " << zoneName << " not found." << nl
1115  << "Available zone names: " << names() << endl
1116  << abort(FatalError);
1117  }
1119  return operator[](zonei);
1120 }
1121 
1122 
1123 template<class ZoneType, class MeshType>
1125 (
1126  const word& zoneName,
1127  const bool verbose
1128 )
1129 {
1130  ZoneType* ptr = findZone(zoneName);
1131 
1132  const bool existing = bool(ptr);
1133 
1134  if (!ptr)
1135  {
1136  ptr = new ZoneType(zoneName, this->size(), *this);
1137  this->push_back(ptr);
1138  }
1139 
1140  if (verbose)
1141  {
1142  Info<< ZoneType::typeName << ' ' << zoneName
1143  << " (" << (existing ? "existing" : "new")
1144  << " at index " << ptr->index() << ')'
1145  << endl;
1146  }
1147 
1148  return *ptr;
1149 }
1150 
1151 
1152 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
1153 
1154 template<class ZoneType, class MeshType>
1155 Foam::Ostream& Foam::operator<<
1156 (
1157  Ostream& os,
1158  const ZoneMesh<ZoneType, MeshType>& zones
1159 )
1160 {
1161  const label sz = zones.size();
1162 
1163  if (sz)
1164  {
1165  os << sz << nl << token::BEGIN_LIST;
1166 
1167  for (label i=0; i < sz; ++i)
1168  {
1169  zones[i].writeDict(os);
1170  }
1171 
1172  os << token::END_LIST;
1173  }
1174  else
1175  {
1176  os << sz << token::BEGIN_LIST << token::END_LIST;
1177  }
1178 
1179  return os;
1180 }
1181 
1182 
1183 // ************************************************************************* //
bool checkParallelSync(const bool report=false) const
Check whether all procs have all zones and in same order.
Definition: ZoneMesh.C:959
dictionary dict
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
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. ...
Definition: UList.H:805
const labelIOList & zoneIDs
Definition: correctPhi.H:59
wordList types() const
Return a list of zone types.
Definition: ZoneMesh.C:444
labelList findMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Extract list indices for all items with &#39;name()&#39; that matches.
void clearAddressing()
Clear addressing.
Definition: ZoneMesh.C:905
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.
Definition: ZoneMesh.C:785
void set(const bitSet &bitset)
Set specified bits from another bitset.
Definition: bitSetI.H:498
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.
Definition: ZoneMesh.C:931
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
label findIndex(const wordRe &key) const
Zone index for the first match, return -1 if not found.
Definition: ZoneMesh.C:690
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
const Map< label > & zoneMap() const
Map of zones containing zone index for all zoned elements.
Definition: ZoneMesh.C:393
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...
Definition: BitOps.C:134
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
int debugSwitch(const char *name, const int deflt=0)
Lookup debug switch or add default value.
Definition: debug.C:222
bool empty() const noexcept
True if List is empty (ie, size() is zero)
Definition: UList.H:675
T & front()
Access first element of the list, position [0].
Definition: UListI.H:230
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
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.
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type get(const label i) const
Return bool value at specified position, always false for out-of-range access.
Definition: UList.H:791
A list of mesh zones.
void stableSort(UList< T > &list)
Stable sort the list.
Definition: UList.C:312
Functions to operate on Pointer Lists.
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
void movePoints(const pointField &pts)
Correct zone mesh after moving points.
Definition: ZoneMesh.C:1039
Extract name (as a word) from an object, typically using its name() method.
Definition: word.H:340
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
dynamicFvMesh & mesh
labelList indices(const wordRe &matcher, const bool useGroups=true) const
Return (sorted) zone indices for all matches.
Definition: ZoneMesh.C:524
label findZoneID(const word &zoneName) const
Find zone index by name, return -1 if not found.
Definition: ZoneMesh.C:718
friend Ostream & operator(Ostream &os, const ZoneMesh< ZoneType, MeshType > &zones)
A class for handling words, derived from Foam::string.
Definition: word.H:63
#define DebugInFunction
Report an information message using Foam::Info.
void sort(UList< T > &list)
Sort the list.
Definition: UList.C:296
void setGroup(const word &groupName, const labelUList &zoneIDs)
Set/add group with zones.
Definition: ZoneMesh.C:862
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:106
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:53
void clearPrimitives()
Clear primitive addressing.
Definition: ZoneMesh.C:919
A HashTable similar to std::unordered_map.
Definition: HashTable.H:108
errorManip< error > abort(error &err)
Definition: errorManip.H:139
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:159
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings...
Definition: wordRe.H:78
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:405
void push_back(const T &val)
Copy append an element to the end of this list.
Definition: DynamicListI.H:555
void resize(const label newLen)
Adjust size of PtrList.
Definition: PtrList.C:95
label whichZone(const label objectIndex) const
Given a global object index, return the zone it is in.
Definition: ZoneMesh.C:406
label push_uniq(const T &val)
Append an element if not already in the list.
Definition: DynamicListI.H:686
ZoneMesh(const ZoneMesh &)=delete
No copy construct.
bool empty() const noexcept
True if the list is empty (ie, size() is zero)
Definition: UPtrListI.H:99
List< word > wordList
List of word.
Definition: fileName.H:59
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:59
#define WarningInFunction
Report a warning using Foam::Warning.
globalIndex procAddr(aMesh.nFaces())
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:103
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:55
surface1 clear()
wordList groupNames() const
A list of the zone group names (if any)
Definition: ZoneMesh.C:458
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:68
bool checkDefinition(const bool report=false) const
Check zone definition. Return true if in error.
Definition: ZoneMesh.C:940
wordList names() const
A list of the zone names.
Definition: ZoneMesh.C:451
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.
Definition: ZoneMesh.C:795
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
entry * set(entry *entryPtr)
Assign a new entry, overwriting any existing entry.
Definition: dictionary.C:765
wordList sortedNames() const
Sorted list of the zone names.
Definition: ZoneMesh.C:486
List< label > labelList
A List of labels.
Definition: List.H:62
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.
Definition: ZoneMesh.C:416
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:180
static int disallowGenericZones
Debug switch to disallow the use of generic zones.
Definition: ZoneMesh.H:143
bitSet bitset(const labelHashSet &locations)
Transform the on locations to a bitSet.
Definition: HashOps.C:63
const ZoneType * cfindZone(const word &zoneName) const
Find zone by name and return const pointer, nullptr on error.
Definition: ZoneMesh.C:750
bool isPattern() const noexcept
The wordRe is a pattern, not a literal string.
Definition: wordReI.H:104
bool writeData(Ostream &os) const
The writeData member function required by regIOobject.
Definition: ZoneMesh.C:1067
Extract type (as a word) from an object, typically using its type() method.
Definition: word.H:361
Namespace for OpenFOAM.
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
label firstMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Find first list item with &#39;name()&#39; 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.
Definition: ZoneMesh.C:849
void updateMetaData()
Update internal meta-data (eg, prior to writing)
Definition: ZoneMesh.C:1051
const pointField & pts