1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "cellToFaceStencil.H"
28 #include "syncTools.H"
29 #include "SortableList.H"
30 #include "emptyPolyPatch.H"
32 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
34 // Merge two list and guarantee global0,global1 are first.
35 void Foam::cellToFaceStencil::merge
39 const labelList& listA,
45 // See if global0, global1 already present in listB
46 label nGlobalInsert = 0;
50 label index0 = findSortedIndex(listB, global0);
59 label index1 = findSortedIndex(listB, global1);
67 // For all in listA see if they are present
72 label elem = listA[i];
74 if (elem != global0 && elem != global1)
76 if (findSortedIndex(listB, elem) == -1)
83 // Extend B with nInsert and whether global0,global1 need to be inserted.
84 labelList result(listB.size() + nGlobalInsert + nInsert);
88 // Insert global0,1 first
91 result[resultI++] = global0;
95 result[resultI++] = global1;
102 label elem = listB[i];
104 if (elem != global0 && elem != global1)
106 result[resultI++] = elem;
114 label elem = listA[i];
116 if (elem != global0 && elem != global1)
118 if (findSortedIndex(listB, elem) == -1)
120 result[resultI++] = elem;
125 if (resultI != result.size())
127 FatalErrorIn("cellToFaceStencil::merge(..)")
128 << "problem" << abort(FatalError);
131 listB.transfer(result);
135 // Merge two list and guarantee globalI is first.
136 void Foam::cellToFaceStencil::merge
139 const labelList& pGlobals,
146 if (cCells[i] != globalI)
148 set.insert(cCells[i]);
154 if (pGlobals[i] != globalI)
156 set.insert(pGlobals[i]);
160 cCells.setSize(set.size()+1);
162 cCells[n++] = globalI;
164 forAllConstIter(labelHashSet, set, iter)
166 cCells[n++] = iter.key();
171 void Foam::cellToFaceStencil::validBoundaryFaces(boolList& isValidBFace) const
173 const polyBoundaryMesh& patches = mesh().boundaryMesh();
175 isValidBFace.setSize(mesh().nFaces()-mesh().nInternalFaces(), true);
177 forAll(patches, patchI)
179 const polyPatch& pp = patches[patchI];
181 if (pp.coupled() || isA<emptyPolyPatch>(pp))
183 label bFaceI = pp.start()-mesh().nInternalFaces();
186 isValidBFace[bFaceI++] = false;
193 Foam::autoPtr<Foam::indirectPrimitivePatch>
194 Foam::cellToFaceStencil::allCoupledFacesPatch() const
196 const polyBoundaryMesh& patches = mesh().boundaryMesh();
200 forAll(patches, patchI)
202 const polyPatch& pp = patches[patchI];
206 nCoupled += pp.size();
209 labelList coupledFaces(nCoupled);
212 forAll(patches, patchI)
214 const polyPatch& pp = patches[patchI];
218 label faceI = pp.start();
222 coupledFaces[nCoupled++] = faceI++;
227 return autoPtr<indirectPrimitivePatch>
229 new indirectPrimitivePatch
242 void Foam::cellToFaceStencil::unionEqOp::operator()
267 void Foam::cellToFaceStencil::insertFaceCells
269 const label exclude0,
270 const label exclude1,
271 const boolList& isValidBFace,
272 const labelList& faceLabels,
273 labelHashSet& globals
276 const labelList& own = mesh().faceOwner();
277 const labelList& nei = mesh().faceNeighbour();
279 forAll(faceLabels, i)
281 label faceI = faceLabels[i];
283 label globalOwn = globalNumbering().toGlobal(own[faceI]);
284 if (globalOwn != exclude0 && globalOwn != exclude1)
286 globals.insert(globalOwn);
289 if (mesh().isInternalFace(faceI))
291 label globalNei = globalNumbering().toGlobal(nei[faceI]);
292 if (globalNei != exclude0 && globalNei != exclude1)
294 globals.insert(globalNei);
299 label bFaceI = faceI-mesh().nInternalFaces();
301 if (isValidBFace[bFaceI])
303 label globalI = globalNumbering().toGlobal
309 if (globalI != exclude0 && globalI != exclude1)
311 globals.insert(globalI);
319 Foam::labelList Foam::cellToFaceStencil::calcFaceCells
321 const boolList& isValidBFace,
322 const labelList& faceLabels,
323 labelHashSet& globals
337 return globals.toc();
341 // Calculates per face a list of global cell/face indices.
342 void Foam::cellToFaceStencil::calcFaceStencil
344 const labelListList& globalCellCells,
345 labelListList& faceStencil
348 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
349 const label nBnd = mesh_.nFaces()-mesh_.nInternalFaces();
350 const labelList& own = mesh_.faceOwner();
351 const labelList& nei = mesh_.faceNeighbour();
354 // Determine neighbouring global cell Cells
355 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
357 labelListList neiGlobalCellCells(nBnd);
358 forAll(patches, patchI)
360 const polyPatch& pp = patches[patchI];
364 label faceI = pp.start();
368 neiGlobalCellCells[faceI-mesh_.nInternalFaces()] =
369 globalCellCells[own[faceI]];
374 syncTools::swapBoundaryFaceList(mesh_, neiGlobalCellCells, false);
378 // Construct stencil in global numbering
379 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
381 faceStencil.setSize(mesh_.nFaces());
383 labelHashSet faceStencilSet;
385 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
387 faceStencilSet.clear();
389 const labelList& ownCCells = globalCellCells[own[faceI]];
390 label globalOwn = ownCCells[0];
394 faceStencilSet.insert(ownCCells[i]);
397 const labelList& neiCCells = globalCellCells[nei[faceI]];
398 label globalNei = neiCCells[0];
402 faceStencilSet.insert(neiCCells[i]);
405 // Guarantee owner first, neighbour second.
406 faceStencil[faceI].setSize(faceStencilSet.size());
408 faceStencil[faceI][n++] = globalOwn;
409 faceStencil[faceI][n++] = globalNei;
410 forAllConstIter(labelHashSet, faceStencilSet, iter)
412 if (iter.key() != globalOwn && iter.key() != globalNei)
414 faceStencil[faceI][n++] = iter.key();
417 //Pout<< "internalface:" << faceI << " toc:" << faceStencilSet.toc()
418 // << " faceStencil:" << faceStencil[faceI] << endl;
420 forAll(patches, patchI)
422 const polyPatch& pp = patches[patchI];
423 label faceI = pp.start();
429 faceStencilSet.clear();
431 const labelList& ownCCells = globalCellCells[own[faceI]];
432 label globalOwn = ownCCells[0];
435 faceStencilSet.insert(ownCCells[i]);
438 // And the neighbours of the coupled cell
439 const labelList& neiCCells =
440 neiGlobalCellCells[faceI-mesh_.nInternalFaces()];
441 label globalNei = neiCCells[0];
444 faceStencilSet.insert(neiCCells[i]);
447 // Guarantee owner first, neighbour second.
448 faceStencil[faceI].setSize(faceStencilSet.size());
450 faceStencil[faceI][n++] = globalOwn;
451 faceStencil[faceI][n++] = globalNei;
452 forAllConstIter(labelHashSet, faceStencilSet, iter)
454 if (iter.key() != globalOwn && iter.key() != globalNei)
456 faceStencil[faceI][n++] = iter.key();
460 //Pout<< "coupledface:" << faceI
461 // << " toc:" << faceStencilSet.toc()
462 // << " faceStencil:" << faceStencil[faceI] << endl;
467 else if (!isA<emptyPolyPatch>(pp))
471 faceStencilSet.clear();
473 const labelList& ownCCells = globalCellCells[own[faceI]];
474 label globalOwn = ownCCells[0];
477 faceStencilSet.insert(ownCCells[i]);
480 // Guarantee owner first
481 faceStencil[faceI].setSize(faceStencilSet.size());
483 faceStencil[faceI][n++] = globalOwn;
484 forAllConstIter(labelHashSet, faceStencilSet, iter)
486 if (iter.key() != globalOwn)
488 faceStencil[faceI][n++] = iter.key();
492 //Pout<< "boundaryface:" << faceI
493 // << " toc:" << faceStencilSet.toc()
494 // << " faceStencil:" << faceStencil[faceI] << endl;
503 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
505 Foam::cellToFaceStencil::cellToFaceStencil(const polyMesh& mesh)
508 globalNumbering_(mesh_.nCells()+mesh_.nFaces()-mesh_.nInternalFaces())
512 // ************************************************************************* //