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 -------------------------------------------------------------------------------
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.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 
224 template<class ZoneType, class MeshType>
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,
251  (
252  entries[zonei].keyword(),
253  entries[zonei].dict(),
254  zonei,
255  *this
256  )
257  );
258  }
259 
260  entries.clear();
261 }
262 
263 
264 template<class ZoneType, class MeshType>
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 
305 template<class ZoneType, class MeshType>
307 (
308  const IOobject& io,
309  const MeshType& mesh
310 )
311 :
312  PtrList<ZoneType>(),
313  regIOobject(io),
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 
322 template<class ZoneType, class MeshType>
324 (
325  const IOobject& io,
326  const MeshType& mesh,
327  Foam::zero
328 )
329 :
330  PtrList<ZoneType>(),
332  mesh_(mesh)
333 {}
334 
335 
336 template<class ZoneType, class MeshType>
338 (
339  const IOobject& io,
340  const MeshType& mesh,
341  const label size
342 )
343 :
344  PtrList<ZoneType>(size),
345  regIOobject(io),
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 
354 template<class ZoneType, class MeshType>
356 (
357  const IOobject& io,
358  const MeshType& mesh,
359  const PtrList<ZoneType>& list
360 )
361 :
362  PtrList<ZoneType>(),
363  regIOobject(io),
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 
380 template<class ZoneType, class MeshType>
382 (
383  const IOobject& io,
384  const MeshType& mesh,
385  PtrList<entry>&& entries
386 )
387 :
388  PtrList<ZoneType>(),
389  regIOobject(io),
390  mesh_(mesh)
391 {
392  if (!readIOcontents(true)) // allowOptionalRead = true
393  {
394  populate(std::move(entries));
395  }
396  entries.clear();
397 }
398 
399 
400 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
401 
402 template<class ZoneType, class MeshType>
405 {
406  if (!zoneMapPtr_)
407  {
408  calcZoneMap();
409  }
411  return *zoneMapPtr_;
412 }
413 
414 
415 template<class ZoneType, class MeshType>
417 (
418  const label objectIndex
419 ) const
420 {
421  return zoneMap().lookup(objectIndex, -1);
422 }
423 
424 
425 template<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  }
448  }
449  }
450  return zones.size();
451 }
452 
453 
454 template<class ZoneType, class MeshType>
456 {
457  return PtrListOps::get<word>(*this, typeOp<ZoneType>());
458 }
459 
460 
461 template<class ZoneType, class MeshType>
463 {
464  return PtrListOps::get<word>(*this, nameOp<ZoneType>());
465 }
466 
467 
468 template<class ZoneType, class MeshType>
470 {
471  return this->groupZoneIDs().sortedToc();
472 }
473 
474 
475 template<class ZoneType, class MeshType>
477 (
478  const wordRe& matcher
479 ) const
480 {
481  return PtrListOps::names(*this, matcher);
482 }
483 
484 
485 template<class ZoneType, class MeshType>
487 (
488  const wordRes& matcher
489 )
490 const
491 {
492  return PtrListOps::names(*this, matcher);
493 }
494 
495 
496 template<class ZoneType, class MeshType>
498 {
499  wordList sorted(this->names());
500  Foam::sort(sorted);
502  return sorted;
503 }
504 
505 
506 template<class ZoneType, class MeshType>
508 (
509  const wordRe& matcher
510 ) const
511 {
512  wordList sorted(this->names(matcher));
513  Foam::sort(sorted);
515  return sorted;
516 }
517 
518 
519 template<class ZoneType, class MeshType>
521 (
522  const wordRes& matcher
523 )
524 const
525 {
526  wordList sorted(this->names(matcher));
527  Foam::sort(sorted);
529  return sorted;
530 }
531 
532 
533 template<class ZoneType, class MeshType>
535 (
536  const wordRe& matcher,
537  const bool useGroups
538 ) const
539 {
540  if (matcher.empty())
541  {
542  return labelList();
543  }
544 
545  // Only check groups if requested and they exist
546  const bool checkGroups = (useGroups && this->hasGroupIDs());
547 
548  labelHashSet ids;
549 
550  if (checkGroups)
551  {
552  ids.reserve(this->size());
553  }
554 
555  if (matcher.isPattern())
556  {
557  if (checkGroups)
558  {
559  const auto& groupLookup = groupZoneIDs();
560  forAllConstIters(groupLookup, iter)
561  {
562  if (matcher(iter.key()))
563  {
564  // Add ids associated with the group
565  ids.insert(iter.val());
566  }
567  }
568  }
569 
570  if (ids.empty())
571  {
572  return PtrListOps::findMatching(*this, matcher);
573  }
574  else
575  {
576  ids.insert(PtrListOps::findMatching(*this, matcher));
577  }
578  }
579  else
580  {
581  // Literal string.
582  // Special version of above for reduced memory footprint
583 
584  const label zoneId = PtrListOps::firstMatching(*this, matcher);
585 
586  if (zoneId >= 0)
587  {
588  return labelList(one{}, zoneId);
589  }
590  else if (checkGroups)
591  {
592  const auto iter = groupZoneIDs().cfind(matcher);
593 
594  if (iter.good())
595  {
596  // Add ids associated with the group
597  ids.insert(iter.val());
598  }
599  }
600  }
602  return ids.sortedToc();
603 }
604 
605 
606 template<class ZoneType, class MeshType>
608 (
609  const wordRes& matcher,
610  const bool useGroups
611 ) const
612 {
613  if (matcher.empty())
614  {
615  return labelList();
616  }
617  else if (matcher.size() == 1)
618  {
619  return this->indices(matcher.front(), useGroups);
620  }
621 
622  labelHashSet ids;
623 
624  // Only check groups if requested and they exist
625  if (useGroups && this->hasGroupIDs())
626  {
627  ids.reserve(this->size());
628 
629  const auto& groupLookup = groupZoneIDs();
630  forAllConstIters(groupLookup, iter)
631  {
632  if (matcher(iter.key()))
633  {
634  // Add ids associated with the group
635  ids.insert(iter.val());
636  }
637  }
638  }
639 
640  if (ids.empty())
641  {
642  return PtrListOps::findMatching(*this, matcher);
643  }
644  else
645  {
646  ids.insert(PtrListOps::findMatching(*this, matcher));
647  }
649  return ids.sortedToc();
650 }
651 
652 
653 template<class ZoneType, class MeshType>
655 (
656  const wordRes& allow,
657  const wordRes& deny,
658  const bool useGroups
659 ) const
660 {
661  if (allow.empty() && deny.empty())
662  {
663  // Fast-path: select all
664  return identity(this->size());
665  }
666 
667  const wordRes::filter matcher(allow, deny);
668 
669  labelHashSet ids;
670 
671  // Only check groups if requested and they exist
672  if (useGroups && this->hasGroupIDs())
673  {
674  ids.reserve(this->size());
675 
676  const auto& groupLookup = groupZoneIDs();
677  forAllConstIters(groupLookup, iter)
678  {
679  if (matcher(iter.key()))
680  {
681  // Add ids associated with the group
682  ids.insert(iter.val());
683  }
684  }
685  }
686 
687  if (ids.empty())
688  {
689  return PtrListOps::findMatching(*this, matcher);
690  }
691  else
692  {
693  ids.insert(PtrListOps::findMatching(*this, matcher));
694  }
696  return ids.sortedToc();
697 }
698 
699 
700 template<class ZoneType, class MeshType>
702 (
703  const wordRe& key
704 ) const
705 {
706  if (key.empty())
707  {
708  return -1;
709  }
710  return PtrListOps::firstMatching(*this, key);
711 }
712 
713 
714 template<class ZoneType, class MeshType>
716 (
717  const wordRes& matcher
718 ) const
719 {
720  if (matcher.empty())
721  {
722  return -1;
723  }
724  return PtrListOps::firstMatching(*this, matcher);
725 }
726 
727 
728 template<class ZoneType, class MeshType>
730 (
731  const word& zoneName
732 ) const
733 {
734  if (zoneName.empty())
735  {
736  return -1;
737  }
738 
739  label zoneId = PtrListOps::firstMatching(*this, zoneName);
740 
741  if (zoneId < 0)
742  {
744  << "Zone named " << zoneName << " not found. "
745  << "List of available zone names: " << names() << endl;
746 
747  // Used for -dry-run, for example
748  if (disallowGenericZones != 0)
749  {
750  Info<< "Creating dummy zone " << zoneName << endl;
751  auto& zm = const_cast<ZoneMesh<ZoneType, MeshType>&>(*this);
752  zm.emplace_back(zoneName, zm.size(), zm);
753  }
754  }
756  return zoneId;
757 }
758 
759 
760 template<class ZoneType, class MeshType>
762 (
763  const word& zoneName
764 ) const
765 {
766  if (zoneName.empty())
767  {
768  return nullptr;
769  }
770 
771  const PtrList<ZoneType>& zones = *this;
772 
773  for (auto iter = zones.begin(); iter != zones.end(); ++iter)
774  {
775  const ZoneType* ptr = iter.get();
776 
777  if (ptr && zoneName == ptr->name())
778  {
779  return ptr;
780  }
781  }
782 
783  // Used for -dry-run, for example
784  if (disallowGenericZones != 0)
785  {
786  Info<< "Creating dummy zone " << zoneName << endl;
787  auto& zm = const_cast<ZoneMesh<ZoneType, MeshType>&>(*this);
788  zm.emplace_back(zoneName, zm.size(), zm);
789  }
791  return nullptr;
792 }
793 
794 
795 template<class ZoneType, class MeshType>
797 (
798  const word& zoneName
799 )
800 {
801  return const_cast<ZoneType*>(this->cfindZone(zoneName));
802 }
803 
804 
805 template<class ZoneType, class MeshType>
807 (
808  const labelUList& zoneIds
809 ) const
810 {
811  bitSet bitset;
812 
813  for (const label zonei : zoneIds)
814  {
815  #ifdef FULLDEBUG
816  if (zonei < 0 || zonei >= this->size())
817  {
819  << ZoneType::typeName << " "
820  << zonei << " out of range [0," << this->size() << ")"
821  << abort(FatalError);
822  }
823  #endif
824 
825  bitset.set
826  (
827  static_cast<const labelList&>(this->operator[](zonei))
828  );
829  }
831  return bitset;
832 }
833 
834 
835 template<class ZoneType, class MeshType>
837 (
838  const wordRe& matcher,
839  const bool useGroups
840 ) const
841 {
842  // matcher.empty() is handled by indices()
843  return this->selection(this->indices(matcher, useGroups));
844 }
845 
846 
847 template<class ZoneType, class MeshType>
849 (
850  const wordRes& matcher,
851  const bool useGroups
852 ) const
853 {
854  // matcher.empty() is handled by indices()
855  return this->selection(this->indices(matcher, useGroups));
856 }
857 
858 
859 template<class ZoneType, class MeshType>
862 {
863  if (!groupIDsPtr_)
864  {
865  calcGroupIDs();
866  }
868  return *groupIDsPtr_;
869 }
870 
871 
872 template<class ZoneType, class MeshType>
874 (
875  const word& groupName,
876  const labelUList& zoneIDs
877 )
878 {
879  groupIDsPtr_.reset(nullptr);
880 
881  PtrList<ZoneType>& zones = *this;
882 
883  boolList pending(zones.size(), true);
884 
885  // Add to specified zones
886  for (const label zonei : zoneIDs)
887  {
888  if (pending.test(zonei))
889  {
890  pending.unset(zonei);
891  zones[zonei].addGroup(groupName);
892  }
893  }
894 
895  // Remove from other zones
896  forAll(zones, zonei)
897  {
898  if (pending.test(zonei))
899  {
900  zones[zonei].removeGroup(groupName);
901  }
902  }
903 }
904 
905 
906 // Private until it is more generally required (and gets a better name?)
907 template<class ZoneType, class MeshType>
909 {
910  zoneMapPtr_.reset(nullptr);
911  additionalMapPtr_.reset(nullptr);
912  groupIDsPtr_.reset(nullptr);
913 }
914 
915 
916 template<class ZoneType, class MeshType>
918 {
919  clearLocalAddressing();
920 
921  PtrList<ZoneType>& zones = *this;
922 
923  for (ZoneType& zn : zones)
924  {
925  zn.clearAddressing();
926  }
927 }
928 
929 
930 template<class ZoneType, class MeshType>
932 {
933  PtrList<ZoneType>& zones = *this;
934 
935  for (ZoneType& zn : zones)
936  {
937  zn.clearPrimitives();
938  }
939 }
940 
941 
942 template<class ZoneType, class MeshType>
944 {
945  clearAddressing();
947 }
948 
949 
950 template<class ZoneType, class MeshType>
952 (
953  const bool report
954 ) const
955 {
956  bool hasError = false;
957 
958  const PtrList<ZoneType>& zones = *this;
959 
960  for (const ZoneType& zn : zones)
961  {
962  hasError |= zn.checkDefinition(report);
963  }
965  return hasError;
966 }
967 
968 
969 template<class ZoneType, class MeshType>
971 (
972  const bool report
973 ) const
974 {
975  if (!UPstream::parRun())
976  {
977  return false;
978  }
979 
980  const PtrList<ZoneType>& zones = *this;
981 
982  bool hasError = false;
983 
984  const wordList localNames(this->names());
985  const wordList localTypes(this->types());
986 
987  // Check and report error(s) on master
988  // - don't need indexing on master itself
989 
990  const globalIndex procAddr
991  (
992  globalIndex::gatherNonLocal{},
993  localNames.size()
994  );
995 
996  const wordList allNames(procAddr.gather(localNames));
997  const wordList allTypes(procAddr.gather(localTypes));
998 
999  // Automatically restricted to master
1000  for (const int proci : procAddr.subProcs())
1001  {
1002  const auto procNames(allNames.slice(procAddr.range(proci)));
1003  const auto procTypes(allTypes.slice(procAddr.range(proci)));
1004 
1005  if (procNames != localNames || procTypes != localTypes)
1006  {
1007  hasError = true;
1008 
1009  if (debug || report)
1010  {
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
1017  << endl;
1018  }
1019  }
1020  }
1021 
1022  Pstream::broadcast(hasError);
1023 
1024  // Check local contents
1025  if (!hasError)
1026  {
1027  for (const ZoneType& zn : zones)
1028  {
1029  if (zn.checkParallelSync(false))
1030  {
1031  hasError = true;
1032 
1033  if (debug || (report && UPstream::master()))
1034  {
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;
1041  }
1042  }
1043  }
1044  }
1045 
1046  return hasError;
1047 }
1048 
1049 
1050 template<class ZoneType, class MeshType>
1052 {
1053  PtrList<ZoneType>& zones = *this;
1054 
1055  for (ZoneType& zn : zones)
1056  {
1057  zn.movePoints(pts);
1058  }
1059 }
1060 
1061 
1062 template<class ZoneType, class MeshType>
1064 {
1065  wordList zoneNames(this->names());
1066  if (zoneNames.empty())
1067  {
1068  this->removeMetaData();
1069  }
1070  else
1071  {
1072  dictionary& meta = this->getMetaData();
1073  meta.set("names", zoneNames);
1074  }
1075 }
1076 
1077 
1078 template<class ZoneType, class MeshType>
1080 {
1081  os << *this;
1082  return os.good();
1084 
1085 
1086 // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
1087 
1088 template<class ZoneType, class MeshType>
1090 (
1091  const word& zoneName
1092 ) const
1093 {
1094  const label zonei = findZoneID(zoneName);
1095 
1096  if (zonei < 0)
1097  {
1099  << "Zone named " << zoneName << " not found." << nl
1100  << "Available zone names: " << names() << endl
1101  << abort(FatalError);
1102  }
1104  return operator[](zonei);
1105 }
1106 
1107 
1108 template<class ZoneType, class MeshType>
1110 (
1111  const word& zoneName
1112 )
1113 {
1114  const label zonei = findZoneID(zoneName);
1115 
1116  if (zonei < 0)
1117  {
1119  << "Zone named " << zoneName << " not found." << nl
1120  << "Available zone names: " << names() << endl
1121  << abort(FatalError);
1122  }
1124  return operator[](zonei);
1125 }
1126 
1127 
1128 template<class ZoneType, class MeshType>
1130 (
1131  const word& zoneName,
1132  const bool verbose
1133 )
1134 {
1135  ZoneType* ptr = findZone(zoneName);
1136 
1137  const bool existing = bool(ptr);
1138 
1139  if (!ptr)
1140  {
1141  ptr = new ZoneType(zoneName, this->size(), *this);
1142  this->push_back(ptr);
1143  }
1144 
1145  if (verbose)
1146  {
1147  Info<< ZoneType::typeName << ' ' << zoneName
1148  << " (" << (existing ? "existing" : "new")
1149  << " at index " << ptr->index() << ')'
1150  << endl;
1151  }
1152 
1153  return *ptr;
1154 }
1155 
1156 
1157 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
1158 
1159 template<class ZoneType, class MeshType>
1160 Foam::Ostream& Foam::operator<<
1161 (
1162  Ostream& os,
1163  const ZoneMesh<ZoneType, MeshType>& zones
1164 )
1165 {
1166  const label sz = zones.size();
1167 
1168  if (sz)
1169  {
1170  os << sz << nl << token::BEGIN_LIST;
1171 
1172  for (label i=0; i < sz; ++i)
1173  {
1174  zones[i].writeDict(os);
1175  }
1176 
1177  os << token::END_LIST;
1178  }
1179  else
1180  {
1181  os << sz << token::BEGIN_LIST << token::END_LIST;
1182  }
1183 
1184  return os;
1185 }
1186 
1187 
1188 // ************************************************************************* //
bool checkParallelSync(const bool report=false) const
Check whether all procs have all zones and in same order.
Definition: ZoneMesh.C:964
dictionary dict
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
const labelIOList & zoneIDs
Definition: correctPhi.H:59
wordList types() const
Return a list of zone types.
Definition: ZoneMesh.C:448
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:910
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:790
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:936
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:600
label findIndex(const wordRe &key) const
Zone index for the first match, return -1 if not found.
Definition: ZoneMesh.C:695
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:397
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:697
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:529
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.
A list of mesh zones.
void stableSort(UList< T > &list)
Stable sort the list.
Definition: UList.C:311
bool broadcast(Type *values, int count, MPI_Datatype datatype, const int communicator)
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:1044
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:286
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
The (sorted) patch indices for all matches, optionally matching zone groups.
Definition: ZoneMesh.C:528
label findZoneID(const word &zoneName) const
Find zone index by name, return -1 if not found.
Definition: ZoneMesh.C:723
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...
Definition: labelLists.C:44
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:295
void setGroup(const word &groupName, const labelUList &zoneIDs)
Set/add group with zones.
Definition: ZoneMesh.C:867
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:924
auto key(const Type &t) -> std::enable_if_t< std::is_enum_v< Type >, std::underlying_type_t< Type > >
Definition: foamGltfBase.H:103
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
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. ...
Definition: UList.H:827
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:418
void push_back(const T &val)
Copy append an element to the end of this list.
Definition: DynamicListI.H:558
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:410
label push_uniq(const T &val)
Append an element if not already in the list.
Definition: DynamicListI.H:688
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())
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:54
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.
Definition: UList.H:813
surface1 clear()
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
wordList groupNames() const
A list of the zone group names (if any)
Definition: ZoneMesh.C:462
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:945
wordList names() const
A list of the zone names.
Definition: ZoneMesh.C:455
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:800
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:490
List< label > labelList
A List of labels.
Definition: List.H:61
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:420
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:755
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:1072
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:854
void updateMetaData()
Update internal meta-data (eg, prior to writing)
Definition: ZoneMesh.C:1056
const pointField & pts