print.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) 2026 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 "print.H"
27 #include "polyMesh.H"
28 #include "boundSphere.H"
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35  namespace zoneGenerators
36  {
39  }
40 }
41 
42 
43 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
44 
46 (
47  const word& name,
48  const polyMesh& mesh,
49  const dictionary& dict
50 )
51 :
53  zoneType_
54  (
55  zoneTypesAllNames.lookupOrDefault
56  (
57  "zoneType",
58  dict,
60  )
61  ),
62  zoneNames_
63  (
64  dict.found("zone")
65  ? new wordList(1, dict.lookup<word>("zone"))
66  : dict.found("zones")
67  ? new wordList(dict.lookup<wordList>("zones"))
68  : nullptr
69  ),
70  geometry_(dict.lookupOrDefault<bool>("geometry", true))
71 {}
72 
73 
74 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
75 
77 {}
78 
79 
80 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
81 
83 {
84  // Determine which zone types to print
85  const bool printPointZones =
86  zoneType_ == zoneTypesAll::point || zoneType_ == zoneTypesAll::all;
87  const bool printFaceZones =
88  zoneType_ == zoneTypesAll::face || zoneType_ == zoneTypesAll::all;
89  const bool printCellZones =
90  zoneType_ == zoneTypesAll::cell || zoneType_ == zoneTypesAll::all;
91 
92  // Get a list of which zones to print. Either user-defined, or all zones.
93  wordList allZoneNames;
94  if (!zoneNames_.valid())
95  {
96  wordHashSet allZoneNameSet;
97  if (printPointZones) allZoneNameSet.insert(mesh_.pointZones().toc());
98  if (printFaceZones) allZoneNameSet.insert(mesh_.faceZones().toc());
99  if (printCellZones) allZoneNameSet.insert(mesh_.cellZones().toc());
100  allZoneNames = allZoneNameSet.toc();
101  }
102  const wordList& zoneNames =
103  zoneNames_.valid() ? zoneNames_() : allZoneNames;
104 
105  // Reference bits of the mesh
106  const pointField& points = mesh_.points();
107  const faceList& faces = mesh_.faces();
108  const scalarField& magFaceAreas = mesh_.magFaceAreas();
109  const pointField& faceCentres = mesh_.faceCentres();
110  const cellList& cells = mesh_.cells();
111  const scalarField& cellVolumes = mesh_.cellVolumes();
112  const pointField& cellCentres = mesh_.cellCentres();
113 
114  // Keep a set of points for which to calculate geometry. Store both forward
115  // and backward addressing so that the maps can be efficiently re-used
116  // across multiple zones.
117  labelList pointZonePoints(points.size(), -1);
118  DynamicList<label> zonePointPoints;
119 
120  // Print each zone in turn ...
121  forAll(zoneNames, zonei)
122  {
123  const word& name = zoneNames[zonei];
124 
125  // Determine what types of zones with this name we are printing
126  const bool printPointZone =
127  printPointZones && mesh_.pointZones().found(name);
128  const bool printFaceZone =
129  printFaceZones && mesh_.faceZones().found(name);
130  const bool printCellZone =
131  printCellZones && mesh_.cellZones().found(name);
132  const bool printMultiple =
133  printPointZone + printFaceZone + printCellZone > 1;
134 
135  // Preamble
136  Info<< "Zone"
137  << (printMultiple ? "s" : "")
138  << " '" << name << "' " << (printMultiple ? "have" : "has");
139 
140  // Initialise integral geometry
141  label pointZoneSize = 0;
142  point pointZoneAverage = point::zero;
143  scalar faceZoneMagArea = 0;
144  point faceZoneCentroid = point::zero;
145  scalar cellZoneVolume = 0;
146  point cellZoneCentroid = point::zero;
147 
148  // Clear the point set
149  forAll(zonePointPoints, zonePointi)
150  {
151  pointZonePoints[zonePointPoints[zonePointi]] = -1;
152  }
153  zonePointPoints.clear();
154 
155  if (printPointZone)
156  {
157  const pointZone& pz = mesh_.pointZones()[name];
158  const label nPz = returnReduce(pz.size(), sumOp<label>());
159 
160  // Print the number of points
161  Info<< ' ' << nPz << " points";
162 
163  if (geometry_ && nPz)
164  {
165  // Generate the global number of points and the average position
166  pointZoneSize = nPz;
167  forAll(pz, i)
168  {
169  pointZoneAverage += points[pz[i]];
170  }
171  reduce(pointZoneAverage, sumOp<point>());
172  pointZoneAverage /= pointZoneSize;
173 
174  // Store the indices of the points in this zone
175  forAll(pz, pzPointi)
176  {
177  const label pointi = pz[pzPointi];
178  if (pointZonePoints[pointi] != -1) continue;
179  pointZonePoints[pointi] = zonePointPoints.size();
180  zonePointPoints.append(pointi);
181  }
182  }
183  }
184 
185  if (printFaceZone)
186  {
187  const faceZone& fz = mesh_.faceZones()[name];
188  const label nFz = returnReduce(fz.size(), sumOp<label>());
189 
190  // Print the number of faces
191  if (printPointZone && printCellZone) Info<< ",";
192  if (printPointZone && !printCellZone) Info<< " and";
193  Info<< ' ' << nFz << " faces";
194 
195  if (geometry_ && nFz)
196  {
197  // Generate the global face-zone area magnitude and centroid
198  forAll(fz, fzFacei)
199  {
200  faceZoneMagArea += magFaceAreas[fz[fzFacei]];
201  faceZoneCentroid +=
202  magFaceAreas[fz[fzFacei]]*faceCentres[fz[fzFacei]];
203  }
204  reduce(faceZoneMagArea, sumOp<scalar>());
205  reduce(faceZoneCentroid, sumOp<point>());
206  faceZoneCentroid /= faceZoneMagArea;
207 
208  // Store the indices of the points in this zone
209  forAll(fz, fzFacei)
210  {
211  const label facei = fz[fzFacei];
212  forAll(faces[facei], facePointi)
213  {
214  const label pointi = faces[facei][facePointi];
215  if (pointZonePoints[pointi] != -1) continue;
216  pointZonePoints[pointi] = zonePointPoints.size();
217  zonePointPoints.append(pointi);
218  }
219  }
220  }
221  }
222 
223  if (printCellZone)
224  {
225  const cellZone& cz = mesh_.cellZones()[name];
226  const label nCz = returnReduce(cz.size(), sumOp<label>());
227 
228  // Print the number of cells
229  if (printPointZone || printFaceZone) Info<< " and";
230  Info<< ' ' << nCz << " cells";
231 
232  if (geometry_ && nCz)
233  {
234  // Generate the global cell-zone volume and centroid
235  forAll(cz, czCelli)
236  {
237  cellZoneVolume += cellVolumes[cz[czCelli]];
238  cellZoneCentroid +=
239  cellVolumes[cz[czCelli]]*cellCentres[cz[czCelli]];
240  }
241  reduce(cellZoneVolume, sumOp<scalar>());
242  reduce(cellZoneCentroid, sumOp<point>());
243  cellZoneCentroid /= cellZoneVolume;
244 
245  // Store the indices of the points in this zone
246  forAll(cz, czCelli)
247  {
248  const label celli = cz[czCelli];
249  forAll(cells[celli], cellFacei)
250  {
251  const label facei = cells[celli][cellFacei];
252  forAll(faces[facei], facePointi)
253  {
254  const label pointi = faces[facei][facePointi];
255  if (pointZonePoints[pointi] != -1) continue;
256  pointZonePoints[pointi] = zonePointPoints.size();
257  zonePointPoints.append(pointi);
258  }
259  }
260  }
261  }
262  }
263 
264  Info<< (geometry_ ? ":" : "") << nl;
265 
266  // Continue if we're not printing geometry
267  if (!geometry_) continue;
268 
269  // Print integral geometry
270  if (printPointZone && pointZoneSize)
271  {
272  Info<< " points average = "
273  << pointZoneAverage << nl;
274  }
275  if (printFaceZone && faceZoneMagArea > 0)
276  {
277  Info<< " faces area/centroid = "
278  << faceZoneMagArea << '/' << faceZoneCentroid << nl;
279  }
280  if (printCellZone && cellZoneVolume > 0)
281  {
282  Info<< " cells volume/centroid = "
283  << cellZoneVolume << '/' << cellZoneCentroid << nl;
284  }
285 
286  // Don't print bounds if there aren't any points
287  if (returnReduce(zonePointPoints.size(), sumOp<label>()) == 0) continue;
288 
289  // Print bounding geometry
290  const boundBox bb(points, zonePointPoints, true);
291  Info<< " bound box min/max = "
292  << bb.min() << '/' << bb.max() << nl;
293  const boundSphere bs =
295  Info<< " bound sphere centre/radius = "
296  << bs.c() << '/' << bs.r() << nl;
297  }
298 
299  Info<< endl;
300 
301  return zoneSet();
302 }
303 
304 
305 // ************************************************************************* //
bool found
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
Macros for easy insertion into run-time selection tables.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:236
A HashTable with keys but without contents.
Definition: HashSet.H:62
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:109
List< Key > toc() const
Return the table of contents.
Definition: HashTable.C:227
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
A List with indirect addressing.
Definition: UIndirectList.H:61
static const Form zero
Definition: VectorSpace.H:118
A bounding box defined in terms of the points at its extremities.
Definition: boundBox.H:60
const point & min() const
Minimum point defining the bounding box.
Definition: boundBoxI.H:88
const point & max() const
Maximum point defining the bounding box.
Definition: boundBoxI.H:94
The smallest sphere enclosing a given set of points.
Definition: boundSphere.H:63
scalar r() const
Return the radius.
Definition: boundSphereI.H:156
const point & c() const
Return the centre.
Definition: boundSphereI.H:144
static boundSphere global(const PointList &ps, const bool strict=false)
Return the sphere bounding the given set of points using Welzl's.
Named list of cell indices representing a sub-set of the mesh.
Definition: cellZone.H:61
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Named list of face indices representing a sub-set of the mesh faces.
Definition: faceZone.H:66
Named list of point indices representing a sub-set of the mesh faces.
Definition: pointZone.H:60
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:78
A class for handling words, derived from string.
Definition: word.H:63
Abstract base class for all zoneGenerators, providing runtime selection.
Definition: zoneGenerator.H:57
A zoneGenerator which looks-up and returns a zoneSet containing point, and/or cell and/or faces zones...
Definition: lookup.H:139
A zoneGenerator which converts the point, cell and face zones from a list of zoneGenerators into a po...
A zoneGenerator which prints pointZones and/or cellZone and/or faceZones from the mesh.
Definition: print.H:103
virtual zoneSet generate() const
Generate and return the zoneSet.
Definition: print.C:82
virtual ~print()
Destructor.
Definition: print.C:76
print(const word &name, const polyMesh &mesh, const dictionary &dict)
Construct from dictionary.
Definition: print.C:46
Zone container returned by zoneGenerator::generate.
Definition: zoneSet.H:94
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
const pointField & points
const cellShapeList & cells
defineTypeNameAndDebug(cylinderHeadPoints, 0)
addToRunTimeSelectionTable(zoneGenerator, cylinderHeadPoints, dictionary)
Namespace for OpenFOAM.
zoneTypesAll
Enumeration defining the zone types with an option for all the types.
Definition: zoneSet.H:77
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:288
messageStream Info
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
static const char nl
Definition: Ostream.H:297
const NamedEnum< zoneTypesAll, 4 > zoneTypesAllNames
Named enumeration defining the zone type names.
Definition: zoneSet.C:43
dictionary dict