blockMeshCheck.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-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 "blockMesh.H"
27 
28 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
29 
30 void Foam::blockMesh::check(const polyMesh& bm, const dictionary& dict) const
31 {
32  const pointField& points = bm.points();
33  const cellList& cells = bm.cells();
34  const polyPatchList& patches = bm.boundary();
35 
36  label nBoundaryFaces = 0;
37  forAll(cells, celli)
38  {
39  nBoundaryFaces += cells[celli].nFaces();
40  }
41 
42  nBoundaryFaces -= 2*bm.nInternalFaces();
43 
44  label nDefinedBoundaryFaces = 0;
46  {
47  nDefinedBoundaryFaces += patches[patchi].size();
48  }
49 
50  if (verboseOutput)
51  {
52  Info<< nl << "Basic statistics" << nl
53  << " Number of internal faces : "
54  << bm.nInternalFaces() << nl
55  << " Number of boundary faces : "
56  << nBoundaryFaces << nl
57  << " Number of defined boundary faces : "
58  << nDefinedBoundaryFaces << nl
59  << " Number of undefined boundary faces : "
60  << nBoundaryFaces - nDefinedBoundaryFaces << nl;
61 
62  if (nBoundaryFaces - nDefinedBoundaryFaces > 0)
63  {
64  Info<< " (Warning : only leave undefined the front "
65  << "and back planes of 2D planar geometries!)" << endl;
66  }
67  }
68 
69  Info<< nl << "Checking topology" << endl;
70 
71  OStringStream oss;
72 
73  // Check for duplicate curved edge definitions
74  forAll(edges_, cei)
75  {
76  for (label cej=cei+1; cej<edges_.size(); cej++)
77  {
78  if (edges_[cei].compare(edges_[cej]) != 0)
79  {
80  oss << " Curved edge #" << cei << ' ';
81  edges_[cei].write(oss, dict);
82  oss << " is a duplicate of curved edge #" << cej << ' ';
83  edges_[cej].write(oss, dict);
84  oss << endl;
85  break;
86  }
87  }
88  }
89 
90  // Check curved-edge/block-edge correspondence
91  //
92  // Loop over the edges of each block rather than the edgeList of the
93  // topological mesh due to problems with calcEdges for blocks with
94  // repeated point labels
95  const blockList& blocks = *this;
96 
97  forAll(edges_, cei)
98  {
99  bool found = false;
100 
101  forAll(blocks, blocki)
102  {
103  edgeList edges = blocks[blocki].blockShape().edges();
104 
105  forAll(edges, ei)
106  {
107  found = edges_[cei].compare(edges[ei][0], edges[ei][1]) != 0;
108  if (found) break;
109  }
110  if (found) break;
111  }
112 
113  if (!found)
114  {
115  oss << " Curved edge #" << cei << ' ';
116  edges_[cei].write(oss, dict);
117  oss << " does not correspond to a block edge" << endl;
118  }
119  }
120 
121  const faceList& faces = bm.faces();
122 
123  // Check for duplicate curved face definitions
124  forAll(faces_, cfi)
125  {
126  for (label cfj=cfi+1; cfj<faces_.size(); cfj++)
127  {
128  if (faces_[cfi].compare(faces_[cfj]) != 0)
129  {
130  oss << " Curved face #" << cfi << ' ';
131  faces_[cfi].write(oss, dict);
132  oss << " is a duplicate of curved face #" << cfj << ' ';
133  faces_[cfj].write(oss, dict);
134  oss << endl;
135  break;
136  }
137  }
138  }
139 
140  // Check curved-face/block-face correspondence
141  forAll(faces_, cfi)
142  {
143  bool found = false;
144 
145  forAll(faces, fi)
146  {
147  found = faces_[cfi].compare(faces[fi]) != 0;
148  if (found) break;
149  }
150 
151  if (!found)
152  {
153  oss << " Curved face #" << cfi << ' ';
154  faces_[cfi].write(oss, dict);
155  oss << " does not correspond to a block face" << endl;
156  }
157  }
158 
159  // Check patch-face consistency
161  {
162  const faceList& Patch = patches[patchi];
163 
164  forAll(Patch, patchFacei)
165  {
166  const face& patchFace = Patch[patchFacei];
167  bool patchFaceOK = false;
168 
169  forAll(cells, celli)
170  {
171  const labelList& cellFaces = cells[celli];
172 
173  forAll(cellFaces, cellFacei)
174  {
175  if (patchFace == faces[cellFaces[cellFacei]])
176  {
177  patchFaceOK = true;
178 
179  if
180  (
181  (
182  patchFace.area(points)
183  & faces[cellFaces[cellFacei]].area(points)
184  ) < 0
185  )
186  {
187  oss << " Face #" << patchFacei << ' '
188  << patchFace << " of patch #" << patchi << ' '
189  << patches[patchi].name() << " points inwards"
190  << endl;
191  }
192  }
193  }
194  }
195 
196  if (!patchFaceOK)
197  {
198  oss << " Face #" << patchFacei << ' ' << patchFace
199  << " of patch #" << patchi << ' ' << patches[patchi].name()
200  << " does not match any block faces" << endl;
201  }
202  }
203  }
204 
205  if (!oss.str().empty())
206  {
208  << oss.str().c_str()
209  << exit(FatalIOError);
210  }
211 }
212 
213 
214 // ************************************************************************* //
bool found
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
const blockEdgeList & edges() const
Return the curved edges.
Definition: blockMesh.H:261
const faceListList & patches() const
Return the patch face lists.
const blockFaceList & faces() const
Return the curved faces.
Definition: blockMesh.H:267
const cellShapeList & cells() const
Return cell shapes list.
const pointField & points() const
The points for the entire mesh.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
label patchi
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
List< label > labelList
A List of labels.
Definition: labelList.H:56
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
List< cell > cellList
list of cells
Definition: cellList.H:42
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
messageStream Info
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
PtrList< block > blockList
A PtrList of blocks.
Definition: blockList.H:45
PtrList< polyPatch > polyPatchList
container classes for polyPatch
Definition: polyPatchList.H:45
IOerror FatalIOError
List< edge > edgeList
Definition: edgeList.H:38
List< face > faceList
Definition: faceListFwd.H:41
static const char nl
Definition: Ostream.H:297
dictionary dict