PrimitivePatchCheck.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 | Copyright (C) 2011 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 Description
25  Checks topology of the patch.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "PrimitivePatch.H"
30 #include "Map.H"
31 #include "ListOps.H"
32 
33 
34 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
35 
36 template
37 <
38  class Face,
39  template<class> class FaceList,
40  class PointField,
41  class PointType
42 >
43 void
46 (
47  const label pointI,
48  const labelList& pFaces,
49  const label startFaceI,
50  const label startEdgeI,
51  boolList& pFacesHad
52 ) const
53 {
54  label index = findIndex(pFaces, startFaceI);
55 
56  if (!pFacesHad[index])
57  {
58  // Mark face as been visited.
59  pFacesHad[index] = true;
60 
61  // Step to next edge on face which is still using pointI
62  const labelList& fEdges = faceEdges()[startFaceI];
63 
64  label nextEdgeI = -1;
65 
66  forAll(fEdges, i)
67  {
68  label edgeI = fEdges[i];
69 
70  const edge& e = edges()[edgeI];
71 
72  if (edgeI != startEdgeI && (e[0] == pointI || e[1] == pointI))
73  {
74  nextEdgeI = edgeI;
75 
76  break;
77  }
78  }
79 
80  if (nextEdgeI == -1)
81  {
83  (
84  "PrimitivePatch<Face, FaceList, PointField, PointType>::"
85  "visitPointRegion"
86  ) << "Problem: cannot find edge out of " << fEdges
87  << "on face " << startFaceI << " that uses point " << pointI
88  << " and is not edge " << startEdgeI << abort(FatalError);
89  }
90 
91  // Walk to next face(s) across edge.
92  const labelList& eFaces = edgeFaces()[nextEdgeI];
93 
94  forAll(eFaces, i)
95  {
96  if (eFaces[i] != startFaceI)
97  {
98  visitPointRegion
99  (
100  pointI,
101  pFaces,
102  eFaces[i],
103  nextEdgeI,
104  pFacesHad
105  );
106  }
107  }
108  }
109 }
110 
111 
112 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
113 
114 template
115 <
116  class Face,
117  template<class> class FaceList,
118  class PointField,
119  class PointType
120 >
121 typename
124 surfaceType() const
125 {
126  if (debug)
127  {
128  Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
129  "surfaceType() : "
130  "calculating patch topology"
131  << endl;
132  }
133 
134  const labelListList& edgeFcs = edgeFaces();
135 
136  surfaceTopo pType = MANIFOLD;
137 
138  forAll(edgeFcs, edgeI)
139  {
140  label nNbrs = edgeFcs[edgeI].size();
141 
142  if (nNbrs < 1 || nNbrs > 2)
143  {
144  pType = ILLEGAL;
145 
146  // Can exit now. Surface is illegal.
147  return pType;
148  }
149  else if (nNbrs == 1)
150  {
151  // Surface might be open or illegal so keep looping.
152  pType = OPEN;
153  }
154  }
155 
156  if (debug)
157  {
158  Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
159  "surfaceType() : "
160  "finished calculating patch topology"
161  << endl;
162  }
163 
164  return pType;
165 }
166 
167 
168 template
169 <
170  class Face,
171  template<class> class FaceList,
172  class PointField,
173  class PointType
174 >
175 bool
178 (
179  const bool report,
180  labelHashSet* setPtr
181 ) const
182 {
183  if (debug)
184  {
185  Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
186  "checkTopology(const bool, labelHashSet&) : "
187  "checking patch topology"
188  << endl;
189  }
190 
191  // Check edgeFaces
192 
193  const labelListList& edgeFcs = edgeFaces();
194 
195  surfaceTopo surfaceType = MANIFOLD;
196 
197  forAll(edgeFcs, edgeI)
198  {
199  label nNbrs = edgeFcs[edgeI].size();
200 
201  if (nNbrs < 1 || nNbrs > 2)
202  {
203  surfaceType = ILLEGAL;
204 
205  if (report)
206  {
207  Info<< "Edge " << edgeI << " with vertices:" << edges()[edgeI]
208  << " has " << nNbrs << " face neighbours"
209  << endl;
210  }
211 
212  if (setPtr)
213  {
214  const edge& e = edges()[edgeI];
215 
216  setPtr->insert(meshPoints()[e.start()]);
217  setPtr->insert(meshPoints()[e.end()]);
218  }
219  }
220  else if (nNbrs == 1)
221  {
222  surfaceType = OPEN;
223  }
224  }
225 
226  if (debug)
227  {
228  Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
229  "checkTopology(const bool, labelHashSet&) : "
230  "finished checking patch topology"
231  << endl;
232  }
233 
234  return surfaceType == ILLEGAL;
235 }
236 
237 
238 template
239 <
240  class Face,
241  template<class> class FaceList,
242  class PointField,
243  class PointType
244 >
245 bool
248 (
249  const bool report,
250  labelHashSet* setPtr
251 ) const
252 {
253  const labelListList& pf = pointFaces();
254  const labelListList& pe = pointEdges();
255  const labelListList& ef = edgeFaces();
256  const labelList& mp = meshPoints();
257 
258  bool foundError = false;
259 
260  forAll(pf, pointI)
261  {
262  const labelList& pFaces = pf[pointI];
263 
264  // Visited faces (as indices into pFaces)
265  boolList pFacesHad(pFaces.size(), false);
266 
267  // Starting edge
268  const labelList& pEdges = pe[pointI];
269  label startEdgeI = pEdges[0];
270 
271  const labelList& eFaces = ef[startEdgeI];
272 
273  forAll(eFaces, i)
274  {
275  // Visit all faces using pointI, starting from eFaces[i] and
276  // startEdgeI. Mark off all faces visited in pFacesHad.
277  this->visitPointRegion
278  (
279  pointI,
280  pFaces,
281  eFaces[i], // starting face for walk
282  startEdgeI, // starting edge for walk
283  pFacesHad
284  );
285  }
286 
287  // After this all faces using pointI should have been visited and
288  // marked off in pFacesHad.
289 
290  label unset = findIndex(pFacesHad, false);
291 
292  if (unset != -1)
293  {
294  foundError = true;
295 
296  label meshPointI = mp[pointI];
297 
298  if (setPtr)
299  {
300  setPtr->insert(meshPointI);
301  }
302 
303  if (report)
304  {
305  Info<< "Point " << meshPointI
306  << " uses faces which are not connected through an edge"
307  << nl
308  << "This means that the surface formed by this patched"
309  << " is multiply connected at this point" << nl
310  << "Connected (patch) faces:" << nl;
311 
312  forAll(pFacesHad, i)
313  {
314  if (pFacesHad[i])
315  {
316  Info<< " " << pFaces[i] << endl;
317  }
318  }
319 
320  Info<< nl << "Unconnected (patch) faces:" << nl;
321  forAll(pFacesHad, i)
322  {
323  if (!pFacesHad[i])
324  {
325  Info<< " " << pFaces[i] << endl;
326  }
327  }
328  }
329  }
330  }
331 
332  return foundError;
333 }
334 
335 
336 // ************************************************************************* //
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
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
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
Various functions to operate on Lists.
messageStream Info
const dimensionedScalar mp
Proton mass.
bool checkTopology(const bool report=false, labelHashSet *setPtr=NULL) const
Check surface formed by patch for manifoldness (see above).
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
static const char nl
Definition: Ostream.H:260
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
#define forAll(list, i)
Definition: UList.H:421
bool checkPointManifold(const bool report=false, labelHashSet *setPtr=NULL) const
Checks primitivePatch for faces sharing point but not edge.
errorManip< error > abort(error &err)
Definition: errorManip.H:131
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
A list of faces which address into the list of points.
error FatalError
label end() const
Return end vertex label.
Definition: edgeI.H:92
List< label > labelList
A List of labels.
Definition: labelList.H:56
surfaceTopo
Enumeration defining the surface type. Used in check routines.
surfaceTopo surfaceType() const
Calculate surface type formed by patch.
label start() const
Return start vertex label.
Definition: edgeI.H:81
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:116