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

CFCFaceToCellStencil.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 "CFCFaceToCellStencil.H"
00027 #include <OpenFOAM/syncTools.H>
00028 #include <OpenFOAM/emptyPolyPatch.H>
00029 
00030 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00031 
00032 // Calculates per face the neighbour data (= faces of cell). Leaves out the
00033 // face itself since this is already in stencil.
00034 void Foam::CFCFaceToCellStencil::calcFaceBoundaryData
00035 (
00036     labelListList& neiGlobal
00037 ) const
00038 {
00039     const polyBoundaryMesh& patches = mesh().boundaryMesh();
00040     const label nBnd = mesh().nFaces()-mesh().nInternalFaces();
00041     const labelList& own = mesh().faceOwner();
00042 
00043     neiGlobal.setSize(nBnd);
00044 
00045     forAll(patches, patchI)
00046     {
00047         const polyPatch& pp = patches[patchI];
00048         label faceI = pp.start();
00049 
00050         if (pp.coupled())
00051         {
00052             // For coupled faces get the faces of the cell on the other side
00053             forAll(pp, i)
00054             {
00055                 const labelList& cFaces = mesh().cells()[own[faceI]];
00056 
00057                 labelList& globFaces = neiGlobal[faceI-mesh().nInternalFaces()];
00058                 globFaces.setSize(cFaces.size()-1);
00059                 label globI = 0;
00060 
00061                 forAll(cFaces, j)
00062                 {
00063                     if (cFaces[j] != faceI)
00064                     {
00065                         globFaces[globI++] = globalNumbering().toGlobal
00066                         (
00067                             cFaces[j]
00068                         );
00069                     }
00070                 }
00071                 faceI++;
00072             }
00073         }
00074         else if (isA<emptyPolyPatch>(pp))
00075         {
00076             // Do nothing.
00077         }
00078         else
00079         {
00080             // Do nothing since face itself already in stencil
00081         }
00082     }
00083     syncTools::swapBoundaryFaceList(mesh(), neiGlobal, false);
00084 }
00085 
00086 
00087 // Calculates per cell the neighbour data (= cell or boundary in global
00088 // numbering). First element is always cell itself!
00089 void Foam::CFCFaceToCellStencil::calcCellStencil(labelListList& globalCellFaces)
00090  const
00091 {
00092     const label nBnd = mesh().nFaces()-mesh().nInternalFaces();
00093     const labelList& own = mesh().faceOwner();
00094     const labelList& nei = mesh().faceNeighbour();
00095 
00096 
00097     // Calculate faces of coupled neighbour (in global numbering)
00098     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00099 
00100     labelListList neiGlobal(nBnd);
00101     calcFaceBoundaryData(neiGlobal);
00102 
00103 
00104 
00105     // Non-empty boundary faces
00106     boolList validBFace(mesh().nFaces()-mesh().nInternalFaces(), true);
00107 
00108     const polyBoundaryMesh& patches = mesh().boundaryMesh();
00109     forAll(patches, patchI)
00110     {
00111         const polyPatch& pp = patches[patchI];
00112 
00113         if (isA<emptyPolyPatch>(pp))
00114         {
00115             label bFaceI = pp.start()-mesh().nInternalFaces();
00116             forAll(pp, i)
00117             {
00118                 validBFace[bFaceI++] = false;
00119             }
00120         }
00121     }
00122 
00123 
00124     // Determine faces of cellCells in global numbering
00125     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00126 
00127     DynamicList<label> allGlobalFaces(100);
00128 
00129     globalCellFaces.setSize(mesh().nCells());
00130     forAll(globalCellFaces, cellI)
00131     {
00132         const cell& cFaces = mesh().cells()[cellI];
00133 
00134         allGlobalFaces.clear();
00135 
00136         // My faces first
00137         forAll(cFaces, i)
00138         {
00139             label faceI = cFaces[i];
00140 
00141             if
00142             (
00143                 mesh().isInternalFace(faceI)
00144              || validBFace[faceI-mesh().nInternalFaces()]
00145             )
00146             {
00147                 allGlobalFaces.append(globalNumbering().toGlobal(faceI));
00148             }
00149         }
00150 
00151         // faces of neighbouring cells second
00152         forAll(cFaces, i)
00153         {
00154             label faceI = cFaces[i];
00155 
00156             if (mesh().isInternalFace(faceI))
00157             {
00158                 label nbrCellI = own[faceI];
00159                 if (nbrCellI == cellI)
00160                 {
00161                     nbrCellI = nei[faceI];
00162                 }
00163                 const cell& nbrFaces = mesh().cells()[nbrCellI];
00164 
00165                 forAll(nbrFaces, j)
00166                 {
00167                     label nbrFaceI = nbrFaces[j];
00168 
00169                     if
00170                     (
00171                         mesh().isInternalFace(nbrFaceI)
00172                      || validBFace[nbrFaceI-mesh().nInternalFaces()]
00173                     )
00174                     {
00175                         label nbrGlobalI = globalNumbering().toGlobal(nbrFaceI);
00176 
00177                         // Check if already there. Note:should use hashset?
00178                         if (findIndex(allGlobalFaces, nbrGlobalI) == -1)
00179                         {
00180                             allGlobalFaces.append(nbrGlobalI);
00181                         }
00182                     }
00183                 }
00184             }
00185             else
00186             {
00187                 const labelList& nbrGlobalFaces =
00188                     neiGlobal[faceI-mesh().nInternalFaces()];
00189 
00190                 forAll(nbrGlobalFaces, j)
00191                 {
00192                     label nbrGlobalI = nbrGlobalFaces[j];
00193 
00194                     // Check if already there. Note:should use hashset?
00195                     if (findIndex(allGlobalFaces, nbrGlobalI) == -1)
00196                     {
00197                         allGlobalFaces.append(nbrGlobalI);
00198                     }
00199                 }
00200             }
00201         }
00202 
00203         globalCellFaces[cellI] = allGlobalFaces;
00204         //Pout<< "** cell:" << cellI
00205         //    << " at:" << mesh().cellCentres()[cellI]
00206         //    << endl;
00207         //const labelList& globalFaces = globalCellFaces[cellI];
00208         //forAll(globalFaces, i)
00209         //{
00210         //    label faceI = globalNumbering().toLocal(globalFaces[i]);
00211         //    Pout<< "    face:" << faceI
00212         //        << " at:" << mesh().faceCentres()[faceI]
00213         //        << endl;
00214         //}
00215     }
00216 }
00217 
00218 
00219 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00220 
00221 Foam::CFCFaceToCellStencil::CFCFaceToCellStencil(const polyMesh& mesh)
00222 :
00223     faceToCellStencil(mesh)
00224 {
00225     // Calculate per cell the (face) connected cells (in global numbering)
00226     calcCellStencil(*this);
00227 }
00228 
00229 
00230 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines