1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2008 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 "removeCells.H"
29 #include "polyTopoChange.H"
30 #include "polyRemoveCell.H"
31 #include "polyRemoveFace.H"
32 #include "polyModifyFace.H"
33 #include "polyRemovePoint.H"
34 #include "syncTools.H"
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41 defineTypeNameAndDebug(removeCells, 0);
45 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
47 // Remove count of elements of f.
48 void Foam::removeCells::uncount
61 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
63 // Construct from mesh
64 Foam::removeCells::removeCells
75 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
77 //- Get labels of exposed faces. These are
78 // - internal faces that become boundary faces
79 // - coupled faces that become uncoupled (since on of the sides
81 Foam::labelList Foam::removeCells::getExposedFaces
83 const labelList& cellLabels
86 // Create list of cells to be removed
87 boolList removedCell(mesh_.nCells(), false);
89 // Go from labelList of cells-to-remove to a boolList.
92 removedCell[cellLabels[i]] = true;
96 const labelList& faceOwner = mesh_.faceOwner();
97 const labelList& faceNeighbour = mesh_.faceNeighbour();
99 // Count cells using face.
100 labelList nCellsUsingFace(mesh_.nFaces(), 0);
102 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
104 label own = faceOwner[faceI];
105 label nei = faceNeighbour[faceI];
107 if (!removedCell[own])
109 nCellsUsingFace[faceI]++;
111 if (!removedCell[nei])
113 nCellsUsingFace[faceI]++;
117 for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++)
119 label own = faceOwner[faceI];
121 if (!removedCell[own])
123 nCellsUsingFace[faceI]++;
127 // Coupled faces: add number of cells using face across couple.
130 syncTools::syncFaceList
139 // Now nCellsUsingFace:
140 // 0 : internal face whose both cells get deleted
141 // boundary face whose all cells get deleted
142 // 1 : internal face that gets exposed
143 // unaffected (uncoupled) boundary face
144 // coupled boundary face that gets exposed ('uncoupled')
145 // 2 : unaffected internal face
146 // unaffected coupled boundary face
148 DynamicList<label> exposedFaces(mesh_.nFaces()/10);
150 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
152 if (nCellsUsingFace[faceI] == 1)
154 exposedFaces.append(faceI);
158 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
160 forAll(patches, patchI)
162 const polyPatch& pp = patches[patchI];
166 label faceI = pp.start();
170 label own = faceOwner[faceI];
172 if (nCellsUsingFace[faceI] == 1 && !removedCell[own])
174 // My owner not removed but other side is so has to become
175 // normal, uncoupled, boundary face
176 exposedFaces.append(faceI);
184 return exposedFaces.shrink();
188 void Foam::removeCells::setRefinement
190 const labelList& cellLabels,
191 const labelList& exposedFaceLabels,
192 const labelList& exposedPatchIDs,
193 polyTopoChange& meshMod
196 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
198 if (exposedFaceLabels.size() != exposedPatchIDs.size())
202 "removeCells::setRefinement(const labelList&"
203 ", const labelList&, const labelList&, polyTopoChange&)"
204 ) << "Size of exposedFaceLabels " << exposedFaceLabels.size()
205 << " differs from size of exposedPatchIDs "
206 << exposedPatchIDs.size()
207 << abort(FatalError);
210 // List of new patchIDs
211 labelList newPatchID(mesh_.nFaces(), -1);
213 forAll(exposedFaceLabels, i)
215 label patchI = exposedPatchIDs[i];
217 if (patchI < 0 || patchI >= patches.size())
221 "removeCells::setRefinement(const labelList&"
222 ", const labelList&, const labelList&, polyTopoChange&)"
223 ) << "Invalid patch " << patchI
224 << " for exposed face " << exposedFaceLabels[i] << endl
225 << "Valid patches 0.." << patches.size()-1
226 << abort(FatalError);
229 if (patches[patchI].coupled())
233 "removeCells::setRefinement(const labelList&"
234 ", const labelList&, const labelList&, polyTopoChange&)"
235 ) << "Trying to put exposed face " << exposedFaceLabels[i]
236 << " into a coupled patch : " << patches[patchI].name()
238 << "This is illegal."
239 << abort(FatalError);
242 newPatchID[exposedFaceLabels[i]] = patchI;
246 // Create list of cells to be removed
247 boolList removedCell(mesh_.nCells(), false);
249 // Go from labelList of cells-to-remove to a boolList and remove all
251 forAll(cellLabels, i)
253 label cellI = cellLabels[i];
255 removedCell[cellI] = true;
257 //Pout<< "Removing cell " << cellI
258 // << " cc:" << mesh_.cellCentres()[cellI] << endl;
260 meshMod.setAction(polyRemoveCell(cellI));
264 // Remove faces that are no longer used. Modify faces that
265 // are used by one cell only.
267 const faceList& faces = mesh_.faces();
268 const labelList& faceOwner = mesh_.faceOwner();
269 const labelList& faceNeighbour = mesh_.faceNeighbour();
270 const faceZoneMesh& faceZones = mesh_.faceZones();
272 // Count starting number of faces using each point. Keep up to date whenever
274 labelList nFacesUsingPoint(mesh_.nPoints(), 0);
278 const face& f = faces[faceI];
282 nFacesUsingPoint[f[fp]]++;
287 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
289 const face& f = faces[faceI];
290 label own = faceOwner[faceI];
291 label nei = faceNeighbour[faceI];
293 if (removedCell[own])
295 if (removedCell[nei])
297 // Face no longer used
298 //Pout<< "Removing internal face " << faceI
299 // << " fc:" << mesh_.faceCentres()[faceI] << endl;
301 meshMod.setAction(polyRemoveFace(faceI));
302 uncount(f, nFacesUsingPoint);
306 if (newPatchID[faceI] == -1)
310 "removeCells::setRefinement(const labelList&"
311 ", const labelList&, const labelList&"
313 ) << "No patchID provided for exposed face " << faceI
314 << " on cell " << nei << nl
315 << "Did you provide patch IDs for all exposed faces?"
316 << abort(FatalError);
319 // nei is remaining cell. FaceI becomes external cell
321 label zoneID = faceZones.whichZone(faceI);
322 bool zoneFlip = false;
326 const faceZone& fZone = faceZones[zoneID];
327 zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
330 //Pout<< "Putting exposed internal face " << faceI
331 // << " fc:" << mesh_.faceCentres()[faceI]
332 // << " into patch " << newPatchID[faceI] << endl;
338 f.reverseFace(), // modified face
339 faceI, // label of face being modified
343 newPatchID[faceI], // patch for face
344 false, // remove from zone
345 zoneID, // zone for face
346 zoneFlip // face flip in zone
351 else if (removedCell[nei])
353 if (newPatchID[faceI] == -1)
357 "removeCells::setRefinement(const labelList&"
358 ", const labelList&, const labelList&"
360 ) << "No patchID provided for exposed face " << faceI
361 << " on cell " << own << nl
362 << "Did you provide patch IDs for all exposed faces?"
363 << abort(FatalError);
366 //Pout<< "Putting exposed internal face " << faceI
367 // << " fc:" << mesh_.faceCentres()[faceI]
368 // << " into patch " << newPatchID[faceI] << endl;
370 // own is remaining cell. FaceI becomes external cell.
371 label zoneID = faceZones.whichZone(faceI);
372 bool zoneFlip = false;
376 const faceZone& fZone = faceZones[zoneID];
377 zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
385 faceI, // label of face being modified
389 newPatchID[faceI], // patch for face
390 false, // remove from zone
391 zoneID, // zone for face
392 zoneFlip // face flip in zone
398 forAll(patches, patchI)
400 const polyPatch& pp = patches[patchI];
404 label faceI = pp.start();
408 if (newPatchID[faceI] != -1)
410 //Pout<< "Putting uncoupled coupled face " << faceI
411 // << " fc:" << mesh_.faceCentres()[faceI]
412 // << " into patch " << newPatchID[faceI] << endl;
414 label zoneID = faceZones.whichZone(faceI);
415 bool zoneFlip = false;
419 const faceZone& fZone = faceZones[zoneID];
420 zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
427 faces[faceI], // modified face
428 faceI, // label of face
429 faceOwner[faceI], // owner
432 newPatchID[faceI], // patch for face
433 false, // remove from zone
434 zoneID, // zone for face
435 zoneFlip // face flip in zone
439 else if (removedCell[faceOwner[faceI]])
441 // Face no longer used
442 //Pout<< "Removing boundary face " << faceI
443 // << " fc:" << mesh_.faceCentres()[faceI]
446 meshMod.setAction(polyRemoveFace(faceI));
447 uncount(faces[faceI], nFacesUsingPoint);
455 label faceI = pp.start();
459 if (newPatchID[faceI] != -1)
463 "removeCells::setRefinement(const labelList&"
464 ", const labelList&, const labelList&"
466 ) << "new patchID provided for boundary face " << faceI
467 << " even though it is not on a coupled face."
468 << abort(FatalError);
471 if (removedCell[faceOwner[faceI]])
473 // Face no longer used
474 //Pout<< "Removing boundary face " << faceI
475 // << " fc:" << mesh_.faceCentres()[faceI]
478 meshMod.setAction(polyRemoveFace(faceI));
479 uncount(faces[faceI], nFacesUsingPoint);
488 // Remove points that are no longer used.
489 // Loop rewritten to not use pointFaces.
491 forAll(nFacesUsingPoint, pointI)
493 if (nFacesUsingPoint[pointI] == 0)
495 //Pout<< "Removing unused point " << pointI
496 // << " at:" << mesh_.points()[pointI] << endl;
498 meshMod.setAction(polyRemovePoint(pointI));
500 else if (nFacesUsingPoint[pointI] == 1)
504 "removeCells::setRefinement(const labelList&"
505 ", const labelList&, const labelList&"
507 ) << "point " << pointI << " at coordinate "
508 << mesh_.points()[pointI]
509 << " is only used by 1 face after removing cells."
510 << " This probably results in an illegal mesh."
517 // ************************************************************************* //