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

cellToCellStencil.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 "cellToCellStencil.H"
00027 #include <OpenFOAM/syncTools.H>
00028 #include <OpenFOAM/SortableList.H>
00029 #include <OpenFOAM/emptyPolyPatch.H>
00030 
00031 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00032 
00033 // Merge two list and guarantee global0,global1 are first.
00034 void Foam::cellToCellStencil::merge
00035 (
00036     const label global0,
00037     const label global1,
00038     const labelList& listA,
00039     labelList& listB
00040 )
00041 {
00042     sort(listB);
00043 
00044     // See if global0, global1 already present in listB
00045     label nGlobalInsert = 0;
00046 
00047     if (global0 != -1)
00048     {
00049         label index0 = findSortedIndex(listB, global0);
00050         if (index0 == -1)
00051         {
00052             nGlobalInsert++;
00053         }
00054     }
00055 
00056     if (global1 != -1)
00057     {
00058         label index1 = findSortedIndex(listB, global1);
00059         if (index1 == -1)
00060         {
00061             nGlobalInsert++;
00062         }
00063     }
00064 
00065 
00066     // For all in listA see if they are present
00067     label nInsert = 0;
00068 
00069     forAll(listA, i)
00070     {
00071         label elem = listA[i];
00072 
00073         if (elem != global0 && elem != global1)
00074         {
00075             if (findSortedIndex(listB, elem) == -1)
00076             {
00077                 nInsert++;
00078             }
00079         }
00080     }
00081 
00082     // Extend B with nInsert and whether global0,global1 need to be inserted.
00083     labelList result(listB.size() + nGlobalInsert + nInsert);
00084 
00085     label resultI = 0;
00086 
00087     // Insert global0,1 first
00088     if (global0 != -1)
00089     {
00090         result[resultI++] = global0;
00091     }
00092     if (global1 != -1)
00093     {
00094         result[resultI++] = global1;
00095     }
00096 
00097 
00098     // Insert listB
00099     forAll(listB, i)
00100     {
00101         label elem = listB[i];
00102 
00103         if (elem != global0 && elem != global1)
00104         {
00105             result[resultI++] = elem;
00106         }
00107     }
00108 
00109 
00110     // Insert listA
00111     forAll(listA, i)
00112     {
00113         label elem = listA[i];
00114 
00115         if (elem != global0 && elem != global1)
00116         {
00117             if (findSortedIndex(listB, elem) == -1)
00118             {
00119                 result[resultI++] = elem;
00120             }
00121         }
00122     }
00123 
00124     if (resultI != result.size())
00125     {
00126         FatalErrorIn("cellToCellStencil::merge(..)")
00127             << "problem" << abort(FatalError);
00128     }
00129 
00130     listB.transfer(result);
00131 }
00132 
00133 
00134 // Merge two list and guarantee globalI is first.
00135 void Foam::cellToCellStencil::merge
00136 (
00137     const label globalI,
00138     const labelList& pGlobals,
00139     labelList& cCells
00140 )
00141 {
00142     labelHashSet set;
00143     forAll(cCells, i)
00144     {
00145         if (cCells[i] != globalI)
00146         {
00147             set.insert(cCells[i]);
00148         }
00149     }
00150 
00151     forAll(pGlobals, i)
00152     {
00153         if (pGlobals[i] != globalI)
00154         {
00155             set.insert(pGlobals[i]);
00156         }
00157     }
00158 
00159     cCells.setSize(set.size()+1);
00160     label n = 0;
00161     cCells[n++] = globalI;
00162 
00163     forAllConstIter(labelHashSet, set, iter)
00164     {
00165         cCells[n++] = iter.key();
00166     }
00167 }
00168 
00169 
00170 void Foam::cellToCellStencil::validBoundaryFaces(boolList& isValidBFace) const
00171 {
00172     const polyBoundaryMesh& patches = mesh().boundaryMesh();
00173 
00174     isValidBFace.setSize(mesh().nFaces()-mesh().nInternalFaces(), true);
00175 
00176     forAll(patches, patchI)
00177     {
00178         const polyPatch& pp = patches[patchI];
00179 
00180         if (pp.coupled() || isA<emptyPolyPatch>(pp))
00181         {
00182             label bFaceI = pp.start()-mesh().nInternalFaces();
00183             forAll(pp, i)
00184             {
00185                 isValidBFace[bFaceI++] = false;
00186             }
00187         }
00188     }
00189 }
00190 
00191 
00192 Foam::autoPtr<Foam::indirectPrimitivePatch>
00193 Foam::cellToCellStencil::allCoupledFacesPatch() const
00194 {
00195     const polyBoundaryMesh& patches = mesh().boundaryMesh();
00196 
00197     label nCoupled = 0;
00198 
00199     forAll(patches, patchI)
00200     {
00201         const polyPatch& pp = patches[patchI];
00202 
00203         if (pp.coupled())
00204         {
00205             nCoupled += pp.size();
00206         }
00207     }
00208     labelList coupledFaces(nCoupled);
00209     nCoupled = 0;
00210 
00211     forAll(patches, patchI)
00212     {
00213         const polyPatch& pp = patches[patchI];
00214 
00215         if (pp.coupled())
00216         {
00217             label faceI = pp.start();
00218 
00219             forAll(pp, i)
00220             {
00221                 coupledFaces[nCoupled++] = faceI++;
00222             }
00223         }
00224     }
00225 
00226     return autoPtr<indirectPrimitivePatch>
00227     (
00228         new indirectPrimitivePatch
00229         (
00230             IndirectList<face>
00231             (
00232                 mesh().faces(),
00233                 coupledFaces
00234             ),
00235             mesh().points()
00236         )
00237     );
00238 }
00239 
00240 
00241 void Foam::cellToCellStencil::unionEqOp::operator()
00242 (
00243     labelList& x,
00244     const labelList& y
00245 ) const
00246 {
00247     if (y.size())
00248     {
00249         if (x.empty())
00250         {
00251             x = y;
00252         }
00253         else
00254         {
00255             labelHashSet set(x);
00256             forAll(y, i)
00257             {
00258                 set.insert(y[i]);
00259             }
00260             x = set.toc();
00261         }
00262     }
00263 }
00264 
00265 
00266 void Foam::cellToCellStencil::insertFaceCells
00267 (
00268     const label exclude0,
00269     const label exclude1,
00270     const boolList& isValidBFace,
00271     const labelList& faceLabels,
00272     labelHashSet& globals
00273 ) const
00274 {
00275     const labelList& own = mesh().faceOwner();
00276     const labelList& nei = mesh().faceNeighbour();
00277 
00278     forAll(faceLabels, i)
00279     {
00280         label faceI = faceLabels[i];
00281 
00282         label globalOwn = globalNumbering().toGlobal(own[faceI]);
00283         if (globalOwn != exclude0 && globalOwn != exclude1)
00284         {
00285             globals.insert(globalOwn);
00286         }
00287 
00288         if (mesh().isInternalFace(faceI))
00289         {
00290             label globalNei = globalNumbering().toGlobal(nei[faceI]);
00291             if (globalNei != exclude0 && globalNei != exclude1)
00292             {
00293                 globals.insert(globalNei);
00294             }
00295         }
00296         else
00297         {
00298             label bFaceI = faceI-mesh().nInternalFaces();
00299 
00300             if (isValidBFace[bFaceI])
00301             {
00302                 label globalI = globalNumbering().toGlobal
00303                 (
00304                     mesh().nCells()
00305                   + bFaceI
00306                 );
00307 
00308                 if (globalI != exclude0 && globalI != exclude1)
00309                 {
00310                     globals.insert(globalI);
00311                 }
00312             }
00313         }
00314     }
00315 }
00316 
00317 
00318 Foam::labelList Foam::cellToCellStencil::calcFaceCells
00319 (
00320     const boolList& isValidBFace,
00321     const labelList& faceLabels,
00322     labelHashSet& globals
00323 ) const
00324 {
00325     globals.clear();
00326 
00327     insertFaceCells
00328     (
00329         -1,
00330         -1,
00331         isValidBFace,
00332         faceLabels,
00333         globals
00334     );
00335 
00336     return globals.toc();
00337 }
00338 
00339 
00340 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00341 
00342 Foam::cellToCellStencil::cellToCellStencil(const polyMesh& mesh)
00343 :
00344     mesh_(mesh),
00345     globalNumbering_(mesh_.nCells()+mesh_.nFaces()-mesh_.nInternalFaces())
00346 {}
00347 
00348 
00349 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines