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

triSurfaceAddressing.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     Contains fix for PrimitivePatch addressing (which doesn't work if surface
00026     is non-manifold). Should be moved into PrimitivePatch.
00027 
00028 \*---------------------------------------------------------------------------*/
00029 
00030 #include "triSurface.H"
00031 #include <OpenFOAM/HashTable.H>
00032 #include <OpenFOAM/SortableList.H>
00033 #include <OpenFOAM/transform.H>
00034 
00035 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00036 
00037 namespace Foam
00038 {
00039 
00040 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00041 
00042 void triSurface::calcSortedEdgeFaces() const
00043 {
00044     if (sortedEdgeFacesPtr_)
00045     {
00046         FatalErrorIn("triSurface::calcSortedEdgeFaces()")
00047             << "sortedEdgeFacesPtr_ already set"
00048             << abort(FatalError);
00049     }
00050 
00051     const labelListList& eFaces = edgeFaces();
00052 
00053     // create the lists for the various results. (resized on completion)
00054     sortedEdgeFacesPtr_ = new labelListList(eFaces.size());
00055     labelListList& sortedEdgeFaces = *sortedEdgeFacesPtr_;
00056 
00057     forAll(eFaces, edgeI)
00058     {
00059         const labelList& myFaceNbs = eFaces[edgeI];
00060 
00061         if (myFaceNbs.size() > 2)
00062         {
00063             // Get point on edge and normalized direction of edge (= e2 base
00064             // of our coordinate system)
00065             const edge& e = edges()[edgeI];
00066 
00067             const point& edgePt = localPoints()[e.start()];
00068 
00069             vector e2 = e.vec(localPoints());
00070             e2 /= mag(e2) + VSMALL;
00071 
00072 
00073             // Get opposite vertex for 0th face
00074             const labelledTri& f = localFaces()[myFaceNbs[0]];
00075             label fp0 = findIndex(f, e[0]);
00076             label fp1 = f.fcIndex(fp0);
00077             label vertI = (f[fp1] != e[1] ? f[fp1] : f.fcIndex(fp1));
00078 
00079             // Get vector normal both to e2 and to edge from opposite vertex
00080             // to edge (will be x-axis of our coordinate system)
00081             vector e0 = e2 ^ (localPoints()[vertI] - edgePt);
00082             e0 /= mag(e0) + VSMALL;
00083 
00084             // Get y-axis of coordinate system
00085             vector e1 = e2 ^ e0;
00086 
00087 
00088             SortableList<scalar> faceAngles(myFaceNbs.size());
00089 
00090             // e0 is reference so angle is 0
00091             faceAngles[0] = 0;
00092 
00093             for(label nbI = 1; nbI < myFaceNbs.size(); nbI++)
00094             {
00095                 // Get opposite vertex
00096                 const labelledTri& f = localFaces()[myFaceNbs[nbI]];
00097                 label fp0 = findIndex(f, e[0]);
00098                 label fp1 = f.fcIndex(fp0);
00099                 label vertI = (f[fp1] != e[1] ? f[fp1] : f.fcIndex(fp1));
00100 
00101                 vector vec = e2 ^ (localPoints()[vertI] - edgePt);
00102                 vec /= mag(vec) + VSMALL;
00103 
00104                 faceAngles[nbI] = pseudoAngle
00105                 (
00106                     e0,
00107                     e1,
00108                     vec
00109                 );
00110             }
00111 
00112             faceAngles.sort();
00113 
00114             sortedEdgeFaces[edgeI] = UIndirectList<label>
00115             (
00116                 myFaceNbs,
00117                 faceAngles.indices()
00118             );
00119         }
00120         else
00121         {
00122             // No need to sort. Just copy.
00123             sortedEdgeFaces[edgeI] = myFaceNbs;
00124         }
00125     }
00126 }
00127 
00128 
00129 void triSurface::calcEdgeOwner() const
00130 {
00131     if (edgeOwnerPtr_)
00132     {
00133         FatalErrorIn("triSurface::calcEdgeOwner()")
00134             << "edgeOwnerPtr_ already set"
00135             << abort(FatalError);
00136     }
00137 
00138     // create the owner list
00139     edgeOwnerPtr_ = new labelList(nEdges());
00140     labelList& edgeOwner = *edgeOwnerPtr_;
00141 
00142     forAll(edges(), edgeI)
00143     {
00144         const edge& e = edges()[edgeI];
00145 
00146         const labelList& myFaces = edgeFaces()[edgeI];
00147 
00148         if (myFaces.size() == 1)
00149         {
00150             edgeOwner[edgeI] = myFaces[0];
00151         }
00152         else
00153         {
00154             // Find the first face whose vertices are aligned with the edge.
00155             // (in case of multiply connected edge the best we can do)
00156             edgeOwner[edgeI] = -1;
00157 
00158             forAll(myFaces, i)
00159             {
00160                 const labelledTri& f = localFaces()[myFaces[i]];
00161 
00162                 if
00163                 (
00164                     ((f[0] == e.start()) && (f[1] == e.end()))
00165                  || ((f[1] == e.start()) && (f[2] == e.end()))
00166                  || ((f[2] == e.start()) && (f[0] == e.end()))
00167                 )
00168                 {
00169                     edgeOwner[edgeI] = myFaces[i];
00170 
00171                     break;
00172                 }
00173             }
00174 
00175             if (edgeOwner[edgeI] == -1)
00176             {
00177                 FatalErrorIn("triSurface::calcEdgeOwner()")
00178                     << "Edge " << edgeI << " vertices:" << e
00179                     << " is used by faces " << myFaces
00180                     << " vertices:"
00181                     << UIndirectList<labelledTri>(localFaces(), myFaces)()
00182                     << " none of which use the edge vertices in the same order"
00183                     << nl << "I give up" << abort(FatalError);
00184             }
00185         }
00186     }
00187 }
00188 
00189 
00190 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00191 
00192 } // End namespace Foam
00193 
00194 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines