checkFireEdges.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) 2016-2021 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "checkFireEdges.H"
29 #include "polyMesh.H"
30 #include "edgeHashes.H"
31 #include "ListOps.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
38  //- Print face information for debugging purposes
39  static inline void printFace
40  (
41  const face& f,
42  label faceI,
43  const edge& currEdge
44  )
45  {
46  Info<< "face " << faceI << ':';
47  forAll(f, fpI)
48  {
49  Info<< ' ';
50  if (f[fpI] == currEdge[0] || f[fpI] == currEdge[1])
51  {
52  Info<< '_'; // highlight the node
53  }
54  Info<< f[fpI];
55  }
56  Info<< endl;
57  }
59 }
60 
61 
62 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
63 
64 Foam::label Foam::checkFireEdges
65 (
66  const faceList& faces,
67  const labelListList& pointFaces,
68  const UList<point>& points
69 )
70 {
71  label nFailedEdges = 0;
72  const bool fullCheck = true;
73 
74  Info<< "Checking edges according to AVL/FIRE on-the-fly methodology..."
75  << endl;
76 
77  labelHashSet strayPoints(100);
78  edgeHashSet failedEdges(100);
79 
80  forAll(faces, faceI)
81  {
82  const face& faceA = faces[faceI];
83 
84  forAll(faceA, edgei)
85  {
86  const edge currEdge = faceA.edge(edgei);
87 
88  // all faces attached to the first point
89  const labelList& otherFaceIds = pointFaces[currEdge[0]];
90 
91  forAll(otherFaceIds, otherI)
92  {
93  const int otherFaceI = otherFaceIds[otherI];
94  const face& faceB = faces[otherFaceI];
95 
96  // only check once
97  if (otherFaceI <= faceI && !fullCheck)
98  {
99  continue;
100  }
101 
102  // get local edges on the second face
103  int other_p0 = -1;
104  int other_p1 = -1;
105  int size_m1 = faceB.size() - 1;
106 
107  forAll(faceB, ptI)
108  {
109  if (faceB[ptI] == currEdge[0])
110  {
111  other_p0 = ptI;
112  }
113 
114  if (faceB[ptI] == currEdge[1])
115  {
116  other_p1 = ptI;
117  }
118  }
119 
120  if
121  (
122  // did not have both points - can skip
123  other_p0 == -1
124  || other_p1 == -1
125  // a normal edge
126  || abs(other_p0 - other_p1) == 1
127  // handle wrapping
128  || (other_p0 == 0 && other_p1 == size_m1)
129  || (other_p1 == 0 && other_p0 == size_m1)
130  )
131  {
132  continue;
133  }
134 
135  // find the "stray" point
136  int stray = -1;
137  if (abs(other_p0 - other_p1) == 2)
138  {
139  // a normal case
140  stray = (other_p0 + other_p1) / 2;
141  }
142  else if
143  (
144  (other_p0 == 0 && other_p1+1 == size_m1)
145  || (other_p1 == 0 && other_p0+1 == size_m1)
146  )
147  {
148  stray = size_m1;
149  }
150 
151  if (stray > 0)
152  {
153  strayPoints.set(faceB[stray]);
154  }
155 
156  failedEdges.set(currEdge);
157 
158  ++nFailedEdges;
159 
160  Info<< nl
161  << "Broken edge calculated between points "
162  << currEdge[0] << " " << currEdge[1] << endl;
163 
164  printFace(faceA, faceI, currEdge);
165  printFace(faceB, otherFaceI, currEdge);
166  }
167  }
168  }
169 
170  if (nFailedEdges)
171  {
172  Info<< endl;
173  }
174  Info<< "detected " << nFailedEdges << " edge failures";
175 
176  // reduce to the actual number of edges
177  nFailedEdges = failedEdges.size();
178 
179  // report the locations
180  if (nFailedEdges)
181  {
182  Info<< " over " << nFailedEdges << " edges" << endl;
183 
184  Info<< nl
185  << "edge points" << nl
186  << "~~~~~~~~~~~" << endl;
187 
188  for (edge thisEdge : failedEdges) // Use copy of edge
189  {
190  if (thisEdge.start() > thisEdge.end())
191  {
192  thisEdge.flip();
193  }
194 
195  if (notNull(points))
196  {
197  forAll(thisEdge, keyI)
198  {
199  const label ptI = thisEdge[keyI];
200  Info<< "point " << ptI << ": " << points[ptI] << endl;
201  }
202  }
203  else
204  {
205  forAll(thisEdge, keyI)
206  {
207  const label ptI = thisEdge[keyI];
208  Info<< "point " << ptI << endl;
209  }
210  }
211  Info<< endl;
212  }
213 
214  Info<< nl
215  << "stray points" << nl
216  << "~~~~~~~~~~~~" << endl;
217 
218  {
219  labelList keys = strayPoints.sortedToc();
220 
221  if (notNull(points))
222  {
223  forAll(keys, keyI)
224  {
225  const label ptI = keys[keyI];
226  Info<< "stray " << ptI << ": " << points[ptI] << endl;
227  }
228  }
229  else
230  {
231  forAll(keys, keyI)
232  {
233  const label ptI = keys[keyI];
234  Info<< "stray " << ptI << endl;
235  }
236  }
237 
238  }
239  Info<< endl;
240  }
241  else
242  {
243  Info<< endl;
244  }
245 
246  return nFailedEdges;
247 }
248 
249 
250 Foam::label Foam::checkFireEdges
251 (
252  const faceList& faces,
253  const UList<point>& points
254 )
255 {
256  label nPoints = -1;
257 
258  if (notNull(points))
259  {
260  nPoints = points.size();
261  }
262  else
263  {
264  // get the max point addressed
265  for (const face& f : faces)
266  {
267  forAll(f, fp)
268  {
269  if (nPoints < f[fp])
270  {
271  nPoints = f[fp];
272  }
273  }
274  }
275 
276  ++nPoints;
277  }
278 
279  labelListList pointFaces(nPoints);
280  invertManyToMany(nPoints, faces, pointFaces);
281 
282  return checkFireEdges(faces, pointFaces, points);
283 }
284 
285 
286 Foam::label Foam::checkFireEdges(const polyMesh& mesh)
287 {
288  return checkFireEdges(mesh.faces(), mesh.pointFaces(), mesh.points());
289 }
290 
291 
292 // ************************************************************************* //
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:63
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::face::edge
Foam::edge edge(const label edgei) const
Return i-th face edge (forward walk order).
Definition: faceI.H:125
polyMesh.H
Foam::HashSet< label, Hash< label > >
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::invertManyToMany
void invertManyToMany(const label len, const UList< InputIntListType > &input, List< OutputIntListType > &output)
Invert many-to-many.
Definition: ListOpsTemplates.C:720
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::notNull
bool notNull(const T *ptr)
True if ptr is not a pointer (of type T) to the nullObject.
Definition: nullObject.H:207
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::checkFireEdges
label checkFireEdges(const faceList &faces, const labelListList &pointFaces, const UList< point > &points=UList< point >::null())
check edge connectivity
Definition: checkFireEdges.C:65
edgeHashes.H
Foam::nl
constexpr char nl
Definition: Ostream.H:404
f
labelList f(nPoints)
Foam::List< face >
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
ListOps.H
Various functions to operate on Lists.
checkFireEdges.H
Checks the mesh for edge connectivity as expected by the AVL/FIRE on-the-fly calculations....
Foam::HashSet::set
bool set(const Key &key)
Same as insert (no value to overwrite)
Definition: HashSet.H:197