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-2023 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  zoneInsidePoints_(),
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  const bool foundPoints = surfacesDict.readIfPresent
160  (
161  "insidePoints",
162  zoneInsidePoints_,
164  );
165 
166  if (foundPoints)
167  {
168  if (surfacesDict.found("insidePoint", keyType::LITERAL))
169  {
170  FatalIOErrorInFunction(surfacesDict)
171  << "Cannot supply both 'insidePoint'"
172  << " and 'insidePoints'" << exit(FatalIOError);
173  }
174  }
175  else
176  {
177  zoneInsidePoints_ = pointField
178  (
179  1,
180  surfacesDict.get<point>("insidePoint", keyType::LITERAL)
181  );
182  }
183  }
184  }
185  else
186  {
187  // Check old syntax
188  bool inside;
189  if (surfacesDict.readIfPresent("zoneInside", inside))
190  {
191  hasSide = true;
192  zoneInside_ = (inside ? INSIDE : OUTSIDE);
193  }
194  }
195 
196  // Read optional cellZone name
197 
198  if (surfacesDict.readIfPresent("cellZone", cellZoneName_))
199  {
200  if
201  (
202  (
203  zoneInside_ == INSIDE
204  || zoneInside_ == OUTSIDE
205  )
206  && !surface.hasVolumeType()
207  )
208  {
209  IOWarningInFunction(surfacesDict)
210  << "Illegal entry zoneInside "
211  << areaSelectionAlgoNames[zoneInside_]
212  << " for faceZones "
213  << faceZoneNames_
214  << " since surface is not closed." << endl;
215  }
216  }
217  else if (hasSide)
218  {
219  IOWarningInFunction(surfacesDict)
220  << "Unused entry zoneInside for faceZone "
221  << faceZoneNames_
222  << " since no cellZone specified."
223  << endl;
224  }
225 
226  // How to handle faces on faceZone
227  word faceTypeMethod;
228  if (surfacesDict.readIfPresent("faceType", faceTypeMethod))
229  {
230  faceType_ = faceZoneTypeNames[faceTypeMethod];
231  }
232  }
233 }
234 
235 
237 (
238  const wordList& faceZoneNames,
239  const word& cellZoneName,
240  const areaSelectionAlgo& zoneInside,
241  const pointField& zoneInsidePoints,
242  const faceZoneType& faceType
243 )
244 :
245  faceZoneNames_(faceZoneNames),
246  cellZoneName_(cellZoneName),
247  zoneInside_(zoneInside),
248  zoneInsidePoints_(zoneInsidePoints),
249  faceType_(faceType)
250 {}
251 
252 
254 :
255  faceZoneNames_(surfZone.faceZoneNames()),
256  cellZoneName_(surfZone.cellZoneName()),
257  zoneInside_(surfZone.zoneInside()),
258  zoneInsidePoints_(surfZone.zoneInsidePoints()),
259  faceType_(surfZone.faceType())
260 {}
261 
262 
264 (
265  const PtrList<surfaceZonesInfo>& surfList
266 )
267 {
268  labelList anonymousSurfaces(surfList.size());
269 
270  label i = 0;
271  forAll(surfList, surfI)
272  {
273  if (surfList[surfI].faceZoneNames().empty())
274  {
275  anonymousSurfaces[i++] = surfI;
276  }
277  }
278  anonymousSurfaces.setSize(i);
279 
280  return anonymousSurfaces;
281 }
282 
283 
285 (
286  const PtrList<surfaceZonesInfo>& surfList
287 )
288 {
289  labelList namedSurfaces(surfList.size());
290 
291  label namedI = 0;
292  forAll(surfList, surfI)
293  {
294  if
295  (
296  surfList.set(surfI)
297  && surfList[surfI].faceZoneNames().size()
298  )
299  {
300  namedSurfaces[namedI++] = surfI;
301  }
302  }
303  namedSurfaces.setSize(namedI);
304 
305  return namedSurfaces;
306 }
307 
308 
310 (
311  const PtrList<surfaceZonesInfo>& surfList
312 )
313 {
314  labelList namedSurfaces(surfList.size());
315 
316  label namedI = 0;
317  forAll(surfList, surfI)
318  {
319  if
320  (
321  surfList.set(surfI)
322  && surfList[surfI].faceZoneNames().size()
323  && !surfList[surfI].cellZoneName().size()
324  )
325  {
326  namedSurfaces[namedI++] = surfI;
327  }
328  }
329  namedSurfaces.setSize(namedI);
330 
331  return namedSurfaces;
332 }
333 
334 
336 (
337  const PtrList<surfaceZonesInfo>& surfList,
338  const searchableSurfaces& allGeometry,
339  const labelList& surfaces
340 )
341 {
342  labelList closed(surfList.size());
343 
344  label closedI = 0;
345  forAll(surfList, surfI)
346  {
347  if
348  (
349  surfList.set(surfI)
350  && surfList[surfI].cellZoneName().size()
351  && (
352  surfList[surfI].zoneInside() == surfaceZonesInfo::INSIDE
353  || surfList[surfI].zoneInside() == surfaceZonesInfo::OUTSIDE
354  )
355  && allGeometry[surfaces[surfI]].hasVolumeType()
356  )
357  {
358  closed[closedI++] = surfI;
359  }
360  }
361  closed.setSize(closedI);
362 
363  return closed;
364 }
365 
366 
368 (
369  const PtrList<surfaceZonesInfo>& surfList,
370  const searchableSurfaces& allGeometry,
371  const labelList& surfaces
372 )
373 {
374  labelList unclosed(surfList.size());
375 
376  label unclosedI = 0;
377  forAll(surfList, surfI)
378  {
379  if
380  (
381  surfList.set(surfI)
382  && !allGeometry[surfaces[surfI]].hasVolumeType()
383  )
384  {
385  unclosed[unclosedI++] = surfI;
386  }
387  }
388  unclosed.setSize(unclosedI);
389 
390  return unclosed;
391 }
392 
393 
395 (
396  const PtrList<surfaceZonesInfo>& surfList,
397  const searchableSurfaces& allGeometry,
398  const labelList& surfaces
399 )
400 {
401  labelList closed(surfList.size());
402 
403  label closedI = 0;
404  forAll(surfList, surfI)
405  {
406  if
407  (
408  surfList.set(surfI)
409  && surfList[surfI].cellZoneName().size()
410  && allGeometry[surfaces[surfI]].hasVolumeType()
411  )
412  {
413  closed[closedI++] = surfI;
414  }
415  }
416  closed.setSize(closedI);
417 
418  return closed;
419 }
420 
421 
423 (
424  const PtrList<surfaceZonesInfo>& surfList
425 )
426 {
427  labelList closed(surfList.size());
428 
429  label closedI = 0;
430  forAll(surfList, surfI)
431  {
432  if
433  (
434  surfList.set(surfI)
435  && surfList[surfI].cellZoneName().size()
436  && surfList[surfI].zoneInside() == surfaceZonesInfo::INSIDEPOINT
437  )
438  {
439  closed[closedI++] = surfI;
440  }
441  }
442  closed.setSize(closedI);
443 
444  return closed;
445 }
446 
447 
449 (
450  const word& name,
451  const labelList& addressing,
452  polyMesh& mesh
453 )
454 {
455  cellZoneMesh& cellZones = mesh.cellZones();
456 
457  label zoneID = cellZones.findZoneID(name);
458 
459  if (zoneID == -1)
460  {
461  zoneID = cellZones.size();
462 
463  cellZones.emplace_back
464  (
465  name,
466  addressing,
467  zoneID,
468  cellZones
469  );
470  }
471 
472  return zoneID;
473 }
474 
475 
477 (
478  const PtrList<surfaceZonesInfo>& surfList,
479  const labelList& namedSurfaces,
480  polyMesh& mesh
481 )
482 {
483  labelList surfaceToCellZone(surfList.size(), -1);
484 
485  forAll(namedSurfaces, i)
486  {
487  label surfI = namedSurfaces[i];
488 
489  const word& cellZoneName = surfList[surfI].cellZoneName();
490 
491  if (!cellZoneName.empty())
492  {
493  label zoneI = addCellZone
494  (
495  cellZoneName,
496  labelList(), // addressing
497  mesh
498  );
499 
500  surfaceToCellZone[surfI] = zoneI;
501  }
502  }
503 
504  // Check they are synced
505  List<wordList> allCellZones(Pstream::nProcs());
506  allCellZones[Pstream::myProcNo()] = mesh.cellZones().names();
507  Pstream::allGatherList(allCellZones);
508 
509  for (label proci = 1; proci < allCellZones.size(); proci++)
510  {
511  if (allCellZones[proci] != allCellZones[0])
512  {
514  << "Zones not synchronised among processors." << nl
515  << " Processor0 has cellZones:" << allCellZones[0]
516  << " , processor" << proci
517  << " has cellZones:" << allCellZones[proci]
518  << exit(FatalError);
519  }
520  }
522  return surfaceToCellZone;
523 }
524 
525 
526 
528 (
529  const word& name,
530  const labelList& addressing,
531  const boolList& flipMap,
532  polyMesh& mesh
533 )
534 {
535  faceZoneMesh& faceZones = mesh.faceZones();
536 
537  label zoneID = faceZones.findZoneID(name);
538 
539  if (zoneID == -1)
540  {
541  zoneID = faceZones.size();
542 
543  faceZones.emplace_back
544  (
545  name,
546  addressing,
547  flipMap,
548  zoneID,
549  faceZones
550  );
551  }
552 // else
553 // {
554 // // Already have faceZone. Add to addressing (if necessary)
555 //
556 // faceZone& fz = faceZones[zoneI];
557 //
558 // DebugVar(fz.size());
559 // DebugVar(fz.addressing().size());
560 //
561 // if (fz.size() != addressing.size())
562 // {
563 // faceZones.clearAddressing();
564 // fz.resetAddressing(addressing, flipMap);
565 // }
566 // else
567 // {
568 // const labelList& oldAddressing = fz;
569 // const boolList& oldFlipMap = fz.flipMap();
570 //
571 // bitSet isZoneFace(mesh.nFaces(), oldAddressing);
572 // bitSet isZoneFlip(mesh.nFaces());
573 // forAll(oldAddressing, i)
574 // {
575 // const label facei = oldAddressing[i];
576 // isZoneFlip[facei] = oldFlipMap[i];
577 // }
578 //
579 // const bitSet newZoneFace(mesh.nFaces(), addressing);
580 // bitSet newZoneFlip(mesh.nFaces());
581 // forAll(addressing, i)
582 // {
583 // if (flipMap[i])
584 // {
585 // newZoneFlip.set(addressing[i]);
586 // }
587 // }
588 //
589 // bool isChanged = false;
590 // forAll(isZoneFace, facei)
591 // {
592 // if
593 // (
594 // isZoneFace[facei] != newZoneFace[facei]
595 // || isZoneFlip[facei] != newZoneFlip[facei]
596 // )
597 // {
598 // isZoneFace[facei] = newZoneFace[facei];
599 // isZoneFlip[facei] = newZoneFlip[facei];
600 // isChanged = true;
601 // }
602 // }
603 //
604 // if (isChanged)
605 // {
606 // labelList newAddressing(isZoneFace.sortedToc());
607 // boolList newFlip(newAddressing.size(), false);
608 // forAll(newAddressing, i)
609 // {
610 // newFlip[i] = isZoneFlip[newAddressing[i]];
611 // }
612 // faceZones.clearAddressing();
613 // fz.resetAddressing
614 // (
615 // std::move(newAddressing),
616 // std::move(newFlip)
617 // );
618 // }
619 // }
620 // }
621 
622  return zoneID;
623 }
624 
625 
627 (
628  const PtrList<surfaceZonesInfo>& surfList,
629  const labelList& namedSurfaces,
630  polyMesh& mesh
631 )
632 {
633  labelListList surfaceToFaceZones(surfList.size());
634 
635  faceZoneMesh& faceZones = mesh.faceZones();
636 
637  forAll(namedSurfaces, i)
638  {
639  label surfI = namedSurfaces[i];
640 
641  const wordList& faceZoneNames = surfList[surfI].faceZoneNames();
642 
643  surfaceToFaceZones[surfI].setSize(faceZoneNames.size(), -1);
644  forAll(faceZoneNames, j)
645  {
646  const word& faceZoneName = faceZoneNames[j];
647 
648  label zoneI = addFaceZone
649  (
650  faceZoneName, //name
651  labelList(), //addressing
652  boolList(), //flipmap
653  mesh
654  );
655 
656  surfaceToFaceZones[surfI][j] = zoneI;
657  }
658  }
659 
660  // Check they are synced
661  List<wordList> allFaceZones(Pstream::nProcs());
662  allFaceZones[Pstream::myProcNo()] = faceZones.names();
663  Pstream::allGatherList(allFaceZones);
664 
665  for (label proci = 1; proci < allFaceZones.size(); proci++)
666  {
667  if (allFaceZones[proci] != allFaceZones[0])
668  {
670  << "Zones not synchronised among processors." << nl
671  << " Processor0 has faceZones:" << allFaceZones[0]
672  << " , processor" << proci
673  << " has faceZones:" << allFaceZones[proci]
674  << exit(FatalError);
675  }
676  }
677 
678  return surfaceToFaceZones;
679 }
680 
681 
682 // ************************************************************************* //
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:598
bool readIfPresent(const word &key, const dictionary &dict, EnumType &val, const bool warnOnly=false) const
Find an entry if present, and assign to T val.
Definition: EnumI.H:111
A surface zone on a MeshedSurface.
Definition: surfZone.H:52
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
static labelListList addFaceZonesToMesh(const PtrList< surfaceZonesInfo > &surfList, const labelList &namedSurfaces, polyMesh &mesh)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
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:1074
static labelList getStandaloneNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of named surfaces without a cellZone.
T & emplace_back(Args &&... args)
Construct and append an element to the end of the list, return reference to the new list element...
Definition: PtrListI.H:105
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:421
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. ...
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:1065
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
void setSize(const label n)
Alias for resize()
Definition: List.H:316
dynamicFvMesh & mesh
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
label findZoneID(const word &zoneName) const
Find zone index by name, return -1 if not found.
Definition: ZoneMesh.C:629
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:106
Container for searchableSurfaces. The collection is specified as a dictionary. For example...
String literal.
Definition: keyType.H:82
static labelList getInsidePointNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of surfaces with a cellZone that have &#39;insidePoint&#39;.
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:670
void setSize(const label newLen)
Same as resize()
Definition: PtrList.H:337
List< word > wordList
List of word.
Definition: fileName.H:59
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...
Definition: error.H:64
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:627
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:678
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:362
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:74
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)