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

thresholdCellFaces.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 "thresholdCellFaces.H"
00027 
00028 #include <OpenFOAM/polyMesh.H>
00029 #include <OpenFOAM/DynamicList.H>
00030 
00031 #include <OpenFOAM/emptyPolyPatch.H>
00032 #include <OpenFOAM/processorPolyPatch.H>
00033 
00034 
00035 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00036 
00037 defineTypeNameAndDebug(Foam::thresholdCellFaces, 0);
00038 
00039 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00040 
00041 void Foam::thresholdCellFaces::calculate
00042 (
00043     const scalarField& field,
00044     const scalar lowerThreshold,
00045     const scalar upperThreshold,
00046     const bool triangulate
00047 )
00048 {
00049     const labelList& own = mesh_.faceOwner();
00050     const labelList& nei = mesh_.faceNeighbour();
00051 
00052     const faceList& origFaces = mesh_.faces();
00053     const pointField& origPoints = mesh_.points();
00054 
00055     const polyBoundaryMesh& bMesh = mesh_.boundaryMesh();
00056 
00057 
00058     surfZoneList surfZones(bMesh.size()+1);
00059 
00060     surfZones[0] = surfZone
00061     (
00062         "internalMesh",
00063         0,  // size
00064         0,  // start
00065         0   // index
00066     );
00067 
00068     forAll(bMesh, patchI)
00069     {
00070         surfZones[patchI+1] = surfZone
00071         (
00072             bMesh[patchI].name(),
00073             0,        // size
00074             0,        // start
00075             patchI+1  // index
00076         );
00077     }
00078 
00079 
00080     label nFaces = 0;
00081     label nPoints = 0;
00082 
00083 
00084     meshCells_.clear();
00085 
00086     DynamicList<face>  surfFaces(0.5 * mesh_.nFaces());
00087     DynamicList<label> surfCells(surfFaces.size());
00088 
00089     labelList oldToNewPoints(origPoints.size(), -1);
00090 
00091 
00092     // internal faces only
00093     for (label faceI = 0; faceI < mesh_.nInternalFaces(); ++faceI)
00094     {
00095         int side = 0;
00096 
00097         // check lowerThreshold
00098         if (field[own[faceI]] > lowerThreshold)
00099         {
00100             if (field[nei[faceI]] < lowerThreshold)
00101             {
00102                 side = +1;
00103             }
00104         }
00105         else if (field[nei[faceI]] > lowerThreshold)
00106         {
00107             side = -1;
00108         }
00109 
00110         // check upperThreshold
00111         if (field[own[faceI]] < upperThreshold)
00112         {
00113             if (field[nei[faceI]] > upperThreshold)
00114             {
00115                 side = +1;
00116             }
00117         }
00118         else if (field[nei[faceI]] < upperThreshold)
00119         {
00120             side = -1;
00121         }
00122 
00123 
00124         if (side)
00125         {
00126             const face& f = origFaces[faceI];
00127 
00128             forAll(f, fp)
00129             {
00130                 if (oldToNewPoints[f[fp]] == -1)
00131                 {
00132                     oldToNewPoints[f[fp]] = nPoints++;
00133                 }
00134             }
00135 
00136 
00137             label cellId;
00138             face  surfFace;
00139 
00140             if (side > 0)
00141             {
00142                 surfFace = f;
00143                 cellId = own[faceI];
00144             }
00145             else
00146             {
00147                 surfFace = f.reverseFace();
00148                 cellId = nei[faceI];
00149             }
00150 
00151 
00152             if (triangulate)
00153             {
00154                 label count = surfFace.triangles(origPoints, surfFaces);
00155                 while (count-- > 0)
00156                 {
00157                     surfCells.append(cellId);
00158                 }
00159             }
00160             else
00161             {
00162                 surfFaces.append(surfFace);
00163                 surfCells.append(cellId);
00164             }
00165         }
00166     }
00167 
00168     surfZones[0].size() = surfFaces.size();
00169 
00170 
00171     // nothing special for processor patches?
00172     forAll(bMesh, patchI)
00173     {
00174         const polyPatch& p = bMesh[patchI];
00175         surfZone& zone = surfZones[patchI+1];
00176 
00177         zone.start() = nFaces;
00178 
00179         if
00180         (
00181             isA<emptyPolyPatch>(p)
00182          || (Pstream::parRun() && isA<processorPolyPatch>(p))
00183         )
00184         {
00185             continue;
00186         }
00187 
00188         label faceI = p.start();
00189 
00190         // patch faces
00191         forAll(p, localFaceI)
00192         {
00193             if
00194             (
00195                 field[own[faceI]] > lowerThreshold
00196              && field[own[faceI]] < upperThreshold
00197             )
00198             {
00199                 const face& f = origFaces[faceI];
00200                 forAll(f, fp)
00201                 {
00202                     if (oldToNewPoints[f[fp]] == -1)
00203                     {
00204                         oldToNewPoints[f[fp]] = nPoints++;
00205                     }
00206                 }
00207 
00208                 label cellId = own[faceI];
00209 
00210                 if (triangulate)
00211                 {
00212                     label count = f.triangles(origPoints, surfFaces);
00213                     while (count-- > 0)
00214                     {
00215                         surfCells.append(cellId);
00216                     }
00217                 }
00218                 else
00219                 {
00220                     surfFaces.append(f);
00221                     surfCells.append(cellId);
00222                 }
00223             }
00224 
00225             ++faceI;
00226         }
00227 
00228         zone.size() = surfFaces.size() - zone.start();
00229     }
00230 
00231 
00232     surfFaces.shrink();
00233     surfCells.shrink();
00234 
00235     // renumber
00236     forAll(surfFaces, faceI)
00237     {
00238         inplaceRenumber(oldToNewPoints, surfFaces[faceI]);
00239     }
00240 
00241 
00242     pointField surfPoints(nPoints);
00243     nPoints = 0;
00244     forAll(oldToNewPoints, pointI)
00245     {
00246         if (oldToNewPoints[pointI] >= 0)
00247         {
00248             surfPoints[oldToNewPoints[pointI]] = origPoints[pointI];
00249             nPoints++;
00250         }
00251     }
00252     surfPoints.setSize(nPoints);
00253 
00254     this->storedPoints().transfer(surfPoints);
00255     this->storedFaces().transfer(surfFaces);
00256     this->storedZones().transfer(surfZones);
00257 
00258     meshCells_.transfer(surfCells);
00259 }
00260 
00261 
00262 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00263 
00264 Foam::thresholdCellFaces::thresholdCellFaces
00265 (
00266     const polyMesh& mesh,
00267     const scalarField& field,
00268     const scalar lowerThreshold,
00269     const scalar upperThreshold,
00270     const bool triangulate
00271 )
00272 :
00273     mesh_(mesh)
00274 {
00275 
00276     if (lowerThreshold > upperThreshold)
00277     {
00278         WarningIn("thresholdCellFaces::thresholdCellFaces(...)")
00279             << "lower > upper limit!  "
00280             << lowerThreshold << " > " << upperThreshold << endl;
00281     }
00282 
00283     calculate(field, lowerThreshold, upperThreshold, triangulate);
00284 }
00285 
00286 
00287 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines