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

findCellPointFaceTet.H

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     find the tetrahedron in which the position is.
00026     while searching for the tet, store the tet
00027     closest to the position.
00028     This way, if position is not inside any tet,
00029     choose the closest one.
00030 
00031 \*---------------------------------------------------------------------------*/
00032 
00033 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00034 
00035 namespace Foam
00036 {
00037 
00038 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00039 
00040 template<class Type>
00041 bool interpolationCellPointFace<Type>::findTet
00042 (
00043     const vector& position,
00044     const label nFace,
00045     vector tetPoints[],
00046     label tetLabelCandidate[],
00047     label tetPointLabels[],
00048     scalar phi[],
00049     scalar phiCandidate[],
00050     label& closestFace,
00051     scalar& minDistance
00052 ) const
00053 {
00054     bool foundTet = false;
00055 
00056     const labelList& thisFacePoints = this->pMeshFaces_[nFace];
00057     tetPoints[2] = this->pMeshFaceCentres_[nFace];
00058 
00059     label pointi = 0;
00060 
00061     while (pointi < thisFacePoints.size() && !foundTet)
00062     {
00063         label nextPointLabel = (pointi + 1) % thisFacePoints.size();
00064 
00065         tetPointLabels[0] = thisFacePoints[pointi];
00066         tetPointLabels[1] = thisFacePoints[nextPointLabel];
00067 
00068         tetPoints[0] = this->pMeshPoints_[tetPointLabels[0]];
00069         tetPoints[1] = this->pMeshPoints_[tetPointLabels[1]];
00070 
00071         bool inside = true;
00072         scalar dist = 0.0;
00073 
00074         for (label n=0; n<4; n++)
00075         {
00076             label p1 = (n + 1) % 4;
00077             label p2 = (n + 2) % 4;
00078             label p3 = (n + 3) % 4;
00079 
00080             vector referencePoint, faceNormal;
00081             referencePoint = tetPoints[p1];
00082 
00083             faceNormal =
00084                 (tetPoints[p3] - tetPoints[p1])
00085               ^ (tetPoints[p2] - tetPoints[p1]);
00086 
00087             faceNormal /= mag(faceNormal);
00088 
00089             // correct normal to point into the tet
00090             vector v0 = tetPoints[n] - referencePoint;
00091             scalar correct = v0 & faceNormal;
00092             if (correct < 0)
00093             {
00094                 faceNormal = -faceNormal;
00095             }
00096 
00097             vector v1 = position - referencePoint + SMALL*faceNormal;
00098             scalar rightSide = v1 & faceNormal;
00099 
00100             // since normal is inwards, inside the tet
00101             // is defined as all dot-products being positive
00102             inside = inside && (rightSide >= 0);
00103 
00104             scalar phiLength = (position - referencePoint) & faceNormal;
00105 
00106             scalar maxLength =
00107                 max(VSMALL, (tetPoints[n] - referencePoint) & faceNormal);
00108 
00109             phi[n] = phiLength/maxLength;
00110 
00111             dist += phi[n];
00112         }
00113 
00114         if (!inside)
00115         {
00116             if (mag(dist - 1.0) < minDistance)
00117             {
00118                 minDistance = mag(dist - 1.0);
00119                 closestFace = nFace;
00120 
00121                 for (label i=0; i<4; i++)
00122                 {
00123                     phiCandidate[i] = phi[i];
00124                 }
00125 
00126                 tetLabelCandidate[0] = tetPointLabels[0];
00127                 tetLabelCandidate[1] = tetPointLabels[1];
00128             }
00129         }
00130 
00131         foundTet = inside;
00132 
00133         pointi++;
00134     }
00135 
00136     if (foundTet)
00137     {
00138         closestFace = nFace;
00139     }
00140 
00141     return foundTet;
00142 }
00143 
00144 
00145 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00146 
00147 } // End namespace Foam
00148 
00149 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines