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

walkPatch.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 
00026 \*---------------------------------------------------------------------------*/
00027 
00028 #include "walkPatch.H"
00029 #include <OpenFOAM/ListOps.H>
00030 
00031 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00032 
00033 defineTypeNameAndDebug(Foam::walkPatch, 0);
00034 
00035 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00036 
00037 // Get other face using v0, v1 (in localFaces numbering). Or -1.
00038 Foam::label Foam::walkPatch::getNeighbour
00039 (
00040     const label faceI,
00041     const label fp,
00042     const label v0,
00043     const label v1
00044 ) const
00045 {
00046     const labelList& fEdges = pp_.faceEdges()[faceI];
00047 
00048     const edgeList& edges = pp_.edges();
00049 
00050 
00051     label nbrEdgeI = -1;
00052 
00053     // Shortcut: maybe faceEdges are sorted(?) in which case fEdges[fp] is
00054     // edge between v0 and v1.
00055     const edge& e = edges[fEdges[fp]];
00056 
00057     if ((e[0] == v0 && e[1] == v1) || (e[0] == v1 && e[1] == v0))
00058     {
00059         // Correct edge.
00060         nbrEdgeI = fEdges[fp];
00061     }
00062     else
00063     {
00064         // Loop over all faceEdges.
00065         forAll(fEdges, i)
00066         {
00067             label edgeI = fEdges[i];
00068 
00069             const edge& e = edges[edgeI];
00070 
00071             if
00072             (
00073                 (e[0] == v0 && e[1] == v1)
00074              || (e[0] == v1 && e[1] == v0)
00075             )
00076             {
00077                 // Found edge on face which uses v0, v1.
00078                 nbrEdgeI = edgeI;
00079 
00080                 break;
00081             }
00082         }
00083     }
00084 
00085 
00086     if (nbrEdgeI == -1)
00087     {
00088         FatalErrorIn("getNeighbour")
00089             << "Did not find edge on face " << faceI << " that uses vertices"
00090             << v0 << " and " << v1 << abort(FatalError);
00091     }
00092 
00093 
00094     // Get neighbouring face.
00095 
00096     const labelList& eFaces = pp_.edgeFaces()[nbrEdgeI];
00097 
00098     if (eFaces.size() == 1)
00099     {
00100         return -1;
00101     }
00102     else if (eFaces.size() == 2)
00103     {
00104         label nbrFaceI = eFaces[0];
00105 
00106         if (nbrFaceI == faceI)
00107         {
00108             nbrFaceI = eFaces[1];
00109         }
00110 
00111         return nbrFaceI;
00112     }
00113     else
00114     {
00115         FatalErrorIn("getNeighbour")
00116             << "Illegal surface on patch. Face " << faceI
00117             << " at vertices " << v0 << ',' << v1
00118             << " has fewer than 1 or more than 2 neighbours"
00119             << abort(FatalError);
00120         return -1;
00121     }
00122 }
00123 
00124 
00125 // Gets labels of changed faces and enterVertices on faces.
00126 // Returns labels of faces changed and enterVertices on them.
00127 void Foam::walkPatch::faceToFace
00128 (
00129     const labelList& changedFaces,
00130     const labelList& enterVerts,
00131 
00132     labelList& nbrFaces,
00133     labelList& nbrEnterVerts
00134 )
00135 {
00136     nbrFaces.setSize(pp_.size());
00137     nbrEnterVerts.setSize(pp_.size());
00138     label changedI = 0;
00139 
00140     forAll(changedFaces, i)
00141     {
00142         label faceI = changedFaces[i];
00143         label enterVertI = enterVerts[i];
00144 
00145         if (!visited_[faceI])
00146         {
00147             // Do this face
00148             visited_[faceI] = true;
00149             visitOrder_.append(faceI);
00150 
00151             const face& f = pp_.localFaces()[faceI];
00152 
00153             label fp = findIndex(f, enterVertI);
00154 
00155             indexInFace_.append(fp);
00156 
00157             // Visit neighbouring faces in order, starting at fp.
00158             for (label i = 0; i < f.size(); i++)
00159             {
00160                 label fp1 = reverse_ ? f.rcIndex(fp) : f.fcIndex(fp);
00161                 label nbr = getNeighbour(faceI, fp, f[fp], f[fp1]);
00162 
00163                 if
00164                 (
00165                     nbr != -1
00166                  && !visited_[nbr]
00167                  && faceZone_[nbr] == faceZone_[faceI]
00168                 )
00169                 {
00170                     nbrFaces[changedI] = nbr;
00171                     nbrEnterVerts[changedI] = f[fp];
00172                     changedI++;
00173                 }
00174 
00175                 fp = fp1;
00176             }
00177         }
00178     }
00179 
00180     nbrFaces.setSize(changedI);
00181     nbrEnterVerts.setSize(changedI);
00182 }
00183 
00184 
00185 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00186 
00187 // Construct from components
00188 Foam::walkPatch::walkPatch
00189 (
00190     const primitivePatch& pp,
00191     const labelList& faceZone,
00192     const bool reverse,
00193     const label faceI,
00194     const label enterVertI,
00195     boolList& visited
00196 )
00197 :
00198     pp_(pp),
00199     faceZone_(faceZone),
00200     reverse_(reverse),
00201     visited_(visited),
00202     visitOrder_(pp.size()),
00203     indexInFace_(pp.size())
00204 {
00205     // List of faces that have been visited in the current iteration.
00206     labelList changedFaces(1, faceI);
00207     // Corresponding list of entry vertices
00208     labelList enterVerts(1, enterVertI);
00209 
00210     while (true)
00211     {
00212         labelList nbrFaces;
00213         labelList nbrEnterVerts;
00214 
00215         faceToFace
00216         (
00217             changedFaces,
00218             enterVerts,
00219 
00220             nbrFaces,
00221             nbrEnterVerts
00222         );
00223 
00224 
00225         if (nbrFaces.empty())
00226         {
00227             break;
00228         }
00229 
00230         changedFaces = nbrFaces;
00231         enterVerts = nbrEnterVerts;
00232     }
00233 
00234     visitOrder_.shrink();
00235     indexInFace_.shrink();
00236 }
00237 
00238 
00239 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines