ZoneList.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2025 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "ZoneList.H"
27 #include "Pstream.H"
28 #include "Time.H"
29 #include "demandDrivenData.H"
30 
31 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32 
33 template<class ZoneType, class ZonesType, class MeshType>
35 {
36  if
37  (
38  readOpt() == IOobject::MUST_READ
39  || readOpt() == IOobject::MUST_READ_IF_MODIFIED
40  || (readOpt() == IOobject::READ_IF_PRESENT && headerOk())
41  )
42  {
43  if (readOpt() == IOobject::MUST_READ_IF_MODIFIED)
44  {
46  << "Specified IOobject::MUST_READ_IF_MODIFIED but class"
47  << " does not support automatic rereading."
48  << endl;
49  }
50 
51  PtrListDictionary<ZoneType>& zones = *this;
52 
53  // Read zones
54  Istream& is = readStream(ZonesType::typeName);
55 
56  PtrList<entry> patchEntries(is);
57  zones.setSize(patchEntries.size());
58 
59  forAll(zones, zi)
60  {
61  zones.set
62  (
63  zi,
64  patchEntries[zi].keyword(),
65  new ZoneType
66  (
67  patchEntries[zi].keyword(),
68  patchEntries[zi].dict(),
69  static_cast<const ZonesType&>(*this)
70  )
71  );
72  }
73 
74  // Check state of IOstream
75  is.check
76  (
77  "ZoneList::ZoneList"
78  "(const IOobject&, const MeshType&)"
79  );
80 
81  close();
82 
83  return true;
84  }
85  else
86  {
87  // Nothing read
88  return false;
89  }
90 }
91 
92 
93 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
94 
95 template<class ZoneType, class ZonesType, class MeshType>
97 (
98  const IOobject& io,
99  const MeshType& mesh
100 )
101 :
102  regIOobject(io),
104  mesh_(mesh),
105  timeIndex_(mesh.time().timeIndex())
106 {
107  read();
108 }
109 
110 
111 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
112 
113 template<class ZoneType, class ZonesType, class MeshType>
115 {
116  clearAddressing();
117 }
118 
119 
120 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
121 
122 template<class ZoneType, class ZonesType, class MeshType>
124 (
125  const label objectIndex
126 ) const
127 {
128  forAll(*this, zi)
129  {
130  if (this->operator[](zi).localIndex(objectIndex) != -1)
131  {
132  return true;
133  }
134  }
135 
136  return false;
137 }
138 
139 
140 template<class ZoneType, class ZonesType, class MeshType>
142 (
143  const word& name
144 ) const
145 {
146  if (name == "all")
147  {
148  return &all();
149  }
150  else
151  {
153  }
154 }
155 
156 
157 template<class ZoneType, class ZonesType, class MeshType>
159 (
160  const label objectIndex
161 ) const
162 {
163  labelList zones;
164 
165  forAll(*this, zi)
166  {
167  if (this->operator[](zi).localIndex(objectIndex) != -1)
168  {
169  zones.append(zi);
170  }
171  }
172 
173  return zones;
174 }
175 
176 
177 template<class ZoneType, class ZonesType, class MeshType>
179 (
180  const UList<wordRe>& zoneNames,
181  const bool warnNotFound
182 ) const
183 {
185 
186  if (zoneNames.size())
187  {
188  forAll(zoneNames, i)
189  {
190  const labelList indices
191  (
192  this->findIndices(zoneNames[i])
193  );
194 
195  if (indices.size())
196  {
197  set.insert(indices);
198  }
199  else if (warnNotFound)
200  {
202  << "Cannot find zone " << zoneNames[i]
203  << endl;
204  }
205  }
206  }
207 
208  return set;
209 }
210 
211 
212 template<class ZoneType, class ZonesType, class MeshType>
214 (
215  ZoneType* zonePtr
216 ) const
217 {
220 
221  if (found(zonePtr->name()))
222  {
223  zones[zonePtr->name()] = *zonePtr;
224  delete zonePtr;
225  }
226  else
227  {
228  zones.PtrListDictionary<ZoneType>::append
229  (
230  zonePtr->name(),
231  zonePtr
232  );
233  }
234 
235  timeIndex_ = time().timeIndex();
236 
237  return *zonePtr;
238 }
239 
240 
241 template<class ZoneType, class ZonesType, class MeshType>
243 (
244  const ZoneType& zone
245 ) const
246 {
248  const_cast<ZoneList<ZoneType, ZonesType, MeshType>&>(*this);
249 
250  if (found(zone.name()))
251  {
252  zones[zone.name()] = zone;
253  }
254  else
255  {
256  zones.PtrListDictionary<ZoneType>::append
257  (
258  zone.name(),
259  zone.clone(*this)
260  );
261  }
262 
263  timeIndex_ = time().timeIndex();
264 
265  return zone;
266 }
267 
268 
269 template<class ZoneType, class ZonesType, class MeshType>
271 {
272  PtrListDictionary<ZoneType>& zones = *this;
273 
274  forAll(zones, zi)
275  {
276  zones[zi].clearAddressing();
277  }
278 }
279 
280 
281 template<class ZoneType, class ZonesType, class MeshType>
283 {
284  clearAddressing();
286 }
287 
288 
289 template<class ZoneType, class ZonesType, class MeshType>
291 (
292  const bool report
293 ) const
294 {
295  bool inError = false;
296 
297  const PtrListDictionary<ZoneType>& zones = *this;
298 
299  forAll(zones, zi)
300  {
301  inError |= zones[zi].checkDefinition(report);
302  }
303  return inError;
304 }
305 
306 
307 template<class ZoneType, class ZonesType, class MeshType>
309 (
310  const bool report
311 ) const
312 {
313  if (!Pstream::parRun())
314  {
315  return false;
316  }
317 
318 
319  const PtrListDictionary<ZoneType>& zones = *this;
320 
321  bool hasError = false;
322 
323  // Collect all names
324  List<wordList> allNames(Pstream::nProcs());
325  allNames[Pstream::myProcNo()] = this->toc();
326  Pstream::gatherList(allNames);
327  Pstream::scatterList(allNames);
328 
329  // Have every processor check but only master print error.
330 
331  for (label proci = 1; proci < allNames.size(); proci++)
332  {
333  if
334  (
335  (allNames[proci] != allNames[0])
336  )
337  {
338  hasError = true;
339 
340  if (debug || (report && Pstream::master()))
341  {
342  Info<< " ***Inconsistent zones across processors, "
343  "processor 0 has zone names:" << allNames[0]
344  << " processor " << proci << " has zone names:"
345  << allNames[proci]
346  << endl;
347  }
348  }
349  }
350 
351  // Check contents
352  if (!hasError)
353  {
354  forAll(zones, zi)
355  {
356  if (zones[zi].checkParallelSync(false))
357  {
358  hasError = true;
359 
360  if (debug || (report && Pstream::master()))
361  {
362  Info<< " ***Zone " << zones[zi].name()
363  << " is not correctly synchronised"
364  << " across coupled boundaries."
365  << " (coupled faces are either not both"
366  << " present in set or have same flipmap)" << endl;
367  }
368  }
369  }
370  }
371 
372  return hasError;
373 }
374 
375 
376 template<class ZoneType, class ZonesType, class MeshType>
378 (
379  const List<labelHashSet>& zonesIndices
380 )
381 {
382  PtrListDictionary<ZoneType>& zones = *this;
383 
384  if (zonesIndices.size() != zones.size())
385  {
387  << "zonesIndices.size() " << zonesIndices.size()
388  << " != number of zones " << zones.size()
389  << exit(FatalError);
390  }
391 
392  forAll(zonesIndices, zonei)
393  {
394  zones[zonei].insert(zonesIndices[zonei]);
395  }
396 
397  timeIndex_ = time().timeIndex();
398 }
399 
400 
401 template<class ZoneType, class ZonesType, class MeshType>
403 {
404  const PtrListDictionary<ZoneType>& zones = *this;
405 
406  forAll(zones, zi)
407  {
408  if (!zones[zi].topoUpdate())
409  {
410  return true;
411  }
412  }
413 
414  return false;
415 }
416 
417 
418 template<class ZoneType, class ZonesType, class MeshType>
420 (
421  const pointField& p
422 )
423 {
424  PtrListDictionary<ZoneType>& zones = *this;
425 
426  forAll(zones, zi)
427  {
428  zones[zi].movePoints(p);
429  }
430 }
431 
432 
433 template<class ZoneType, class ZonesType, class MeshType>
435 (
436  const polyTopoChangeMap& map
437 )
438 {
439  PtrListDictionary<ZoneType>& zones = *this;
440 
441  forAll(zones, zi)
442  {
443  zones[zi].topoChange(map);
444  }
445 
446  if (all_.valid())
447  {
448  const label allSize = static_cast<const ZonesType&>(*this).allSize();
449  if (all().size() != allSize)
450  {
451  all_() = identityMap
452  (
453  static_cast<const ZonesType&>(*this).allSize()
454  );
455  }
456  }
457 
458  timeIndex_ = time().timeIndex();
459 }
460 
461 
462 template<class ZoneType, class ZonesType, class MeshType>
464 (
465  const polyMeshMap& map
466 )
467 {
468  PtrListDictionary<ZoneType>& zones = *this;
469 
470  forAll(zones, zi)
471  {
472  zones[zi].mapMesh(map);
473  }
474 
475  all_.clear();
476 
477  timeIndex_ = time().timeIndex();
478 }
479 
480 
481 template<class ZoneType, class ZonesType, class MeshType>
483 (
484  const polyDistributionMap& map
485 )
486 {
487  PtrListDictionary<ZoneType>& zones = *this;
488 
489  forAll(zones, zi)
490  {
491  zones[zi].distribute(map);
492  }
493 
494  all_.clear();
495 
496  timeIndex_ = time().timeIndex();
497 }
498 
499 
500 template<class ZoneType, class ZonesType, class MeshType>
502 {
503  clearAddressing();
504  otherZones.clearAddressing();
505 
506  PtrListDictionary<ZoneType>& zones = *this;
507 
508  DynamicList<label> toOtherZone;
509 
510  forAll(zones, zi)
511  {
512  const label ozi = otherZones.findIndex(zones[zi].name());
513 
514  if (ozi < 0)
515  {
516  toOtherZone.append(zi);
517  }
518  }
519 
520  forAll(otherZones, ozi)
521  {
522  const label zi = this->findIndex(otherZones[ozi].name());
523 
524  if (zi < 0)
525  {
526  zones.append
527  (
528  otherZones[ozi].name(),
529  otherZones[ozi].clone
530  (
531  static_cast<const ZonesType&>(*this)
532  )
533  );
534  otherZones.set(ozi, otherZones[ozi].name(), nullptr);
535  }
536  else
537  {
538  zones[zi].swap(otherZones[ozi]);
539  }
540  }
541 
542  forAll(toOtherZone, i)
543  {
544  otherZones.PtrListDictionary<ZoneType>::append
545  (
546  zones[toOtherZone[i]].name(),
547  zones[toOtherZone[i]].clone(otherZones)
548  );
549  zones.set(toOtherZone[i], zones[toOtherZone[i]].name(), nullptr);
550  }
551 
552  zones.shrink();
553  otherZones.shrink();
554 
555  timeIndex_ = time().timeIndex();
556 }
557 
558 
559 template<class ZoneType, class ZonesType, class MeshType>
561 {
562  readOpt() = IOobject::READ_IF_PRESENT;
563  return read();
564 }
565 
566 
567 template<class ZoneType, class ZonesType, class MeshType>
569 {
570  os << *this;
571  return os.good();
572 }
573 
574 
575 template<class ZoneType, class ZonesType, class MeshType>
577 (
581  const bool write
582 ) const
583 {
584  if (this->size())
585  {
586  return regIOobject::writeObject(fmt, ver, cmp, write);
587  }
588  else
589  {
590  return true;
591  }
592 }
593 
594 
595 template<class ZoneType, class ZonesType, class MeshType>
597 {
598  const ZonesType& zones = static_cast<const ZonesType&>(*this);
599 
600  if (!all_.valid())
601  {
602  all_ = new ZoneType
603  (
604  "all",
605  identityMap(zones.allSize()),
606  zones
607  );
608  }
609 
610  return all_();
611 }
612 
613 
614 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
615 
616 template<class ZoneType, class ZonesType, class MeshType>
618 (
619  const word& name
620 ) const
621 {
622  const ZoneType* ptr = lookupPtr(name);
623 
624  if (ptr == nullptr)
625  {
627  << "Cannot find " << ZoneType::typeName << " " << name
628  << exit(FatalError);
629  }
630 
631  return *ptr;
632 }
633 
634 
635 template<class ZoneType, class ZonesType, class MeshType>
637 (
638  const word& name
639 )
640 {
641  ZoneType* ptr = this->lookupPtr(name);
642 
643  if (ptr == nullptr)
644  {
646  << "Cannot find " << ZoneType::typeName << " " << name
647  << exit(FatalError);
648  }
649 
650  return *ptr;
651 }
652 
653 
654 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
655 
656 template<class ZoneType, class ZonesType, class MeshType>
657 Foam::Ostream& Foam::operator<<
658 (
659  Ostream& os,
661 )
662 {
663  os << zones.size() << nl << token::BEGIN_LIST;
664 
665  forAll(zones, zi)
666  {
667  zones[zi].writeDict(os);
668  }
669 
670  os << token::END_LIST;
671 
672  return os;
673 }
674 
675 
676 // ************************************************************************* //
bool found
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
void insert(const word &, T *)
Add at head of dictionary.
void clear()
Clear the dictionary.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:109
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
Version number type.
Definition: IOstream.H:97
streamFormat
Enumeration for the format of data in the stream.
Definition: IOstream.H:87
compressionType
Enumeration for the format of data in the stream.
Definition: IOstream.H:194
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:333
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:178
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
void append(const word &key, T *)
Append an element at the end of the list.
autoPtr< T > set(const label, const word &key, T *)
Set element to pointer provided and return old element.
label timeIndex() const
Return current time index.
Definition: TimeStateI.H:28
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:74
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311
A list of mesh zones.
Definition: ZoneList.H:71
bool checkDefinition(const bool report=false) const
Check zone definition. Return true if in error.
Definition: ZoneList.C:291
const ZoneType & all() const
Return const reference to the all zone.
Definition: ZoneList.C:596
label timeIndex() const
Definition: ZoneList.H:122
~ZoneList()
Destructor.
Definition: ZoneList.C:114
void insert(const List< labelHashSet > &zonesIndices)
Insert given indices into zones.
Definition: ZoneList.C:378
virtual bool writeData(Ostream &) const
writeData member function required by regIOobject
Definition: ZoneList.C:568
const ZoneType & append(ZoneType *) const
Append or update a zone.
Definition: ZoneList.C:214
bool found(const label objectIndex) const
Return true if objectIndex is in any zone.
Definition: ZoneList.C:124
ZoneList(const IOobject &, const MeshType &)
Read constructor given IOobject and a MeshType reference.
Definition: ZoneList.C:97
bool noTopoUpdate() const
Return true if any of the zones were not updated by zoneGenerators.
Definition: ZoneList.C:402
bool readIfPresent()
Read zones if the zones file is present.
Definition: ZoneList.C:560
virtual bool writeObject(IOstream::streamFormat, IOstream::versionNumber, IOstream::compressionType, const bool write) const
Write using given format, version and compression.
Definition: ZoneList.C:577
labelList whichZones(const label objectIndex) const
Given a global object index, return the list of zones it is in.
Definition: ZoneList.C:159
virtual void distribute(const polyDistributionMap &)
Redistribute or update using the given distribution map.
Definition: ZoneList.C:483
labelHashSet zoneSet(const UList< wordRe > &zoneNames, const bool warnNotFound=true) const
Return the set of zone indices corresponding to the given names.
Definition: ZoneList.C:179
void swap(ZonesType &)
Swap zones.
Definition: ZoneList.C:501
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
Definition: ZoneList.C:464
void clearAddressing()
Clear addressing.
Definition: ZoneList.C:270
virtual void movePoints(const pointField &)
Correct zones after moving points.
Definition: ZoneList.C:420
void clear()
Clear the zones.
Definition: ZoneList.C:282
bool checkParallelSync(const bool report=false) const
Check whether all procs have all zones and in same order. Return.
Definition: ZoneList.C:309
virtual void topoChange(const polyTopoChangeMap &map)
Update topology using the given map.
Definition: ZoneList.C:435
const ZoneType * lookupPtr(const word &name) const
Return const reference to ZoneType by name.
Definition: ZoneList.C:142
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:420
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
Class containing mesh-to-mesh mapping information.
Definition: polyMeshMap.H:51
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:55
A class for handling words, derived from string.
Definition: word.H:62
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
Template functions to aid in the implementation of demand driven data.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
tUEqn clear()
#define WarningInFunction
Report a warning using Foam::Warning.
void read(Istream &, label &, const dictionary &)
In-place read with dictionary lookup.
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:258
labelList findIndices(const ListType &, typename ListType::const_reference, const label start=0)
Find all occurrences of given element. Linear search.
messageStream Info
T clone(const T &t)
Definition: List.H:55
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
error FatalError
labelList identityMap(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
static const char nl
Definition: Ostream.H:267
dictionary dict
volScalarField & p