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 "extendedUpwindCellToFaceStencil.H"
00027 #include <finiteVolume/cellToFaceStencil.H>
00028 #include <OpenFOAM/syncTools.H>
00029 #include <OpenFOAM/SortableList.H>
00030
00031
00032
00033 void Foam::extendedUpwindCellToFaceStencil::selectOppositeFaces
00034 (
00035 const boolList& nonEmptyFace,
00036 const scalar minOpposedness,
00037 const label faceI,
00038 const label cellI,
00039 DynamicList<label>& oppositeFaces
00040 ) const
00041 {
00042 const vectorField& areas = mesh_.faceAreas();
00043 const labelList& own = mesh_.faceOwner();
00044 const cell& cFaces = mesh_.cells()[cellI];
00045
00046 SortableList<scalar> opposedness(cFaces.size(), -GREAT);
00047
00048
00049 forAll(cFaces, i)
00050 {
00051 label otherFaceI = cFaces[i];
00052
00053 if (otherFaceI != faceI && nonEmptyFace[otherFaceI])
00054 {
00055 if ((own[otherFaceI] == cellI) == (own[faceI] == cellI))
00056 {
00057 opposedness[i] = -(areas[otherFaceI] & areas[faceI]);
00058 }
00059 else
00060 {
00061 opposedness[i] = (areas[otherFaceI] & areas[faceI]);
00062 }
00063 }
00064 }
00065
00066 label sz = opposedness.size();
00067
00068 oppositeFaces.clear();
00069
00070 scalar myAreaSqr = magSqr(areas[faceI]);
00071
00072 if (myAreaSqr > VSMALL)
00073 {
00074 forAll(opposedness, i)
00075 {
00076 opposedness[i] /= myAreaSqr;
00077 }
00078
00079 opposedness.sort();
00080
00081
00082 oppositeFaces.append(cFaces[opposedness.indices()[sz-1]]);
00083
00084 for (label i = sz-2; i >= 0; --i)
00085 {
00086 if (opposedness[i] < minOpposedness)
00087 {
00088 break;
00089 }
00090 oppositeFaces.append(cFaces[opposedness.indices()[i]]);
00091 }
00092 }
00093 else
00094 {
00095
00096 opposedness.sort();
00097
00098
00099
00100 oppositeFaces.append(cFaces[opposedness.indices()[sz-1]]);
00101 }
00102 }
00103
00104
00105 void Foam::extendedUpwindCellToFaceStencil::transportStencil
00106 (
00107 const boolList& nonEmptyFace,
00108 const labelListList& faceStencil,
00109 const scalar minOpposedness,
00110 const label faceI,
00111 const label cellI,
00112 const bool stencilHasNeighbour,
00113
00114 DynamicList<label>& oppositeFaces,
00115 labelHashSet& faceStencilSet,
00116 labelList& transportedStencil
00117 ) const
00118 {
00119 label globalOwn = faceStencil[faceI][0];
00120 label globalNei = -1;
00121 if (stencilHasNeighbour && faceStencil[faceI].size() >= 2)
00122 {
00123 globalNei = faceStencil[faceI][1];
00124 }
00125
00126
00127 selectOppositeFaces
00128 (
00129 nonEmptyFace,
00130 minOpposedness,
00131 faceI,
00132 cellI,
00133 oppositeFaces
00134 );
00135
00136
00137 faceStencilSet.clear();
00138 forAll(oppositeFaces, i)
00139 {
00140 const labelList& fStencil = faceStencil[oppositeFaces[i]];
00141
00142 forAll(fStencil, j)
00143 {
00144 label globalI = fStencil[j];
00145
00146 if (globalI != globalOwn && globalI != globalNei)
00147 {
00148 faceStencilSet.insert(globalI);
00149 }
00150 }
00151 }
00152
00153
00154 if (stencilHasNeighbour)
00155 {
00156 transportedStencil.setSize(faceStencilSet.size()+2);
00157 label n = 0;
00158 transportedStencil[n++] = globalOwn;
00159 transportedStencil[n++] = globalNei;
00160
00161 forAllConstIter(labelHashSet, faceStencilSet, iter)
00162 {
00163 if (iter.key() != globalOwn && iter.key() != globalNei)
00164 {
00165 transportedStencil[n++] = iter.key();
00166 }
00167 }
00168 if (n != transportedStencil.size())
00169 {
00170 FatalErrorIn
00171 (
00172 "extendedUpwindCellToFaceStencil::transportStencil(..)"
00173 ) << "problem:" << faceStencilSet
00174 << abort(FatalError);
00175 }
00176 }
00177 else
00178 {
00179 transportedStencil.setSize(faceStencilSet.size()+1);
00180 label n = 0;
00181 transportedStencil[n++] = globalOwn;
00182
00183 forAllConstIter(labelHashSet, faceStencilSet, iter)
00184 {
00185 if (iter.key() != globalOwn)
00186 {
00187 transportedStencil[n++] = iter.key();
00188 }
00189 }
00190 if (n != transportedStencil.size())
00191 {
00192 FatalErrorIn
00193 (
00194 "extendedUpwindCellToFaceStencil::transportStencil(..)"
00195 ) << "problem:" << faceStencilSet
00196 << abort(FatalError);
00197 }
00198 }
00199 }
00200
00201
00202 void Foam::extendedUpwindCellToFaceStencil::transportStencils
00203 (
00204 const labelListList& faceStencil,
00205 const scalar minOpposedness,
00206 labelListList& ownStencil,
00207 labelListList& neiStencil
00208 )
00209 {
00210 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
00211 const label nBnd = mesh_.nFaces()-mesh_.nInternalFaces();
00212 const labelList& own = mesh_.faceOwner();
00213 const labelList& nei = mesh_.faceNeighbour();
00214
00215
00216 DynamicList<label> oppositeFaces;
00217 labelHashSet faceStencilSet;
00218
00219
00220
00221 boolList nonEmptyFace(mesh_.nFaces(), true);
00222 forAll(patches, patchI)
00223 {
00224 const polyPatch& pp = patches[patchI];
00225
00226 if (isA<emptyPolyPatch>(pp))
00227 {
00228 label faceI = pp.start();
00229 forAll(pp, i)
00230 {
00231 nonEmptyFace[faceI++] = false;
00232 }
00233 }
00234 }
00235
00236
00237
00238
00239
00240
00241 ownStencil.setSize(mesh_.nFaces());
00242
00243
00244 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
00245 {
00246
00247 transportStencil
00248 (
00249 nonEmptyFace,
00250 faceStencil,
00251 minOpposedness,
00252 faceI,
00253 own[faceI],
00254 true,
00255 oppositeFaces,
00256 faceStencilSet,
00257 ownStencil[faceI]
00258 );
00259 }
00260
00261 forAll(patches, patchI)
00262 {
00263 const polyPatch& pp = patches[patchI];
00264 label faceI = pp.start();
00265
00266 if (pp.coupled())
00267 {
00268 forAll(pp, i)
00269 {
00270 transportStencil
00271 (
00272 nonEmptyFace,
00273 faceStencil,
00274 minOpposedness,
00275 faceI,
00276 own[faceI],
00277 true,
00278
00279 oppositeFaces,
00280 faceStencilSet,
00281 ownStencil[faceI]
00282 );
00283 faceI++;
00284 }
00285 }
00286 else if (!isA<emptyPolyPatch>(pp))
00287 {
00288 forAll(pp, i)
00289 {
00290
00291 transportStencil
00292 (
00293 nonEmptyFace,
00294 faceStencil,
00295 minOpposedness,
00296 faceI,
00297 own[faceI],
00298 false,
00299
00300 oppositeFaces,
00301 faceStencilSet,
00302 ownStencil[faceI]
00303 );
00304 faceI++;
00305 }
00306 }
00307 }
00308
00309
00310
00311
00312
00313 labelListList neiBndStencil(nBnd);
00314 for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++)
00315 {
00316 neiBndStencil[faceI-mesh_.nInternalFaces()] = ownStencil[faceI];
00317 }
00318 syncTools::swapBoundaryFaceList(mesh_, neiBndStencil, false);
00319
00320
00321
00322
00323
00324
00325
00326
00327 neiStencil.setSize(mesh_.nFaces());
00328
00329
00330 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
00331 {
00332 transportStencil
00333 (
00334 nonEmptyFace,
00335 faceStencil,
00336 minOpposedness,
00337 faceI,
00338 nei[faceI],
00339 true,
00340
00341 oppositeFaces,
00342 faceStencilSet,
00343 neiStencil[faceI]
00344 );
00345 }
00346
00347
00348 forAll(patches, patchI)
00349 {
00350 const polyPatch& pp = patches[patchI];
00351 label faceI = pp.start();
00352
00353 if (pp.coupled())
00354 {
00355 forAll(pp, i)
00356 {
00357 neiStencil[faceI].transfer
00358 (
00359 neiBndStencil[faceI-mesh_.nInternalFaces()]
00360 );
00361 faceI++;
00362 }
00363 }
00364 else
00365 {
00366
00367 }
00368 }
00369 }
00370
00371
00372
00373
00374 Foam::extendedUpwindCellToFaceStencil::extendedUpwindCellToFaceStencil
00375 (
00376 const cellToFaceStencil& stencil,
00377 const bool pureUpwind,
00378 const scalar minOpposedness
00379 )
00380 :
00381 extendedCellToFaceStencil(stencil.mesh()),
00382 pureUpwind_(pureUpwind)
00383 {
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 transportStencils
00414 (
00415 stencil,
00416 minOpposedness,
00417 ownStencil_,
00418 neiStencil_
00419 );
00420
00421 ownMapPtr_ = calcDistributeMap
00422 (
00423 stencil.mesh(),
00424 stencil.globalNumbering(),
00425 ownStencil_
00426 );
00427
00428 neiMapPtr_ = calcDistributeMap
00429 (
00430 stencil.mesh(),
00431 stencil.globalNumbering(),
00432 neiStencil_
00433 );
00434
00435
00436 if (pureUpwind_)
00437 {
00438 const fvMesh& mesh = dynamic_cast<const fvMesh&>(stencil.mesh());
00439
00440 List<List<point> > stencilPoints(ownStencil_.size());
00441
00442
00443
00444
00445 collectData(ownMapPtr_(), ownStencil_, mesh.C(), stencilPoints);
00446
00447
00448 forAll(stencilPoints, faceI)
00449 {
00450 const point& fc = mesh.faceCentres()[faceI];
00451 const vector& fArea = mesh.faceAreas()[faceI];
00452
00453 const List<point>& points = stencilPoints[faceI];
00454 const labelList& stencil = ownStencil_[faceI];
00455
00456 DynamicList<label> newStencil(stencil.size());
00457 forAll(points, i)
00458 {
00459 if (((points[i]-fc) & fArea) < 0)
00460 {
00461 newStencil.append(stencil[i]);
00462 }
00463 }
00464 if (newStencil.size() != stencil.size())
00465 {
00466 ownStencil_[faceI].transfer(newStencil);
00467 }
00468 }
00469
00470
00471
00472
00473
00474 collectData(neiMapPtr_(), neiStencil_, mesh.C(), stencilPoints);
00475
00476
00477 forAll(stencilPoints, faceI)
00478 {
00479 const point& fc = mesh.faceCentres()[faceI];
00480 const vector& fArea = mesh.faceAreas()[faceI];
00481
00482 const List<point>& points = stencilPoints[faceI];
00483 const labelList& stencil = neiStencil_[faceI];
00484
00485 DynamicList<label> newStencil(stencil.size());
00486 forAll(points, i)
00487 {
00488 if (((points[i]-fc) & fArea) > 0)
00489 {
00490 newStencil.append(stencil[i]);
00491 }
00492 }
00493 if (newStencil.size() != stencil.size())
00494 {
00495 neiStencil_[faceI].transfer(newStencil);
00496 }
00497 }
00498
00499
00500
00501 }
00502 }
00503
00504
00505 Foam::extendedUpwindCellToFaceStencil::extendedUpwindCellToFaceStencil
00506 (
00507 const cellToFaceStencil& stencil
00508 )
00509 :
00510 extendedCellToFaceStencil(stencil.mesh()),
00511 pureUpwind_(true)
00512 {
00513
00514
00515 ownStencil_ = stencil;
00516
00517 ownMapPtr_ = calcDistributeMap
00518 (
00519 stencil.mesh(),
00520 stencil.globalNumbering(),
00521 ownStencil_
00522 );
00523
00524 const fvMesh& mesh = dynamic_cast<const fvMesh&>(stencil.mesh());
00525
00526 List<List<point> > stencilPoints(ownStencil_.size());
00527 collectData(ownMapPtr_(), ownStencil_, mesh.C(), stencilPoints);
00528
00529
00530 neiStencil_.setSize(ownStencil_.size());
00531
00532 forAll(stencilPoints, faceI)
00533 {
00534 const point& fc = mesh.faceCentres()[faceI];
00535 const vector& fArea = mesh.faceAreas()[faceI];
00536
00537 const List<point>& points = stencilPoints[faceI];
00538 const labelList& stencil = ownStencil_[faceI];
00539
00540 DynamicList<label> newOwnStencil(stencil.size());
00541 DynamicList<label> newNeiStencil(stencil.size());
00542 forAll(points, i)
00543 {
00544 if (((points[i]-fc) & fArea) > 0)
00545 {
00546 newNeiStencil.append(stencil[i]);
00547 }
00548 else
00549 {
00550 newOwnStencil.append(stencil[i]);
00551 }
00552 }
00553 if (newNeiStencil.size() > 0)
00554 {
00555 ownStencil_[faceI].transfer(newOwnStencil);
00556 neiStencil_[faceI].transfer(newNeiStencil);
00557 }
00558 }
00559
00560
00561 neiMapPtr_.reset(new mapDistribute(ownMapPtr_()));
00562 }
00563
00564
00565