initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / OpenFOAM / meshes / primitiveMesh / PrimitivePatch / PrimitivePatchCheck.C
blob172bc9db7e217c6ffa4bd81d7d29ef62604bcd4b
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
45 void
46 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
47 visitPointRegion
49     const label pointI,
50     const labelList& pFaces,
51     const label startFaceI,
52     const label startEdgeI,
53     boolList& pFacesHad
54 ) const
56     label index = findIndex(pFaces, startFaceI);
58     if (!pFacesHad[index])
59     {
60         // Mark face as been visited.
61         pFacesHad[index] = true;
63         // Step to next edge on face which is still using pointI
64         const labelList& fEdges = faceEdges()[startFaceI];
66         label nextEdgeI = -1;
68         forAll(fEdges, i)
69         {
70             label edgeI = fEdges[i];
72             const edge& e = edges()[edgeI];
74             if (edgeI != startEdgeI && (e[0] == pointI || e[1] == pointI))
75             {
76                 nextEdgeI = edgeI;
78                 break;
79             }
80         }
82         if (nextEdgeI == -1)
83         {
84             FatalErrorIn
85             (
86                 "PrimitivePatch<Face, FaceList, PointField, PointType>::"
87                 "visitPointRegion"
88             )   << "Problem: cannot find edge out of " << fEdges
89                 << "on face " << startFaceI << " that uses point " << pointI
90                 << " and is not edge " << startEdgeI << abort(FatalError);
91         }
93         // Walk to next face(s) across edge.
94         const labelList& eFaces = edgeFaces()[nextEdgeI];
96         forAll(eFaces, i)
97         {
98             if (eFaces[i] != startFaceI)
99             {
100                 visitPointRegion
101                 (
102                     pointI,
103                     pFaces,
104                     eFaces[i],
105                     nextEdgeI,
106                     pFacesHad
107                 );
108             }
109         }
110     }
114 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
116 template
118     class Face,
119     template<class> class FaceList,
120     class PointField,
121     class PointType
124 typename Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::surfaceTopo
125 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
126 surfaceType() const
128     if (debug)
129     {
130         Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
131                "surfaceType() : "
132                "calculating patch topology"
133             << endl;
134     }
136     const labelListList& edgeFcs = edgeFaces();
138     surfaceTopo pType = MANIFOLD;
140     forAll(edgeFcs, edgeI)
141     {
142         label nNbrs = edgeFcs[edgeI].size();
144         if (nNbrs < 1 || nNbrs > 2)
145         {
146             pType = ILLEGAL;
148             // Can exit now. Surface is illegal.
149             return pType;
150         }
151         else if (nNbrs == 1)
152         {
153             // Surface might be open or illegal so keep looping.
154             pType = OPEN;
155         }
156     }
158     if (debug)
159     {
160         Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
161                "surfaceType() : "
162                "finished calculating patch topology"
163             << endl;
164     }
166     return pType;
170 template
172     class Face,
173     template<class> class FaceList,
174     class PointField,
175     class PointType
178 bool
179 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
180 checkTopology
182     const bool report,
183     labelHashSet* setPtr
184 ) const
186     if (debug)
187     {
188         Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
189                "checkTopology(const bool, labelHashSet&) : "
190                "checking patch topology"
191             << endl;
192     }
194     // Check edgeFaces
196     const labelListList& edgeFcs = edgeFaces();
198     surfaceTopo surfaceType = MANIFOLD;
200     forAll(edgeFcs, edgeI)
201     {
202         label nNbrs = edgeFcs[edgeI].size();
204         if (nNbrs < 1 || nNbrs > 2)
205         {
206             surfaceType = ILLEGAL;
208             if (report)
209             {
210                 Info<< "Edge " << edgeI << " with vertices:" << edges()[edgeI]
211                     << " has " << nNbrs << " face neighbours"
212                     << endl;
213             }
215             if (setPtr)
216             {
217                 const edge& e = edges()[edgeI];
219                 setPtr->insert(meshPoints()[e.start()]);
220                 setPtr->insert(meshPoints()[e.end()]);
221             }
222         }
223         else if (nNbrs == 1)
224         {
225             surfaceType = OPEN;
226         }
227     }
229     if (debug)
230     {
231         Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
232                "checkTopology(const bool, labelHashSet&) : "
233                "finished checking patch topology"
234             << endl;
235     }
237     return surfaceType == ILLEGAL;
241 template
243     class Face,
244     template<class> class FaceList,
245     class PointField,
246     class PointType
249 bool
250 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
251 checkPointManifold
253     const bool report,
254     labelHashSet* setPtr
255 ) const
257     const labelListList& pf = pointFaces();
258     const labelListList& pe = pointEdges();
259     const labelListList& ef = edgeFaces();
260     const labelList& mp = meshPoints();
262     bool foundError = false;
264     forAll(pf, pointI)
265     {
266         const labelList& pFaces = pf[pointI];
268         // Visited faces (as indices into pFaces)
269         boolList pFacesHad(pFaces.size(), false);
271         // Starting edge
272         const labelList& pEdges = pe[pointI];
273         label startEdgeI = pEdges[0];
275         const labelList& eFaces = ef[startEdgeI];
277         forAll(eFaces, i)
278         {
279             // Visit all faces using pointI, starting from eFaces[i] and
280             // startEdgeI. Mark off all faces visited in pFacesHad.
281             this->visitPointRegion
282             (
283                 pointI,
284                 pFaces,
285                 eFaces[i],  // starting face for walk
286                 startEdgeI, // starting edge for walk
287                 pFacesHad
288             );
289         }
291         // After this all faces using pointI should have been visited and
292         // marked off in pFacesHad.
294         label unset = findIndex(pFacesHad, false);
296         if (unset != -1)
297         {
298             foundError = true;
300             label meshPointI = mp[pointI];
302             if (setPtr)
303             {
304                 setPtr->insert(meshPointI);
305             }
307             if (report)
308             {
309                 Info<< "Point " << meshPointI
310                     << " uses faces which are not connected through an edge"
311                     << nl
312                     << "This means that the surface formed by this patched"
313                     << " is multiply connected at this point" << nl
314                     << "Connected (patch) faces:" << nl;
316                 forAll(pFacesHad, i)
317                 {
318                     if (pFacesHad[i])
319                     {
320                         Info<< "    " << pFaces[i] << endl;
321                     }
322                 }
324                 Info<< nl << "Unconnected (patch) faces:" << nl;
325                 forAll(pFacesHad, i)
326                 {
327                     if (!pFacesHad[i])
328                     {
329                         Info<< "    " << pFaces[i] << endl;
330                     }
331                 }
332             }
333         }
334     }
336     return foundError;
340 // ************************************************************************* //