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-------------------------------------------------------------------------------
11License
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
37const Foam::Enum
38<
40>
42({
43 { areaSelectionAlgo::INSIDE, "inside" },
44 { areaSelectionAlgo::OUTSIDE, "outside" },
45 { areaSelectionAlgo::INSIDEPOINT, "insidePoint" },
46 { areaSelectionAlgo::NONE, "none" },
47});
48
49
50const Foam::Enum
51<
53>
55({
56 { faceZoneNaming::NOZONE, "none" },
57 { faceZoneNaming::SINGLE, "single" },
58 { faceZoneNaming::REGION, "region" }
59});
60
61
62const 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,
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
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 {
118 break;
119
121 {
122 // Should already be handled above
123 faceZoneNames_.setSize
124 (
125 nRegions,
126 surfacesDict.get<word>("faceZone")
127 );
128 }
129 break;
130
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,
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,
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 }
502
503 return surfaceToCellZone;
504}
505
506
507
509(
510 const word& name,
511 const labelList& addressing,
512 const boolList& flipMap,
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,
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// ************************************************************************* //
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: Enum.H:61
void setSize(const label n)
Alias for resize()
Definition: List.H:218
label nProcs() const noexcept
Number of ranks associated with PstreamBuffers.
static void allGatherList(const List< commsStruct > &comms, List< T > &values, const int tag, const label comm)
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: PtrList.H:73
const T * set(const label i) const
Definition: PtrList.H:138
void setSize(const label newLen)
Same as resize()
Definition: PtrList.H:151
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
label size() const noexcept
The number of elements in the list.
Definition: UPtrListI.H:106
label findZoneID(const word &zoneName) const
Find zone index by name, return -1 if not found.
Definition: ZoneMesh.C:525
wordList names() const
A list of the zone names.
Definition: ZoneMesh.C:304
A subset of mesh cells.
Definition: cellZone.H:65
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search for an entry (const access) with the given keyword.
Definition: dictionaryI.H:87
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, bool mandatory=true) const
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:67
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:81
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
Definition: polyMesh.H:498
const cellZoneMesh & cellZones() const noexcept
Return cell zone mesh.
Definition: polyMesh.H:504
int myProcNo() const noexcept
Return processor number.
Base class of (analytical or triangulated) surface. Encapsulates all the search routines....
Container for searchableSurfaces. The collection is specified as a dictionary. For example,...
A surface zone on a MeshedSurface.
Definition: surfZone.H:59
faceZoneNaming
How to generate faceZone name.
static labelList getInsidePointNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of surfaces with a cellZone that have 'insidePoint'.
areaSelectionAlgo
Types of selection of area.
static labelList getUnnamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of unnamed surfaces (surfaces without faceZoneName)
static labelList getStandaloneNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of named surfaces without a cellZone.
faceZoneType
What to do with faceZone faces.
static label addFaceZone(const word &name, const labelList &addressing, const boolList &flipMap, polyMesh &mesh)
static const Enum< faceZoneType > faceZoneTypeNames
static labelList getNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of named surfaces (surfaces with faceZoneName)
static labelList getAllClosedNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList, const searchableSurfaces &allGeometry, const labelList &surfaces)
Get indices of surfaces with a cellZone that are closed.
static const Enum< faceZoneNaming > faceZoneNamingNames
static labelList addCellZonesToMesh(const PtrList< surfaceZonesInfo > &surfList, const labelList &namedSurfaces, polyMesh &mesh)
static labelList getUnclosedNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList, const searchableSurfaces &allGeometry, const labelList &surfaces)
Get indices of surfaces with a cellZone that are unclosed.
static labelListList addFaceZonesToMesh(const PtrList< surfaceZonesInfo > &surfList, const labelList &namedSurfaces, polyMesh &mesh)
static const Enum< areaSelectionAlgo > areaSelectionAlgoNames
static label addCellZone(const word &name, const labelList &addressing, polyMesh &mesh)
static labelList getClosedNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList, const searchableSurfaces &allGeometry, const labelList &surfaces)
Get indices of surfaces with a cellZone that are closed and.
A class for handling words, derived from Foam::string.
Definition: word.H:68
dynamicFvMesh & mesh
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
wordList regionNames
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
List< label > labelList
A List of labels.
Definition: List.H:66
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
IOerror FatalIOError
List< bool > boolList
A List of bools.
Definition: List.H:64
error FatalError
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333