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

cell.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 <OpenFOAM/cell.H>
00027 #include <OpenFOAM/pyramidPointFaceRef.H>
00028 
00029 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00030 
00031 const char* const Foam::cell::typeName = "cell";
00032 
00033 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00034 
00035 Foam::labelList Foam::cell::labels(const unallocFaceList& f) const
00036 {
00037     // return the unordered list of vertex labels supporting the cell
00038 
00039     // count the maximum size of all vertices
00040     label maxVert = 0;
00041 
00042     const labelList& faces = *this;
00043 
00044     forAll (faces, faceI)
00045     {
00046         maxVert += f[faces[faceI]].size();
00047     }
00048 
00049     // set the fill-in list
00050     labelList p(maxVert);
00051 
00052     // in the first face there is no duplicates
00053     const labelList& first = f[faces[0]];
00054 
00055     forAll (first, pointI)
00056     {
00057         p[pointI] = first[pointI];
00058     }
00059 
00060     // re-use maxVert to count the real vertices
00061     maxVert = first.size();
00062 
00063     // go through the rest of the faces. For each vertex, check if the point is
00064     // already inserted (up to maxVert, which now carries the number of real
00065     // points. If not, add it at the end of the list.
00066     for (label faceI = 1; faceI < faces.size(); faceI++)
00067     {
00068         const labelList& curFace = f[faces[faceI]];
00069 
00070         forAll (curFace, pointI)
00071         {
00072             const label curPoint = curFace[pointI];
00073 
00074             bool found = false;
00075 
00076             for (register label checkI = 0; checkI < maxVert; checkI++)
00077             {
00078                 if (curPoint == p[checkI])
00079                 {
00080                     found = true;
00081                     break;
00082                 }
00083             }
00084 
00085             if (!found)
00086             {
00087                 p[maxVert] = curPoint;
00088 
00089                 maxVert++;
00090             }
00091         }
00092     }
00093 
00094     // reset the size of the list
00095     p.setSize(maxVert);
00096 
00097     return p;
00098 }
00099 
00100 
00101 Foam::pointField Foam::cell::points
00102 (
00103     const unallocFaceList& f,
00104     const pointField& meshPoints
00105 ) const
00106 {
00107     labelList pointLabels = labels(f);
00108 
00109     pointField p(pointLabels.size());
00110 
00111     forAll(p, i)
00112     {
00113         p[i] = meshPoints[pointLabels[i]];
00114     }
00115 
00116     return p;
00117 }
00118 
00119 
00120 Foam::edgeList Foam::cell::edges(const unallocFaceList& f) const
00121 {
00122     // return the lisf of cell edges
00123 
00124     const labelList& curFaces = *this;
00125 
00126     // create a list of edges
00127     label maxNoEdges = 0;
00128 
00129     forAll (curFaces, faceI)
00130     {
00131         maxNoEdges += f[curFaces[faceI]].nEdges();
00132     }
00133 
00134     edgeList allEdges(maxNoEdges);
00135     label nEdges = 0;
00136 
00137     forAll (curFaces, faceI)
00138     {
00139         const edgeList curFaceEdges = f[curFaces[faceI]].edges();
00140 
00141         forAll (curFaceEdges, faceEdgeI)
00142         {
00143             const edge& curEdge = curFaceEdges[faceEdgeI];
00144 
00145             bool edgeFound = false;
00146 
00147             for (label addedEdgeI = 0; addedEdgeI < nEdges; addedEdgeI++)
00148             {
00149                 if (allEdges[addedEdgeI] == curEdge)
00150                 {
00151                     edgeFound = true;
00152 
00153                     break;
00154                 }
00155             }
00156 
00157             if (!edgeFound)
00158             {
00159                 // Add the new edge onto the list
00160                 allEdges[nEdges] = curEdge;
00161                 nEdges++;
00162             }
00163         }
00164     }
00165 
00166     allEdges.setSize(nEdges);
00167 
00168     return allEdges;
00169 }
00170 
00171 
00172 Foam::point Foam::cell::centre
00173 (
00174     const pointField& p,
00175     const unallocFaceList& f
00176 ) const
00177 {
00178     // When one wants to access the cell centre and magnitude, the
00179     // functionality on the mesh level should be used in preference to the
00180     // functions provided here. They do not rely to the functionality
00181     // implemented here, provide additional checking and are more efficient.
00182     // The cell::centre and cell::mag functions may be removed in the future.
00183 
00184     // WARNING!
00185     // In the old version of the code, it was possible to establish whether any
00186     // of the pyramids had a negative volume, caused either by the poor
00187     // estimate of the cell centre or by the fact that the cell was defined
00188     // inside out. In the new description of the cell, this can only be
00189     // established with the reference to the owner-neighbour face-cell
00190     // relationship, which is not available on this level. Thus, all the
00191     // pyramids are believed to be positive with no checking.
00192 
00193     // first calculate the aproximate cell centre as the average of all
00194     // face centres
00195     vector cEst = vector::zero;
00196     scalar sumArea = 0;
00197 
00198     const labelList& faces = *this;
00199 
00200     forAll (faces, faceI)
00201     {
00202         scalar a = f[faces[faceI]].mag(p);
00203         cEst += f[faces[faceI]].centre(p)*a;
00204         sumArea += a;
00205     }
00206 
00207     cEst /= sumArea + VSMALL;
00208 
00209     // Calculate the centre by breaking the cell into pyramids and
00210     // volume-weighted averaging their centres
00211     vector sumVc = vector::zero;
00212 
00213     scalar sumV = 0;
00214 
00215     forAll (faces, faceI)
00216     {
00217         // calculate pyramid volume. If it is greater than zero, OK.
00218         // If not, the pyramid is inside-out. Create a face with the opposite
00219         // order and recalculate pyramid centre!
00220         scalar pyrVol = pyramidPointFaceRef(f[faces[faceI]], cEst).mag(p);
00221         vector pyrCentre = pyramidPointFaceRef(f[faces[faceI]], cEst).centre(p);
00222 
00223         // if pyramid inside-out because face points inwards invert
00224         // N.B. pyramid remains unchanged
00225         if (pyrVol < 0)
00226         {
00227             pyrVol = -pyrVol;
00228         }
00229 
00230         sumVc += pyrVol*pyrCentre;
00231         sumV += pyrVol;
00232     }
00233 
00234     return sumVc/(sumV + VSMALL);
00235 }
00236 
00237 
00238 Foam::scalar Foam::cell::mag
00239 (
00240     const pointField& p,
00241     const unallocFaceList& f
00242 ) const
00243 {
00244     // When one wants to access the cell centre and magnitude, the
00245     // functionality on the mesh level should be used in preference to the
00246     // functions provided here. They do not rely to the functionality
00247     // implemented here, provide additional checking and are more efficient.
00248     // The cell::centre and cell::mag functions may be removed in the future.
00249 
00250     // WARNING! See cell::centre
00251 
00252     // first calculate the aproximate cell centre as the average of all
00253     // face centres
00254     vector cEst = vector::zero;
00255     scalar nCellFaces = 0;
00256 
00257     const labelList& faces = *this;
00258 
00259     forAll (faces, faceI)
00260     {
00261         cEst += f[faces[faceI]].centre(p);
00262         nCellFaces += 1;
00263     }
00264 
00265     cEst /= nCellFaces;
00266 
00267     // Calculate the magnitude by summing the mags of the pyramids
00268     scalar v = 0;
00269 
00270     forAll (faces, faceI)
00271     {
00272         v += ::Foam::mag(pyramidPointFaceRef(f[faces[faceI]], cEst).mag(p));
00273     }
00274 
00275     return v;
00276 }
00277 
00278 
00279 // * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
00280 
00281 bool Foam::operator==(const cell& a, const cell& b)
00282 {
00283     // Trivial reject: faces are different size
00284     if (a.size() != b.size())
00285     {
00286         return false;
00287     }
00288 
00289     List<bool> fnd(a.size(), false);
00290 
00291     forAll (b, bI)
00292     {
00293         label curLabel = b[bI];
00294 
00295         bool found = false;
00296 
00297         forAll (a, aI)
00298         {
00299             if (a[aI] == curLabel)
00300             {
00301                 found = true;
00302                 fnd[aI] = true;
00303                 break;
00304             }
00305         }
00306 
00307         if (!found)
00308         {
00309             return false;
00310         }
00311     }
00312 
00313     // check if all faces on a were marked
00314     bool result = true;
00315 
00316     forAll (fnd, aI)
00317     {
00318         result = (result && fnd[aI]);
00319     }
00320 
00321     return result;
00322 }
00323 
00324 
00325 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines