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-------------------------------------------------------------------------------
10License
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
35namespace 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
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
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
287{
288 return checkFireEdges(mesh.faces(), mesh.pointFaces(), mesh.points());
289}
290
291
292// ************************************************************************* //
Various functions to operate on Lists.
Checks the mesh for edge connectivity as expected by the AVL/FIRE on-the-fly calculations....
bool set(const Key &key)
Same as insert (no value to overwrite)
Definition: HashSet.H:197
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:137
label size() const noexcept
The number of elements in table.
Definition: HashTableI.H:52
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:66
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Foam::edge edge(const label edgei) const
Return i-th face edge (forward walk order).
Definition: faceI.H:125
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:81
dynamicFvMesh & mesh
const pointField & points
label nPoints
Namespace for OpenFOAM.
void invertManyToMany(const label len, const UList< InputIntListType > &input, List< OutputIntListType > &output)
Invert many-to-many.
label checkFireEdges(const faceList &faces, const labelListList &pointFaces, const UList< point > &points=UList< point >::null())
check edge connectivity
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
bool notNull(const T *ptr)
True if ptr is not a pointer (of type T) to the nullObject.
Definition: nullObject.H:207
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
labelList f(nPoints)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333