1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
25 Remove a layer of cells and prepare addressing data
27 \*---------------------------------------------------------------------------*/
29 #include "layerAdditionRemoval.H"
31 #include "primitiveMesh.H"
32 #include "polyTopoChange.H"
33 #include "oppositeFace.H"
34 #include "polyTopoChanger.H"
35 #include "polyRemoveCell.H"
36 #include "polyRemoveFace.H"
37 #include "polyRemovePoint.H"
38 #include "polyModifyFace.H"
40 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
42 bool Foam::layerAdditionRemoval::validCollapse() const
44 // Check for valid layer collapse
45 // - no boundary-to-boundary collapse
49 Pout<< "Checking layer collapse for object " << name() << endl;
52 // Grab the face collapse mapping
53 const polyMesh& mesh = topoChanger().mesh();
55 const labelList& ftc = facesPairing();
56 const labelList& mf = mesh.faceZones()[faceZoneID_.index()];
58 label nBoundaryHits = 0;
64 !mesh.isInternalFace(mf[faceI])
65 && !mesh.isInternalFace(ftc[faceI])
75 Pout<< "Finished checking layer collapse for object "
76 << name() <<". Number of boundary-on-boundary hits: "
77 << nBoundaryHits << endl;
80 if (returnReduce(nBoundaryHits, sumOp<label>()) > 0)
90 void Foam::layerAdditionRemoval::removeCellLayer
95 // Algorithm for layer removal. Second phase: topological change
96 // 2) Go through all the faces of the master cell layer and remove
97 // the ones that are not in the master face zone.
99 // 3) Grab all the faces coming out of points that are collapsed
100 // and select the ones that are not marked for removal. Go
101 // through the remaining faces and replace the point to remove by
102 // the equivalent point in the master face zone.
105 Pout<< "Removing the cell layer for object " << name() << endl;
108 const polyMesh& mesh = topoChanger().mesh();
110 const labelList& ptc = pointsPairing();
111 const labelList& ftc = facesPairing();
113 // Remove all the cells from the master layer
114 const labelList& mc =
115 topoChanger().mesh().faceZones()[faceZoneID_.index()].masterCells();
119 ref.setAction(polyRemoveCell(mc[cellI]));
122 // Remove all the faces from the master layer cells which are not in
123 // the master face layer
124 labelHashSet facesToRemoveMap(mc.size()*primitiveMesh::facesPerCell_);
126 const cellList& cells = mesh.cells();
130 const cell& curCell = cells[mc[cellI]];
132 forAll(curCell, faceI)
134 // Check if the face is in the master zone. If not, remove it
137 mesh.faceZones().whichZone(curCell[faceI])
138 != faceZoneID_.index()
141 facesToRemoveMap.insert(curCell[faceI]);
146 forAllConstIter(labelHashSet, facesToRemoveMap, iter)
148 ref.setAction(polyRemoveFace(iter.key()));
151 // Remove all points that will be collapsed
154 ref.setAction(polyRemovePoint(ptc[pointI]));
157 // Grab all faces coming off points to be deleted. If the face
158 // has not been deleted, replace the removed point with the
159 // equivalent from the master layer.
161 // Make a map of all point to be removed, giving the master point label
164 Map<label> removedPointMap(2*ptc.size());
166 const labelList& meshPoints =
167 mesh.faceZones()[faceZoneID_.index()]().meshPoints();
171 removedPointMap.insert(ptc[pointI], meshPoints[pointI]);
174 const labelListList& pf = mesh.pointFaces();
176 const faceList& faces = mesh.faces();
177 const labelList& own = mesh.faceOwner();
178 const labelList& nei = mesh.faceNeighbour();
180 // Make a list of faces to be modified using the map to avoid duplicates
181 labelHashSet facesToModify(ptc.size()*primitiveMesh::facesPerPoint_);
185 const labelList& curFaces = pf[ptc[pointI]];
187 forAll(curFaces, faceI)
189 if (!facesToRemoveMap.found(curFaces[faceI]))
191 facesToModify.insert(curFaces[faceI]);
196 labelList ftm = facesToModify.toc();
198 //Pout<< "faces to modify: " << ftm << endl;
202 // For every face to modify, copy the face and re-map the vertices.
203 // It is known all the faces will be changed since they hang off
204 // re-mapped vertices
205 label curFaceID = ftm[faceI];
207 face newFace(faces[curFaceID]);
209 forAll(newFace, pointI)
211 Map<label>::iterator rpmIter =
212 removedPointMap.find(newFace[pointI]);
214 if (rpmIter != removedPointMap.end())
216 // Point mapped. Replace it
217 newFace[pointI] = rpmIter();
221 //Pout<< "face label: " << curFaceID
222 // << " old face: " << faces[curFaceID]
223 // << " new face: " << newFace << endl;
225 // Get face zone and its flip
226 label modifiedFaceZone = mesh.faceZones().whichZone(curFaceID);
227 bool modifiedFaceZoneFlip = false;
229 if (modifiedFaceZone >= 0)
231 modifiedFaceZoneFlip =
232 mesh.faceZones()[modifiedFaceZone].flipMap()
234 mesh.faceZones()[modifiedFaceZone].whichFace(curFaceID)
240 if (curFaceID < mesh.nInternalFaces())
242 newNei = nei[curFaceID];
254 newFace, // modified face
255 curFaceID, // label of face being modified
256 own[curFaceID], // owner
259 mesh.boundaryMesh().whichPatch(curFaceID),// patch for face
260 false, // remove from zone
261 modifiedFaceZone, // zone for face
262 modifiedFaceZoneFlip // face flip in zone
267 // Modify the faces in the master layer to point past the removed cells
269 const labelList& mf = mesh.faceZones()[faceZoneID_.index()];
270 const boolList& mfFlip = mesh.faceZones()[faceZoneID_.index()].flipMap();
274 // Grab the owner and neighbour of the faces to be collapsed and get rid
275 // of the cell to be removed
276 label masterSideCell = own[mf[faceI]];
278 if (masterSideCell == mc[faceI])
280 // Owner cell of the face is being removed.
281 // Grab the neighbour instead
282 masterSideCell = nei[mf[faceI]];
285 label slaveSideCell = own[ftc[faceI]];
287 if (slaveSideCell == mc[faceI])
289 // Owner cell of the face is being removed.
290 // Grab the neighbour instead
291 slaveSideCell = nei[ftc[faceI]];
294 // Find out if the face needs to be flipped
296 label newNeighbour = -1;
297 bool flipFace = false;
298 label newPatchID = -1;
299 label newZoneID = -1;
301 // Is any of the faces a boundary face? If so, grab the patch
302 // A boundary-to-boundary collapse is checked for in validCollapse()
303 // and cannot happen here.
305 if (!mesh.isInternalFace(mf[faceI]))
307 // Master is the boundary face: it gets a new owner but no flip
308 newOwner = slaveSideCell;
311 newPatchID = mesh.boundaryMesh().whichPatch(mf[faceI]);
312 newZoneID = mesh.faceZones().whichZone(mf[faceI]);
314 else if (!mesh.isInternalFace(ftc[faceI]))
316 // Slave is the boundary face: grab its patch
317 newOwner = slaveSideCell;
320 // Find out if the face flip is necessary
321 if (own[mf[faceI]] == slaveSideCell)
330 newPatchID = mesh.boundaryMesh().whichPatch(ftc[faceI]);
332 // The zone of the master face is preserved
333 newZoneID = mesh.faceZones().whichZone(mf[faceI]);
337 // Both faces are internal: flip is decided based on which of the
338 // new cells around it has a lower label
339 newOwner = min(masterSideCell, slaveSideCell);
340 newNeighbour = max(masterSideCell, slaveSideCell);
342 if (newOwner == own[mf[faceI]] || newNeighbour == nei[mf[faceI]])
353 // The zone of the master face is preserved
354 newZoneID = mesh.faceZones().whichZone(mf[faceI]);
357 // Modify the face and flip if necessary
358 face newFace = faces[mf[faceI]];
359 bool zoneFlip = mfFlip[faceI];
364 zoneFlip = !zoneFlip;
367 // Pout<< "Modifying face " << mf[faceI]
368 // << " newFace: " << newFace << nl
369 // << " newOwner: " << newOwner
370 // << " newNeighbour: " << newNeighbour
371 // << " flipFace: " << flipFace
372 // << " newPatchID: " << newPatchID
373 // << " newZoneID: " << newZoneID << nl
374 // << " oldOwn: " << own[mf[faceI]]
375 // << " oldNei: " << nei[mf[faceI]] << endl;
381 newFace, // modified face
382 mf[faceI], // label of face being modified
384 newNeighbour, // neighbour
386 newPatchID, // patch for face
387 false, // remove from zone
388 newZoneID, // new zone
389 zoneFlip // face flip in zone
396 // ************************************************************************* //