surfaceZonesInfo.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) 2013-2015 OpenFOAM Foundation
9  Copyright (C) 2015-2022 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 "surfaceZonesInfo.H"
30 #include "searchableSurface.H"
31 #include "searchableSurfaces.H"
32 #include "polyMesh.H"
33 #include "dictionary.H"
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 const Foam::Enum
38 <
40 >
42 ({
43  { areaSelectionAlgo::INSIDE, "inside" },
44  { areaSelectionAlgo::OUTSIDE, "outside" },
45  { areaSelectionAlgo::INSIDEPOINT, "insidePoint" },
46  { areaSelectionAlgo::NONE, "none" },
47 });
48 
49 
50 const Foam::Enum
51 <
53 >
55 ({
56  { faceZoneNaming::NOZONE, "none" },
57  { faceZoneNaming::SINGLE, "single" },
58  { faceZoneNaming::REGION, "region" }
59 });
60 
61 
62 const Foam::Enum
63 <
65 >
67 ({
68  { faceZoneType::INTERNAL, "internal" },
69  { faceZoneType::BAFFLE, "baffle" },
70  { faceZoneType::BOUNDARY, "boundary" },
71 });
72 
73 
74 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
75 
77 (
78  const searchableSurface& surface,
79  const dictionary& surfacesDict,
80  const wordList& regionNames
81 )
82 :
83  faceZoneNames_(),
84  cellZoneName_(),
85  zoneInside_(NONE),
86  zoneInsidePoint_(point::min),
87  faceType_(INTERNAL)
88 {
89  const label nRegions = surface.regions().size();
90 
91  // Old syntax
92  surfaceZonesInfo::faceZoneNaming namingType = faceZoneNaming::NOZONE;
93 
94  word namingMethod;
95  word faceZoneName;
96  if (surfacesDict.readIfPresent("faceZone", faceZoneName))
97  {
98  // Single zone name per surface
99  if (surfacesDict.found("faceZoneNaming"))
100  {
101  FatalIOErrorInFunction(surfacesDict)
102  << "Cannot provide both \"faceZone\" and \"faceZoneNaming\""
103  << exit(FatalIOError);
104  }
105 
106  namingType = faceZoneNaming::SINGLE;
107  faceZoneNames_.setSize(nRegions, faceZoneName);
108  }
109  else if (surfacesDict.readIfPresent("faceZoneNaming", namingMethod))
110  {
111  //namingType = faceZoneNamingNames.get("faceZoneNaming", surfacesDict);
112  namingType = faceZoneNamingNames[namingMethod];
113 
114  // Generate faceZone names. Maybe make runtime-selection table?
115  switch (namingType)
116  {
117  case faceZoneNaming::NOZONE:
118  break;
119 
120  case faceZoneNaming::SINGLE:
121  {
122  // Should already be handled above
123  faceZoneNames_.setSize
124  (
125  nRegions,
126  surfacesDict.get<word>("faceZone")
127  );
128  }
129  break;
130 
131  case faceZoneNaming::REGION:
132  {
133  faceZoneNames_ = regionNames;
134  }
135  break;
136  }
137  }
138 
139  if (faceZoneNames_.size())
140  {
141  if (faceZoneNames_.size() != nRegions)
142  {
143  FatalIOErrorInFunction(surfacesDict)
144  << "Number of faceZones (through 'faceZones' keyword)"
145  << " does not correspond to the number of regions "
146  << nRegions << " in surface " << surface.name()
147  << exit(FatalIOError);
148  }
149 
150  // Read optional entry to determine inside of faceZone
151 
152  word method;
153  bool hasSide = surfacesDict.readIfPresent("cellZoneInside", method);
154  if (hasSide)
155  {
156  zoneInside_ = areaSelectionAlgoNames[method];
157  if (zoneInside_ == INSIDEPOINT)
158  {
159  surfacesDict.readEntry("insidePoint", zoneInsidePoint_);
160  }
161 
162  }
163  else
164  {
165  // Check old syntax
166  bool inside;
167  if (surfacesDict.readIfPresent("zoneInside", inside))
168  {
169  hasSide = true;
170  zoneInside_ = (inside ? INSIDE : OUTSIDE);
171  }
172  }
173 
174  // Read optional cellZone name
175 
176  if (surfacesDict.readIfPresent("cellZone", cellZoneName_))
177  {
178  if
179  (
180  (
181  zoneInside_ == INSIDE
182  || zoneInside_ == OUTSIDE
183  )
184  && !surface.hasVolumeType()
185  )
186  {
187  IOWarningInFunction(surfacesDict)
188  << "Illegal entry zoneInside "
189  << areaSelectionAlgoNames[zoneInside_]
190  << " for faceZones "
191  << faceZoneNames_
192  << " since surface is not closed." << endl;
193  }
194  }
195  else if (hasSide)
196  {
197  IOWarningInFunction(surfacesDict)
198  << "Unused entry zoneInside for faceZone "
199  << faceZoneNames_
200  << " since no cellZone specified."
201  << endl;
202  }
203 
204  // How to handle faces on faceZone
205  word faceTypeMethod;
206  if (surfacesDict.readIfPresent("faceType", faceTypeMethod))
207  {
208  faceType_ = faceZoneTypeNames[faceTypeMethod];
209  }
210  }
211 }
212 
213 
215 (
216  const wordList& faceZoneNames,
217  const word& cellZoneName,
218  const areaSelectionAlgo& zoneInside,
219  const point& zoneInsidePoint,
220  const faceZoneType& faceType
221 )
222 :
223  faceZoneNames_(faceZoneNames),
224  cellZoneName_(cellZoneName),
225  zoneInside_(zoneInside),
226  zoneInsidePoint_(zoneInsidePoint),
227  faceType_(faceType)
228 {}
229 
230 
232 :
233  faceZoneNames_(surfZone.faceZoneNames()),
234  cellZoneName_(surfZone.cellZoneName()),
235  zoneInside_(surfZone.zoneInside()),
236  zoneInsidePoint_(surfZone.zoneInsidePoint()),
237  faceType_(surfZone.faceType())
238 {}
239 
240 
242 (
243  const PtrList<surfaceZonesInfo>& surfList
244 )
245 {
246  labelList anonymousSurfaces(surfList.size());
247 
248  label i = 0;
249  forAll(surfList, surfI)
250  {
251  if (surfList[surfI].faceZoneNames().empty())
252  {
253  anonymousSurfaces[i++] = surfI;
254  }
255  }
256  anonymousSurfaces.setSize(i);
257 
258  return anonymousSurfaces;
259 }
260 
261 
263 (
264  const PtrList<surfaceZonesInfo>& surfList
265 )
266 {
267  labelList namedSurfaces(surfList.size());
268 
269  label namedI = 0;
270  forAll(surfList, surfI)
271  {
272  if
273  (
274  surfList.set(surfI)
275  && surfList[surfI].faceZoneNames().size()
276  )
277  {
278  namedSurfaces[namedI++] = surfI;
279  }
280  }
281  namedSurfaces.setSize(namedI);
282 
283  return namedSurfaces;
284 }
285 
286 
288 (
289  const PtrList<surfaceZonesInfo>& surfList
290 )
291 {
292  labelList namedSurfaces(surfList.size());
293 
294  label namedI = 0;
295  forAll(surfList, surfI)
296  {
297  if
298  (
299  surfList.set(surfI)
300  && surfList[surfI].faceZoneNames().size()
301  && !surfList[surfI].cellZoneName().size()
302  )
303  {
304  namedSurfaces[namedI++] = surfI;
305  }
306  }
307  namedSurfaces.setSize(namedI);
308 
309  return namedSurfaces;
310 }
311 
312 
314 (
315  const PtrList<surfaceZonesInfo>& surfList,
316  const searchableSurfaces& allGeometry,
317  const labelList& surfaces
318 )
319 {
320  labelList closed(surfList.size());
321 
322  label closedI = 0;
323  forAll(surfList, surfI)
324  {
325  if
326  (
327  surfList.set(surfI)
328  && surfList[surfI].cellZoneName().size()
329  && (
330  surfList[surfI].zoneInside() == surfaceZonesInfo::INSIDE
331  || surfList[surfI].zoneInside() == surfaceZonesInfo::OUTSIDE
332  )
333  && allGeometry[surfaces[surfI]].hasVolumeType()
334  )
335  {
336  closed[closedI++] = surfI;
337  }
338  }
339  closed.setSize(closedI);
340 
341  return closed;
342 }
343 
344 
346 (
347  const PtrList<surfaceZonesInfo>& surfList,
348  const searchableSurfaces& allGeometry,
349  const labelList& surfaces
350 )
351 {
352  labelList unclosed(surfList.size());
353 
354  label unclosedI = 0;
355  forAll(surfList, surfI)
356  {
357  if
358  (
359  surfList.set(surfI)
360  && !allGeometry[surfaces[surfI]].hasVolumeType()
361  )
362  {
363  unclosed[unclosedI++] = surfI;
364  }
365  }
366  unclosed.setSize(unclosedI);
367 
368  return unclosed;
369 }
370 
371 
373 (
374  const PtrList<surfaceZonesInfo>& surfList,
375  const searchableSurfaces& allGeometry,
376  const labelList& surfaces
377 )
378 {
379  labelList closed(surfList.size());
380 
381  label closedI = 0;
382  forAll(surfList, surfI)
383  {
384  if
385  (
386  surfList.set(surfI)
387  && surfList[surfI].cellZoneName().size()
388  && allGeometry[surfaces[surfI]].hasVolumeType()
389  )
390  {
391  closed[closedI++] = surfI;
392  }
393  }
394  closed.setSize(closedI);
395 
396  return closed;
397 }
398 
399 
401 (
402  const PtrList<surfaceZonesInfo>& surfList
403 )
404 {
405  labelList closed(surfList.size());
406 
407  label closedI = 0;
408  forAll(surfList, surfI)
409  {
410  if
411  (
412  surfList.set(surfI)
413  && surfList[surfI].cellZoneName().size()
414  && surfList[surfI].zoneInside() == surfaceZonesInfo::INSIDEPOINT
415  )
416  {
417  closed[closedI++] = surfI;
418  }
419  }
420  closed.setSize(closedI);
421 
422  return closed;
423 }
424 
425 
427 (
428  const word& name,
429  const labelList& addressing,
430  polyMesh& mesh
431 )
432 {
433  cellZoneMesh& cellZones = mesh.cellZones();
434 
435  label zoneI = cellZones.findZoneID(name);
436 
437  if (zoneI == -1)
438  {
439  zoneI = cellZones.size();
440  cellZones.setSize(zoneI+1);
441  cellZones.set
442  (
443  zoneI,
444  new cellZone
445  (
446  name, // name
447  addressing, // addressing
448  zoneI, // index
449  cellZones // cellZoneMesh
450  )
451  );
452  }
453  return zoneI;
454 }
455 
456 
458 (
459  const PtrList<surfaceZonesInfo>& surfList,
460  const labelList& namedSurfaces,
461  polyMesh& mesh
462 )
463 {
464  labelList surfaceToCellZone(surfList.size(), -1);
465 
466  forAll(namedSurfaces, i)
467  {
468  label surfI = namedSurfaces[i];
469 
470  const word& cellZoneName = surfList[surfI].cellZoneName();
471 
472  if (cellZoneName != word::null)
473  {
474  label zoneI = addCellZone
475  (
476  cellZoneName,
477  labelList(0), // addressing
478  mesh
479  );
480 
481  surfaceToCellZone[surfI] = zoneI;
482  }
483  }
484 
485  // Check they are synced
486  List<wordList> allCellZones(Pstream::nProcs());
487  allCellZones[Pstream::myProcNo()] = mesh.cellZones().names();
488  Pstream::allGatherList(allCellZones);
489 
490  for (label proci = 1; proci < allCellZones.size(); proci++)
491  {
492  if (allCellZones[proci] != allCellZones[0])
493  {
495  << "Zones not synchronised among processors." << nl
496  << " Processor0 has cellZones:" << allCellZones[0]
497  << " , processor" << proci
498  << " has cellZones:" << allCellZones[proci]
499  << exit(FatalError);
500  }
501  }
503  return surfaceToCellZone;
504 }
505 
506 
507 
509 (
510  const word& name,
511  const labelList& addressing,
512  const boolList& flipMap,
513  polyMesh& mesh
514 )
515 {
516  faceZoneMesh& faceZones = mesh.faceZones();
517 
518  label zoneI = faceZones.findZoneID(name);
519 
520  if (zoneI == -1)
521  {
522  zoneI = faceZones.size();
523  faceZones.setSize(zoneI+1);
524 
525  faceZones.set
526  (
527  zoneI,
528  new faceZone
529  (
530  name, // name
531  addressing, // addressing
532  flipMap, // flipMap
533  zoneI, // index
534  faceZones // faceZoneMesh
535  )
536  );
537  }
538 // else
539 // {
540 // // Already have faceZone. Add to addressing (if necessary)
541 //
542 // faceZone& fz = faceZones[zoneI];
543 //
544 // DebugVar(fz.size());
545 // DebugVar(fz.addressing().size());
546 //
547 // if (fz.size() != addressing.size())
548 // {
549 // faceZones.clearAddressing();
550 // fz.resetAddressing(addressing, flipMap);
551 // }
552 // else
553 // {
554 // const labelList& oldAddressing = fz;
555 // const boolList& oldFlipMap = fz.flipMap();
556 //
557 // bitSet isZoneFace(mesh.nFaces(), oldAddressing);
558 // bitSet isZoneFlip(mesh.nFaces());
559 // forAll(oldAddressing, i)
560 // {
561 // const label facei = oldAddressing[i];
562 // isZoneFlip[facei] = oldFlipMap[i];
563 // }
564 //
565 // const bitSet newZoneFace(mesh.nFaces(), addressing);
566 // bitSet newZoneFlip(mesh.nFaces());
567 // forAll(addressing, i)
568 // {
569 // if (flipMap[i])
570 // {
571 // newZoneFlip.set(addressing[i]);
572 // }
573 // }
574 //
575 // bool isChanged = false;
576 // forAll(isZoneFace, facei)
577 // {
578 // if
579 // (
580 // isZoneFace[facei] != newZoneFace[facei]
581 // || isZoneFlip[facei] != newZoneFlip[facei]
582 // )
583 // {
584 // isZoneFace[facei] = newZoneFace[facei];
585 // isZoneFlip[facei] = newZoneFlip[facei];
586 // isChanged = true;
587 // }
588 // }
589 //
590 // if (isChanged)
591 // {
592 // labelList newAddressing(isZoneFace.sortedToc());
593 // boolList newFlip(newAddressing.size(), false);
594 // forAll(newAddressing, i)
595 // {
596 // newFlip[i] = isZoneFlip[newAddressing[i]];
597 // }
598 // faceZones.clearAddressing();
599 // fz.resetAddressing
600 // (
601 // std::move(newAddressing),
602 // std::move(newFlip)
603 // );
604 // }
605 // }
606 // }
607  return zoneI;
608 }
609 
610 
612 (
613  const PtrList<surfaceZonesInfo>& surfList,
614  const labelList& namedSurfaces,
615  polyMesh& mesh
616 )
617 {
618  labelListList surfaceToFaceZones(surfList.size());
619 
620  faceZoneMesh& faceZones = mesh.faceZones();
621 
622  forAll(namedSurfaces, i)
623  {
624  label surfI = namedSurfaces[i];
625 
626  const wordList& faceZoneNames = surfList[surfI].faceZoneNames();
627 
628  surfaceToFaceZones[surfI].setSize(faceZoneNames.size(), -1);
629  forAll(faceZoneNames, j)
630  {
631  const word& faceZoneName = faceZoneNames[j];
632 
633  label zoneI = addFaceZone
634  (
635  faceZoneName, //name
636  labelList(0), //addressing
637  boolList(0), //flipmap
638  mesh
639  );
640 
641  surfaceToFaceZones[surfI][j] = zoneI;
642  }
643  }
644 
645  // Check they are synced
646  List<wordList> allFaceZones(Pstream::nProcs());
647  allFaceZones[Pstream::myProcNo()] = faceZones.names();
648  Pstream::allGatherList(allFaceZones);
649 
650  for (label proci = 1; proci < allFaceZones.size(); proci++)
651  {
652  if (allFaceZones[proci] != allFaceZones[0])
653  {
655  << "Zones not synchronised among processors." << nl
656  << " Processor0 has faceZones:" << allFaceZones[0]
657  << " , processor" << proci
658  << " has faceZones:" << allFaceZones[proci]
659  << exit(FatalError);
660  }
661  }
662 
663  return surfaceToFaceZones;
664 }
665 
666 
667 // ************************************************************************* //
static const Enum< areaSelectionAlgo > areaSelectionAlgoNames
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
A surface zone on a MeshedSurface.
Definition: surfZone.H:52
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
static labelListList addFaceZonesToMesh(const PtrList< surfaceZonesInfo > &surfList, const labelList &namedSurfaces, polyMesh &mesh)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
static const Enum< faceZoneNaming > faceZoneNamingNames
static labelList addCellZonesToMesh(const PtrList< surfaceZonesInfo > &surfList, const labelList &namedSurfaces, polyMesh &mesh)
static const Enum< faceZoneType > faceZoneTypeNames
wordList regionNames
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1029
static labelList getStandaloneNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of named surfaces without a cellZone.
static labelList getUnclosedNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList, const searchableSurfaces &allGeometry, const labelList &surfaces)
Get indices of surfaces with a cellZone that are unclosed.
static labelList getAllClosedNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList, const searchableSurfaces &allGeometry, const labelList &surfaces)
Get indices of surfaces with a cellZone that are closed.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:414
static void allGatherList(List< T > &values, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Gather data, but keep individual values separate. Uses linear/tree communication. ...
bool readEntry(const word &key, const dictionary &dict, EnumType &val, const bool mandatory=true) const
Find entry and assign to T val.
Definition: Enum.C:215
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
Definition: UPstream.H:1020
void setSize(const label n)
Alias for resize()
Definition: List.H:289
dynamicFvMesh & mesh
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:52
label findZoneID(const word &zoneName) const
Find zone index by name, return -1 if not found.
Definition: ZoneMesh.C:513
A class for handling words, derived from Foam::string.
Definition: word.H:63
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:113
static const word null
An empty word.
Definition: word.H:84
Container for searchableSurfaces. The collection is specified as a dictionary. For example...
static labelList getInsidePointNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of surfaces with a cellZone that have &#39;insidePoint&#39;.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
static labelList getUnnamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of unnamed surfaces (surfaces without faceZoneName)
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
const wordList surface
Standard surface field types (scalar, vector, tensor, etc)
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
Definition: polyMesh.H:646
void setSize(const label newLen)
Same as resize()
Definition: PtrList.H:316
A subset of mesh cells.
Definition: cellZone.H:58
List< word > wordList
List of word.
Definition: fileName.H:58
vector point
Point is a vector.
Definition: point.H:37
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:607
surfaceZonesInfo(const searchableSurface &surface, const dictionary &surfacesDict, const wordList &regionNames)
Construct from surfaces and dictionary and fully resolved.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:55
faceZoneNaming
How to generate faceZone name.
const cellZoneMesh & cellZones() const noexcept
Return cell zone mesh.
Definition: polyMesh.H:654
static labelList getClosedNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList, const searchableSurfaces &allGeometry, const labelList &surfaces)
Get indices of surfaces with a cellZone that are closed and.
static labelList getNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of named surfaces (surfaces with faceZoneName)
wordList names() const
A list of the zone names.
Definition: ZoneMesh.C:292
faceZoneType
What to do with faceZone faces.
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:73
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:60
List< label > labelList
A List of labels.
Definition: List.H:62
List< bool > boolList
A List of bools.
Definition: List.H:60
areaSelectionAlgo
Types of selection of area.
static label addFaceZone(const word &name, const labelList &addressing, const boolList &flipMap, polyMesh &mesh)
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...
static label addCellZone(const word &name, const labelList &addressing, polyMesh &mesh)