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

tetWedgeMatcher.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 \*---------------------------------------------------------------------------*/
00025 
00026 #include "tetWedgeMatcher.H"
00027 #include "cellMatcher.H"
00028 #include <OpenFOAM/primitiveMesh.H>
00029 #include <OpenFOAM/primitiveMesh.H>
00030 #include <OpenFOAM/cellModeller.H>
00031 
00032 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00033 
00034 const Foam::label Foam::tetWedgeMatcher::vertPerCell = 5;
00035 const Foam::label Foam::tetWedgeMatcher::facePerCell = 4;
00036 const Foam::label Foam::tetWedgeMatcher::maxVertPerFace = 4;
00037 
00038 
00039 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00040 
00041 // Construct null
00042 Foam::tetWedgeMatcher::tetWedgeMatcher()
00043 :
00044     cellMatcher
00045     (
00046         vertPerCell,
00047         facePerCell,
00048         maxVertPerFace,
00049        "tetWedge"
00050     )
00051 {}
00052 
00053 
00054 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00055 
00056 Foam::tetWedgeMatcher::~tetWedgeMatcher()
00057 {}
00058 
00059 
00060 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00061 
00062 bool Foam::tetWedgeMatcher::matchShape
00063 (
00064     const bool checkOnly,
00065     const faceList& faces,
00066     const labelList& owner,
00067     const label cellI,
00068     const labelList& myFaces
00069 )
00070 {
00071     if (!faceSizeMatch(faces, myFaces))
00072     {
00073         return false;
00074     }
00075 
00076     // Is tetWedge for sure now. No other shape has two tri, two quad
00077     if (checkOnly)
00078     {
00079         return true;
00080     }
00081 
00082     // Calculate localFaces_ and mapping pointMap_, faceMap_
00083     label numVert = calcLocalFaces(faces, myFaces);
00084 
00085     if (numVert != vertPerCell)
00086     {
00087         return false;
00088     }
00089 
00090     // Set up 'edge' to face mapping.
00091     calcEdgeAddressing(numVert);
00092 
00093     // Set up point on face to index-in-face mapping
00094     calcPointFaceIndex();
00095 
00096     // Storage for maps -vertex to mesh and -face to mesh
00097     vertLabels_.setSize(vertPerCell);
00098     faceLabels_.setSize(facePerCell);
00099 
00100     //
00101     // Try first triangular face. Rotate in all directions.
00102     // Walk path to other triangular face.
00103     //
00104 
00105     label face0I = -1;
00106     forAll(faceSize_, faceI)
00107     {
00108         if (faceSize_[faceI] == 3)
00109         {
00110             face0I = faceI;
00111             break;
00112         }
00113     }
00114 
00115     const face& face0 = localFaces_[face0I];
00116 
00117     // Try all rotations of this face
00118     for(label face0vert0 = 0; face0vert0 < faceSize_[face0I]; face0vert0++)
00119     {
00120         //
00121         // Try to follow prespecified path on faces of cell,
00122         // starting at face0vert0
00123         //
00124 
00125         vertLabels_[0] = pointMap_[face0[face0vert0]];
00126         faceLabels_[0] = faceMap_[face0I];
00127 
00128         // Walk face 0 from vertex 0 to 1
00129         label face0vert1 =
00130             nextVert
00131             (
00132                 face0vert0,
00133                 faceSize_[face0I],
00134                 !(owner[faceMap_[face0I]] == cellI)
00135             );
00136         vertLabels_[1] = pointMap_[face0[face0vert1]];
00137 
00138         // Jump edge from face0 to face1 (the other triangular face)
00139         label face1I =
00140             otherFace
00141             (
00142                 numVert,
00143                 face0[face0vert0],
00144                 face0[face0vert1],
00145                 face0I
00146             );
00147 
00148         if (faceSize_[face1I] != 3)
00149         {
00150             continue;
00151         }
00152         faceLabels_[1] = faceMap_[face1I];
00153 
00154 
00155         // Now correctly oriented tet-wedge for sure.
00156 
00157         // Walk face 0 from vertex 1 to 2
00158         label face0vert2 =
00159             nextVert
00160             (
00161                 face0vert1,
00162                 faceSize_[face0I],
00163                 !(owner[faceMap_[face0I]] == cellI)
00164             );
00165         vertLabels_[2] = pointMap_[face0[face0vert2]];
00166 
00167         // Jump edge from face0 to face3
00168         label face3I =
00169             otherFace
00170             (
00171                 numVert,
00172                 face0[face0vert1],
00173                 face0[face0vert2],
00174                 face0I
00175             );
00176         faceLabels_[3] = faceMap_[face3I];
00177 
00178         // Jump edge from face0 to face2
00179         label face2I =
00180             otherFace
00181             (
00182                 numVert,
00183                 face0[face0vert2],
00184                 face0[face0vert0],
00185                 face0I
00186             );
00187         faceLabels_[2] = faceMap_[face2I];
00188 
00189         // Get index of vertex 2 in face3
00190         label face3vert2 = pointFaceIndex_[face0[face0vert2]][face3I];
00191 
00192         // Walk face 3 from vertex 2 to 4
00193         label face3vert4 =
00194             nextVert
00195             (
00196                 face3vert2,
00197                 faceSize_[face3I],
00198                 (owner[faceMap_[face3I]] == cellI)
00199             );
00200 
00201         const face& face3 = localFaces_[face3I];
00202 
00203         vertLabels_[4] = pointMap_[face3[face3vert4]];
00204 
00205         // Walk face 3 from vertex 4 to 3
00206         label face3vert3 =
00207             nextVert
00208             (
00209                 face3vert4,
00210                 faceSize_[face3I],
00211                 (owner[faceMap_[face3I]] == cellI)
00212             );
00213         vertLabels_[3] = pointMap_[face3[face3vert3]];
00214 
00215         return true;
00216     }
00217 
00218     // Tried all triangular faces, in all rotations but no match found
00219     return false;
00220 }
00221 
00222 
00223 Foam::label Foam::tetWedgeMatcher::faceHashValue() const
00224 {
00225     return 2*3 + 2*4;
00226 }
00227 
00228 
00229 bool Foam::tetWedgeMatcher::faceSizeMatch
00230 (
00231     const faceList& faces,
00232     const labelList& myFaces
00233 ) const
00234 {
00235     if (myFaces.size() != 4)
00236     {
00237         return false;
00238     }
00239 
00240     label nTris = 0;
00241     label nQuads = 0;
00242     
00243     forAll(myFaces, myFaceI)
00244     {
00245         label size = faces[myFaces[myFaceI]].size();
00246 
00247         if (size == 3)
00248         {
00249             nTris++;
00250         }
00251         else if (size == 4)
00252         {
00253             nQuads++;
00254         }
00255         else
00256         {
00257             return false;
00258         }
00259     }
00260     if ((nTris == 2) && (nQuads == 2))
00261     {
00262         return true;
00263     }
00264     else
00265     {
00266         return false;
00267     }
00268 }
00269 
00270 
00271 bool Foam::tetWedgeMatcher::isA(const primitiveMesh& mesh, const label cellI)
00272 {
00273     return matchShape
00274     (
00275         true,
00276         mesh.faces(),
00277         mesh.faceOwner(),
00278         cellI,
00279         mesh.cells()[cellI]
00280     );
00281 }
00282 
00283 
00284 bool Foam::tetWedgeMatcher::isA(const faceList& faces)
00285 {
00286     // Do as if mesh with one cell only
00287     return matchShape
00288     (
00289         true,
00290         faces,                      // all faces in mesh
00291         labelList(faces.size(), 0), // cell 0 is owner of all faces
00292         0,                          // cell label
00293         makeIdentity(faces.size())  // faces of cell 0
00294     );
00295 }
00296 
00297 
00298 bool Foam::tetWedgeMatcher::matches
00299 (
00300     const primitiveMesh& mesh,
00301     const label cellI,
00302     cellShape& shape
00303 )
00304 {
00305     if
00306     (
00307         matchShape
00308         (
00309             false,
00310             mesh.faces(),
00311             mesh.faceOwner(),
00312             cellI,
00313             mesh.cells()[cellI]
00314         )
00315     )
00316     {
00317         shape = cellShape(model(), vertLabels());
00318 
00319         return true;
00320     }
00321     else
00322     {
00323         return false;
00324     }
00325 }
00326 
00327 
00328 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines