FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

PrimitivePatchCheck.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 Description
00025     Checks topology of the patch.
00026 
00027 \*---------------------------------------------------------------------------*/
00028 
00029 #include "PrimitivePatch_.H"
00030 #include <OpenFOAM/Map.H>
00031 #include <OpenFOAM/ListOps.H>
00032 
00033 
00034 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00035 
00036 template
00037 <
00038     class Face,
00039     template<class> class FaceList,
00040     class PointField,
00041     class PointType
00042 >
00043 void
00044 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
00045 visitPointRegion
00046 (
00047     const label pointI,
00048     const labelList& pFaces,
00049     const label startFaceI,
00050     const label startEdgeI,
00051     boolList& pFacesHad
00052 ) const
00053 {
00054     label index = findIndex(pFaces, startFaceI);
00055 
00056     if (!pFacesHad[index])
00057     {
00058         // Mark face as been visited.
00059         pFacesHad[index] = true;
00060 
00061         // Step to next edge on face which is still using pointI
00062         const labelList& fEdges = faceEdges()[startFaceI];
00063 
00064         label nextEdgeI = -1;
00065 
00066         forAll(fEdges, i)
00067         {
00068             label edgeI = fEdges[i];
00069 
00070             const edge& e = edges()[edgeI];
00071 
00072             if (edgeI != startEdgeI && (e[0] == pointI || e[1] == pointI))
00073             {
00074                 nextEdgeI = edgeI;
00075 
00076                 break;
00077             }
00078         }
00079 
00080         if (nextEdgeI == -1)
00081         {
00082             FatalErrorIn
00083             (
00084                 "PrimitivePatch<Face, FaceList, PointField, PointType>::"
00085                 "visitPointRegion"
00086             )   << "Problem: cannot find edge out of " << fEdges
00087                 << "on face " << startFaceI << " that uses point " << pointI
00088                 << " and is not edge " << startEdgeI << abort(FatalError);
00089         }
00090 
00091         // Walk to next face(s) across edge.
00092         const labelList& eFaces = edgeFaces()[nextEdgeI];
00093 
00094         forAll(eFaces, i)
00095         {
00096             if (eFaces[i] != startFaceI)
00097             {
00098                 visitPointRegion
00099                 (
00100                     pointI,
00101                     pFaces,
00102                     eFaces[i],
00103                     nextEdgeI,
00104                     pFacesHad
00105                 );
00106             }
00107         }
00108     }
00109 }
00110 
00111 
00112 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00113 
00114 template
00115 <
00116     class Face,
00117     template<class> class FaceList,
00118     class PointField,
00119     class PointType
00120 >
00121 typename Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::surfaceTopo
00122 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
00123 surfaceType() const
00124 {
00125     if (debug)
00126     {
00127         Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
00128                "surfaceType() : "
00129                "calculating patch topology"
00130             << endl;
00131     }
00132 
00133     const labelListList& edgeFcs = edgeFaces();
00134 
00135     surfaceTopo pType = MANIFOLD;
00136 
00137     forAll(edgeFcs, edgeI)
00138     {
00139         label nNbrs = edgeFcs[edgeI].size();
00140 
00141         if (nNbrs < 1 || nNbrs > 2)
00142         {
00143             pType = ILLEGAL;
00144 
00145             // Can exit now. Surface is illegal.
00146             return pType;
00147         }
00148         else if (nNbrs == 1)
00149         {
00150             // Surface might be open or illegal so keep looping.
00151             pType = OPEN;
00152         }
00153     }
00154 
00155     if (debug)
00156     {
00157         Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
00158                "surfaceType() : "
00159                "finished calculating patch topology"
00160             << endl;
00161     }
00162 
00163     return pType;
00164 }
00165 
00166 
00167 template
00168 <
00169     class Face,
00170     template<class> class FaceList,
00171     class PointField,
00172     class PointType
00173 >
00174 bool
00175 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
00176 checkTopology
00177 (
00178     const bool report,
00179     labelHashSet* setPtr
00180 ) const
00181 {
00182     if (debug)
00183     {
00184         Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
00185                "checkTopology(const bool, labelHashSet&) : "
00186                "checking patch topology"
00187             << endl;
00188     }
00189 
00190     // Check edgeFaces
00191 
00192     const labelListList& edgeFcs = edgeFaces();
00193 
00194     surfaceTopo surfaceType = MANIFOLD;
00195 
00196     forAll(edgeFcs, edgeI)
00197     {
00198         label nNbrs = edgeFcs[edgeI].size();
00199 
00200         if (nNbrs < 1 || nNbrs > 2)
00201         {
00202             surfaceType = ILLEGAL;
00203 
00204             if (report)
00205             {
00206                 Info<< "Edge " << edgeI << " with vertices:" << edges()[edgeI]
00207                     << " has " << nNbrs << " face neighbours"
00208                     << endl;
00209             }
00210 
00211             if (setPtr)
00212             {
00213                 const edge& e = edges()[edgeI];
00214 
00215                 setPtr->insert(meshPoints()[e.start()]);
00216                 setPtr->insert(meshPoints()[e.end()]);
00217             }
00218         }
00219         else if (nNbrs == 1)
00220         {
00221             surfaceType = OPEN;
00222         }
00223     }
00224 
00225     if (debug)
00226     {
00227         Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
00228                "checkTopology(const bool, labelHashSet&) : "
00229                "finished checking patch topology"
00230             << endl;
00231     }
00232 
00233     return surfaceType == ILLEGAL;
00234 }
00235 
00236 
00237 template
00238 <
00239     class Face,
00240     template<class> class FaceList,
00241     class PointField,
00242     class PointType
00243 >
00244 bool
00245 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
00246 checkPointManifold
00247 (
00248     const bool report,
00249     labelHashSet* setPtr
00250 ) const
00251 {
00252     const labelListList& pf = pointFaces();
00253     const labelListList& pe = pointEdges();
00254     const labelListList& ef = edgeFaces();
00255     const labelList& mp = meshPoints();
00256 
00257     bool foundError = false;
00258 
00259     forAll(pf, pointI)
00260     {
00261         const labelList& pFaces = pf[pointI];
00262 
00263         // Visited faces (as indices into pFaces)
00264         boolList pFacesHad(pFaces.size(), false);
00265 
00266         // Starting edge
00267         const labelList& pEdges = pe[pointI];
00268         label startEdgeI = pEdges[0];
00269 
00270         const labelList& eFaces = ef[startEdgeI];
00271 
00272         forAll(eFaces, i)
00273         {
00274             // Visit all faces using pointI, starting from eFaces[i] and
00275             // startEdgeI. Mark off all faces visited in pFacesHad.
00276             this->visitPointRegion
00277             (
00278                 pointI,
00279                 pFaces,
00280                 eFaces[i],  // starting face for walk
00281                 startEdgeI, // starting edge for walk
00282                 pFacesHad
00283             );
00284         }
00285 
00286         // After this all faces using pointI should have been visited and
00287         // marked off in pFacesHad.
00288 
00289         label unset = findIndex(pFacesHad, false);
00290 
00291         if (unset != -1)
00292         {
00293             foundError = true;
00294 
00295             label meshPointI = mp[pointI];
00296 
00297             if (setPtr)
00298             {
00299                 setPtr->insert(meshPointI);
00300             }
00301 
00302             if (report)
00303             {
00304                 Info<< "Point " << meshPointI
00305                     << " uses faces which are not connected through an edge"
00306                     << nl
00307                     << "This means that the surface formed by this patched"
00308                     << " is multiply connected at this point" << nl
00309                     << "Connected (patch) faces:" << nl;
00310 
00311                 forAll(pFacesHad, i)
00312                 {
00313                     if (pFacesHad[i])
00314                     {
00315                         Info<< "    " << pFaces[i] << endl;
00316                     }
00317                 }
00318 
00319                 Info<< nl << "Unconnected (patch) faces:" << nl;
00320                 forAll(pFacesHad, i)
00321                 {
00322                     if (!pFacesHad[i])
00323                     {
00324                         Info<< "    " << pFaces[i] << endl;
00325                     }
00326                 }
00327             }
00328         }
00329     }
00330 
00331     return foundError;
00332 }
00333 
00334 
00335 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines