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 "removeCells.H"
00027 #include <OpenFOAM/polyMesh.H>
00028 #include "polyTopoChange.H"
00029 #include <dynamicMesh/polyRemoveCell.H>
00030 #include <dynamicMesh/polyRemoveFace.H>
00031 #include <dynamicMesh/polyModifyFace.H>
00032 #include <dynamicMesh/polyRemovePoint.H>
00033 #include <OpenFOAM/syncTools.H>
00034
00035
00036
00037 namespace Foam
00038 {
00039
00040 defineTypeNameAndDebug(removeCells, 0);
00041
00042 }
00043
00044
00045
00046
00047 void Foam::removeCells::uncount
00048 (
00049 const labelList& f,
00050 labelList& nUsage
00051 )
00052 {
00053 forAll(f, fp)
00054 {
00055 nUsage[f[fp]]--;
00056 }
00057 }
00058
00059
00060
00061
00062
00063 Foam::removeCells::removeCells
00064 (
00065 const polyMesh& mesh,
00066 const bool syncPar
00067 )
00068 :
00069 mesh_(mesh),
00070 syncPar_(syncPar)
00071 {}
00072
00073
00074
00075
00076
00077
00078
00079
00080 Foam::labelList Foam::removeCells::getExposedFaces
00081 (
00082 const labelList& cellLabels
00083 ) const
00084 {
00085
00086 boolList removedCell(mesh_.nCells(), false);
00087
00088
00089 forAll(cellLabels, i)
00090 {
00091 removedCell[cellLabels[i]] = true;
00092 }
00093
00094
00095 const labelList& faceOwner = mesh_.faceOwner();
00096 const labelList& faceNeighbour = mesh_.faceNeighbour();
00097
00098
00099 labelList nCellsUsingFace(mesh_.nFaces(), 0);
00100
00101 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
00102 {
00103 label own = faceOwner[faceI];
00104 label nei = faceNeighbour[faceI];
00105
00106 if (!removedCell[own])
00107 {
00108 nCellsUsingFace[faceI]++;
00109 }
00110 if (!removedCell[nei])
00111 {
00112 nCellsUsingFace[faceI]++;
00113 }
00114 }
00115
00116 for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++)
00117 {
00118 label own = faceOwner[faceI];
00119
00120 if (!removedCell[own])
00121 {
00122 nCellsUsingFace[faceI]++;
00123 }
00124 }
00125
00126
00127 if (syncPar_)
00128 {
00129 syncTools::syncFaceList
00130 (
00131 mesh_,
00132 nCellsUsingFace,
00133 plusEqOp<label>(),
00134 false
00135 );
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 DynamicList<label> exposedFaces(mesh_.nFaces()/10);
00148
00149 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
00150 {
00151 if (nCellsUsingFace[faceI] == 1)
00152 {
00153 exposedFaces.append(faceI);
00154 }
00155 }
00156
00157 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
00158
00159 forAll(patches, patchI)
00160 {
00161 const polyPatch& pp = patches[patchI];
00162
00163 if (pp.coupled())
00164 {
00165 label faceI = pp.start();
00166
00167 forAll(pp, i)
00168 {
00169 label own = faceOwner[faceI];
00170
00171 if (nCellsUsingFace[faceI] == 1 && !removedCell[own])
00172 {
00173
00174
00175 exposedFaces.append(faceI);
00176 }
00177
00178 faceI++;
00179 }
00180 }
00181 }
00182
00183 return exposedFaces.shrink();
00184 }
00185
00186
00187 void Foam::removeCells::setRefinement
00188 (
00189 const labelList& cellLabels,
00190 const labelList& exposedFaceLabels,
00191 const labelList& exposedPatchIDs,
00192 polyTopoChange& meshMod
00193 ) const
00194 {
00195 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
00196
00197 if (exposedFaceLabels.size() != exposedPatchIDs.size())
00198 {
00199 FatalErrorIn
00200 (
00201 "removeCells::setRefinement(const labelList&"
00202 ", const labelList&, const labelList&, polyTopoChange&)"
00203 ) << "Size of exposedFaceLabels " << exposedFaceLabels.size()
00204 << " differs from size of exposedPatchIDs "
00205 << exposedPatchIDs.size()
00206 << abort(FatalError);
00207 }
00208
00209
00210 labelList newPatchID(mesh_.nFaces(), -1);
00211
00212 forAll(exposedFaceLabels, i)
00213 {
00214 label patchI = exposedPatchIDs[i];
00215
00216 if (patchI < 0 || patchI >= patches.size())
00217 {
00218 FatalErrorIn
00219 (
00220 "removeCells::setRefinement(const labelList&"
00221 ", const labelList&, const labelList&, polyTopoChange&)"
00222 ) << "Invalid patch " << patchI
00223 << " for exposed face " << exposedFaceLabels[i] << endl
00224 << "Valid patches 0.." << patches.size()-1
00225 << abort(FatalError);
00226 }
00227
00228 if (patches[patchI].coupled())
00229 {
00230 FatalErrorIn
00231 (
00232 "removeCells::setRefinement(const labelList&"
00233 ", const labelList&, const labelList&, polyTopoChange&)"
00234 ) << "Trying to put exposed face " << exposedFaceLabels[i]
00235 << " into a coupled patch : " << patches[patchI].name()
00236 << endl
00237 << "This is illegal."
00238 << abort(FatalError);
00239 }
00240
00241 newPatchID[exposedFaceLabels[i]] = patchI;
00242 }
00243
00244
00245
00246 boolList removedCell(mesh_.nCells(), false);
00247
00248
00249
00250 forAll(cellLabels, i)
00251 {
00252 label cellI = cellLabels[i];
00253
00254 removedCell[cellI] = true;
00255
00256
00257
00258
00259 meshMod.setAction(polyRemoveCell(cellI));
00260 }
00261
00262
00263
00264
00265
00266 const faceList& faces = mesh_.faces();
00267 const labelList& faceOwner = mesh_.faceOwner();
00268 const labelList& faceNeighbour = mesh_.faceNeighbour();
00269 const faceZoneMesh& faceZones = mesh_.faceZones();
00270
00271
00272
00273 labelList nFacesUsingPoint(mesh_.nPoints(), 0);
00274
00275 forAll(faces, faceI)
00276 {
00277 const face& f = faces[faceI];
00278
00279 forAll(f, fp)
00280 {
00281 nFacesUsingPoint[f[fp]]++;
00282 }
00283 }
00284
00285
00286 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
00287 {
00288 const face& f = faces[faceI];
00289 label own = faceOwner[faceI];
00290 label nei = faceNeighbour[faceI];
00291
00292 if (removedCell[own])
00293 {
00294 if (removedCell[nei])
00295 {
00296
00297
00298
00299
00300 meshMod.setAction(polyRemoveFace(faceI));
00301 uncount(f, nFacesUsingPoint);
00302 }
00303 else
00304 {
00305 if (newPatchID[faceI] == -1)
00306 {
00307 FatalErrorIn
00308 (
00309 "removeCells::setRefinement(const labelList&"
00310 ", const labelList&, const labelList&"
00311 ", polyTopoChange&)"
00312 ) << "No patchID provided for exposed face " << faceI
00313 << " on cell " << nei << nl
00314 << "Did you provide patch IDs for all exposed faces?"
00315 << abort(FatalError);
00316 }
00317
00318
00319
00320 label zoneID = faceZones.whichZone(faceI);
00321 bool zoneFlip = false;
00322
00323 if (zoneID >= 0)
00324 {
00325 const faceZone& fZone = faceZones[zoneID];
00326
00327
00328 zoneFlip = !fZone.flipMap()[fZone.whichFace(faceI)];
00329 }
00330
00331
00332
00333
00334
00335 meshMod.setAction
00336 (
00337 polyModifyFace
00338 (
00339 f.reverseFace(),
00340 faceI,
00341 nei,
00342 -1,
00343 true,
00344 newPatchID[faceI],
00345 false,
00346 zoneID,
00347 zoneFlip
00348 )
00349 );
00350 }
00351 }
00352 else if (removedCell[nei])
00353 {
00354 if (newPatchID[faceI] == -1)
00355 {
00356 FatalErrorIn
00357 (
00358 "removeCells::setRefinement(const labelList&"
00359 ", const labelList&, const labelList&"
00360 ", polyTopoChange&)"
00361 ) << "No patchID provided for exposed face " << faceI
00362 << " on cell " << own << nl
00363 << "Did you provide patch IDs for all exposed faces?"
00364 << abort(FatalError);
00365 }
00366
00367
00368
00369
00370
00371
00372 label zoneID = faceZones.whichZone(faceI);
00373 bool zoneFlip = false;
00374
00375 if (zoneID >= 0)
00376 {
00377 const faceZone& fZone = faceZones[zoneID];
00378 zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
00379 }
00380
00381 meshMod.setAction
00382 (
00383 polyModifyFace
00384 (
00385 f,
00386 faceI,
00387 own,
00388 -1,
00389 false,
00390 newPatchID[faceI],
00391 false,
00392 zoneID,
00393 zoneFlip
00394 )
00395 );
00396 }
00397 }
00398
00399 forAll(patches, patchI)
00400 {
00401 const polyPatch& pp = patches[patchI];
00402
00403 if (pp.coupled())
00404 {
00405 label faceI = pp.start();
00406
00407 forAll(pp, i)
00408 {
00409 if (newPatchID[faceI] != -1)
00410 {
00411
00412
00413
00414
00415 label zoneID = faceZones.whichZone(faceI);
00416 bool zoneFlip = false;
00417
00418 if (zoneID >= 0)
00419 {
00420 const faceZone& fZone = faceZones[zoneID];
00421 zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
00422 }
00423
00424 meshMod.setAction
00425 (
00426 polyModifyFace
00427 (
00428 faces[faceI],
00429 faceI,
00430 faceOwner[faceI],
00431 -1,
00432 false,
00433 newPatchID[faceI],
00434 false,
00435 zoneID,
00436 zoneFlip
00437 )
00438 );
00439 }
00440 else if (removedCell[faceOwner[faceI]])
00441 {
00442
00443
00444
00445
00446
00447 meshMod.setAction(polyRemoveFace(faceI));
00448 uncount(faces[faceI], nFacesUsingPoint);
00449 }
00450
00451 faceI++;
00452 }
00453 }
00454 else
00455 {
00456 label faceI = pp.start();
00457
00458 forAll(pp, i)
00459 {
00460 if (newPatchID[faceI] != -1)
00461 {
00462 FatalErrorIn
00463 (
00464 "removeCells::setRefinement(const labelList&"
00465 ", const labelList&, const labelList&"
00466 ", polyTopoChange&)"
00467 ) << "new patchID provided for boundary face " << faceI
00468 << " even though it is not on a coupled face."
00469 << abort(FatalError);
00470 }
00471
00472 if (removedCell[faceOwner[faceI]])
00473 {
00474
00475
00476
00477
00478
00479 meshMod.setAction(polyRemoveFace(faceI));
00480 uncount(faces[faceI], nFacesUsingPoint);
00481 }
00482
00483 faceI++;
00484 }
00485 }
00486 }
00487
00488
00489
00490
00491
00492 forAll(nFacesUsingPoint, pointI)
00493 {
00494 if (nFacesUsingPoint[pointI] == 0)
00495 {
00496
00497
00498
00499 meshMod.setAction(polyRemovePoint(pointI));
00500 }
00501 else if (nFacesUsingPoint[pointI] == 1)
00502 {
00503 WarningIn
00504 (
00505 "removeCells::setRefinement(const labelList&"
00506 ", const labelList&, const labelList&"
00507 ", polyTopoChange&)"
00508 ) << "point " << pointI << " at coordinate "
00509 << mesh_.points()[pointI]
00510 << " is only used by 1 face after removing cells."
00511 << " This probably results in an illegal mesh."
00512 << endl;
00513 }
00514 }
00515 }
00516
00517
00518