Added faceCentres member function.
[OpenFOAM-1.6.x.git] / src / OpenFOAM / meshes / primitiveMesh / PrimitivePatch / PrimitivePatchCheck.C
blob11fe2235ba50843272587b2a40d45de3380f84d5
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     option) any later version.
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.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 Description
26     Checks topology of the patch.
28 \*---------------------------------------------------------------------------*/
30 #include "PrimitivePatch.H"
31 #include "Map.H"
32 #include "ListOps.H"
35 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
37 template
39     class Face,
40     template<class> class FaceList,
41     class PointField,
42     class PointType
44 void
45 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
46 visitPointRegion
48     const label pointI,
49     const labelList& pFaces,
50     const label startFaceI,
51     const label startEdgeI,
52     boolList& pFacesHad
53 ) const
55     label index = findIndex(pFaces, startFaceI);
57     if (!pFacesHad[index])
58     {
59         // Mark face as been visited.
60         pFacesHad[index] = true;
62         // Step to next edge on face which is still using pointI
63         const labelList& fEdges = faceEdges()[startFaceI];
65         label nextEdgeI = -1;
67         forAll(fEdges, i)
68         {
69             label edgeI = fEdges[i];
71             const edge& e = edges()[edgeI];
73             if (edgeI != startEdgeI && (e[0] == pointI || e[1] == pointI))
74             {
75                 nextEdgeI = edgeI;
77                 break;
78             }
79         }
81         if (nextEdgeI == -1)
82         {
83             FatalErrorIn
84             (
85                 "PrimitivePatch<Face, FaceList, PointField, PointType>::"
86                 "visitPointRegion"
87             )   << "Problem: cannot find edge out of " << fEdges
88                 << "on face " << startFaceI << " that uses point " << pointI
89                 << " and is not edge " << startEdgeI << abort(FatalError);
90         }
92         // Walk to next face(s) across edge.
93         const labelList& eFaces = edgeFaces()[nextEdgeI];
95         forAll(eFaces, i)
96         {
97             if (eFaces[i] != startFaceI)
98             {
99                 visitPointRegion
100                 (
101                     pointI,
102                     pFaces,
103                     eFaces[i],
104                     nextEdgeI,
105                     pFacesHad
106                 );
107             }
108         }
109     }
113 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
115 template
117     class Face,
118     template<class> class FaceList,
119     class PointField,
120     class PointType
122 typename Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::surfaceTopo
123 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
124 surfaceType() const
126     if (debug)
127     {
128         Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
129                "surfaceType() : "
130                "calculating patch topology"
131             << endl;
132     }
134     const labelListList& edgeFcs = edgeFaces();
136     surfaceTopo pType = MANIFOLD;
138     forAll(edgeFcs, edgeI)
139     {
140         label nNbrs = edgeFcs[edgeI].size();
142         if (nNbrs < 1 || nNbrs > 2)
143         {
144             pType = ILLEGAL;
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     }
156     if (debug)
157     {
158         Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
159                "surfaceType() : "
160                "finished calculating patch topology"
161             << endl;
162     }
164     return pType;
168 template
170     class Face,
171     template<class> class FaceList,
172     class PointField,
173     class PointType
175 bool
176 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
177 checkTopology
179     const bool report,
180     labelHashSet* setPtr
181 ) const
183     if (debug)
184     {
185         Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
186                "checkTopology(const bool, labelHashSet&) : "
187                "checking patch topology"
188             << endl;
189     }
191     // Check edgeFaces
193     const labelListList& edgeFcs = edgeFaces();
195     surfaceTopo surfaceType = MANIFOLD;
197     forAll(edgeFcs, edgeI)
198     {
199         label nNbrs = edgeFcs[edgeI].size();
201         if (nNbrs < 1 || nNbrs > 2)
202         {
203             surfaceType = ILLEGAL;
205             if (report)
206             {
207                 Info<< "Edge " << edgeI << " with vertices:" << edges()[edgeI]
208                     << " has " << nNbrs << " face neighbours"
209                     << endl;
210             }
212             if (setPtr)
213             {
214                 const edge& e = edges()[edgeI];
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     }
226     if (debug)
227     {
228         Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
229                "checkTopology(const bool, labelHashSet&) : "
230                "finished checking patch topology"
231             << endl;
232     }
234     return surfaceType == ILLEGAL;
238 template
240     class Face,
241     template<class> class FaceList,
242     class PointField,
243     class PointType
245 bool
246 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
247 checkPointManifold
249     const bool report,
250     labelHashSet* setPtr
251 ) const
253     const labelListList& pf = pointFaces();
254     const labelListList& pe = pointEdges();
255     const labelListList& ef = edgeFaces();
256     const labelList& mp = meshPoints();
258     bool foundError = false;
260     forAll(pf, pointI)
261     {
262         const labelList& pFaces = pf[pointI];
264         // Visited faces (as indices into pFaces)
265         boolList pFacesHad(pFaces.size(), false);
267         // Starting edge
268         const labelList& pEdges = pe[pointI];
269         label startEdgeI = pEdges[0];
271         const labelList& eFaces = ef[startEdgeI];
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         }
287         // After this all faces using pointI should have been visited and
288         // marked off in pFacesHad.
290         label unset = findIndex(pFacesHad, false);
292         if (unset != -1)
293         {
294             foundError = true;
296             label meshPointI = mp[pointI];
298             if (setPtr)
299             {
300                 setPtr->insert(meshPointI);
301             }
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;
312                 forAll(pFacesHad, i)
313                 {
314                     if (pFacesHad[i])
315                     {
316                         Info<< "    " << pFaces[i] << endl;
317                     }
318                 }
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     }
332     return foundError;
336 // ************************************************************************* //