00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "cellToFaceStencil.H"
00027 #include <OpenFOAM/syncTools.H>
00028 #include <OpenFOAM/SortableList.H>
00029 #include <OpenFOAM/emptyPolyPatch.H>
00030
00031
00032
00033
00034 void Foam::cellToFaceStencil::merge
00035 (
00036 const label global0,
00037 const label global1,
00038 const labelList& listA,
00039 labelList& listB
00040 )
00041 {
00042 sort(listB);
00043
00044
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
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
00083 labelList result(listB.size() + nGlobalInsert + nInsert);
00084
00085 label resultI = 0;
00086
00087
00088 if (global0 != -1)
00089 {
00090 result[resultI++] = global0;
00091 }
00092 if (global1 != -1)
00093 {
00094 result[resultI++] = global1;
00095 }
00096
00097
00098
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
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("cellToFaceStencil::merge(..)")
00127 << "problem" << abort(FatalError);
00128 }
00129
00130 listB.transfer(result);
00131 }
00132
00133
00134
00135 void Foam::cellToFaceStencil::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::cellToFaceStencil::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::cellToFaceStencil::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::cellToFaceStencil::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::cellToFaceStencil::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::cellToFaceStencil::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
00341 void Foam::cellToFaceStencil::calcFaceStencil
00342 (
00343 const labelListList& globalCellCells,
00344 labelListList& faceStencil
00345 ) const
00346 {
00347 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
00348 const label nBnd = mesh_.nFaces()-mesh_.nInternalFaces();
00349 const labelList& own = mesh_.faceOwner();
00350 const labelList& nei = mesh_.faceNeighbour();
00351
00352
00353
00354
00355
00356 labelListList neiGlobalCellCells(nBnd);
00357 forAll(patches, patchI)
00358 {
00359 const polyPatch& pp = patches[patchI];
00360
00361 if (pp.coupled())
00362 {
00363 label faceI = pp.start();
00364
00365 forAll(pp, i)
00366 {
00367 neiGlobalCellCells[faceI-mesh_.nInternalFaces()] =
00368 globalCellCells[own[faceI]];
00369 faceI++;
00370 }
00371 }
00372 }
00373 syncTools::swapBoundaryFaceList(mesh_, neiGlobalCellCells, false);
00374
00375
00376
00377
00378
00379
00380 faceStencil.setSize(mesh_.nFaces());
00381
00382 labelHashSet faceStencilSet;
00383
00384 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
00385 {
00386 faceStencilSet.clear();
00387
00388 const labelList& ownCCells = globalCellCells[own[faceI]];
00389 label globalOwn = ownCCells[0];
00390
00391 forAll(ownCCells, i)
00392 {
00393 faceStencilSet.insert(ownCCells[i]);
00394 }
00395
00396 const labelList& neiCCells = globalCellCells[nei[faceI]];
00397 label globalNei = neiCCells[0];
00398
00399 forAll(neiCCells, i)
00400 {
00401 faceStencilSet.insert(neiCCells[i]);
00402 }
00403
00404
00405 faceStencil[faceI].setSize(faceStencilSet.size());
00406 label n = 0;
00407 faceStencil[faceI][n++] = globalOwn;
00408 faceStencil[faceI][n++] = globalNei;
00409 forAllConstIter(labelHashSet, faceStencilSet, iter)
00410 {
00411 if (iter.key() != globalOwn && iter.key() != globalNei)
00412 {
00413 faceStencil[faceI][n++] = iter.key();
00414 }
00415 }
00416
00417
00418 }
00419 forAll(patches, patchI)
00420 {
00421 const polyPatch& pp = patches[patchI];
00422 label faceI = pp.start();
00423
00424 if (pp.coupled())
00425 {
00426 forAll(pp, i)
00427 {
00428 faceStencilSet.clear();
00429
00430 const labelList& ownCCells = globalCellCells[own[faceI]];
00431 label globalOwn = ownCCells[0];
00432 forAll(ownCCells, i)
00433 {
00434 faceStencilSet.insert(ownCCells[i]);
00435 }
00436
00437
00438 const labelList& neiCCells =
00439 neiGlobalCellCells[faceI-mesh_.nInternalFaces()];
00440 label globalNei = neiCCells[0];
00441 forAll(neiCCells, i)
00442 {
00443 faceStencilSet.insert(neiCCells[i]);
00444 }
00445
00446
00447 faceStencil[faceI].setSize(faceStencilSet.size());
00448 label n = 0;
00449 faceStencil[faceI][n++] = globalOwn;
00450 faceStencil[faceI][n++] = globalNei;
00451 forAllConstIter(labelHashSet, faceStencilSet, iter)
00452 {
00453 if (iter.key() != globalOwn && iter.key() != globalNei)
00454 {
00455 faceStencil[faceI][n++] = iter.key();
00456 }
00457 }
00458
00459
00460
00461
00462
00463 faceI++;
00464 }
00465 }
00466 else if (!isA<emptyPolyPatch>(pp))
00467 {
00468 forAll(pp, i)
00469 {
00470 faceStencilSet.clear();
00471
00472 const labelList& ownCCells = globalCellCells[own[faceI]];
00473 label globalOwn = ownCCells[0];
00474 forAll(ownCCells, i)
00475 {
00476 faceStencilSet.insert(ownCCells[i]);
00477 }
00478
00479
00480 faceStencil[faceI].setSize(faceStencilSet.size());
00481 label n = 0;
00482 faceStencil[faceI][n++] = globalOwn;
00483 forAllConstIter(labelHashSet, faceStencilSet, iter)
00484 {
00485 if (iter.key() != globalOwn)
00486 {
00487 faceStencil[faceI][n++] = iter.key();
00488 }
00489 }
00490
00491
00492
00493
00494
00495 faceI++;
00496 }
00497 }
00498 }
00499 }
00500
00501
00502
00503
00504 Foam::cellToFaceStencil::cellToFaceStencil(const polyMesh& mesh)
00505 :
00506 mesh_(mesh),
00507 globalNumbering_(mesh_.nCells()+mesh_.nFaces()-mesh_.nInternalFaces())
00508 {}
00509
00510
00511