Initial commit for version 2.0.x patch release
[OpenFOAM-2.0.x.git] / src / OpenFOAM / meshes / primitiveMesh / PrimitivePatch / PrimitivePatchCheck.C
blob1d52d0731610073201afaa86da8e934308544438
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2004-2010 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
13     the Free Software Foundation, either version 3 of the License, or
14     (at your 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, see <http://www.gnu.org/licenses/>.
24 Description
25     Checks topology of the patch.
27 \*---------------------------------------------------------------------------*/
29 #include "PrimitivePatch.H"
30 #include "Map.H"
31 #include "ListOps.H"
34 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
36 template
38     class Face,
39     template<class> class FaceList,
40     class PointField,
41     class PointType
43 void
44 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
45 visitPointRegion
47     const label pointI,
48     const labelList& pFaces,
49     const label startFaceI,
50     const label startEdgeI,
51     boolList& pFacesHad
52 ) const
54     label index = findIndex(pFaces, startFaceI);
56     if (!pFacesHad[index])
57     {
58         // Mark face as been visited.
59         pFacesHad[index] = true;
61         // Step to next edge on face which is still using pointI
62         const labelList& fEdges = faceEdges()[startFaceI];
64         label nextEdgeI = -1;
66         forAll(fEdges, i)
67         {
68             label edgeI = fEdges[i];
70             const edge& e = edges()[edgeI];
72             if (edgeI != startEdgeI && (e[0] == pointI || e[1] == pointI))
73             {
74                 nextEdgeI = edgeI;
76                 break;
77             }
78         }
80         if (nextEdgeI == -1)
81         {
82             FatalErrorIn
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         }
91         // Walk to next face(s) across edge.
92         const labelList& eFaces = edgeFaces()[nextEdgeI];
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     }
112 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
114 template
116     class Face,
117     template<class> class FaceList,
118     class PointField,
119     class PointType
121 typename
122 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 // ************************************************************************* //