1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend 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 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "faceCracker.H"
28 #include "primitiveMesh.H"
29 #include "polyTopoChange.H"
30 #include "polyTopoChanger.H"
32 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
34 void Foam::faceCracker::detachFaceCracker
41 Pout<< "void faceCracker::detachFaceCracker("
42 << "polyTopoChange& ref) const "
43 << " for object " << name() << " : "
44 << "Detaching faces" << endl;
47 const polyMesh& mesh = topoChanger().mesh();
48 const faceZoneMesh& zoneMesh = mesh.faceZones();
50 const primitiveFacePatch& masterFaceLayer =
51 zoneMesh[crackZoneID_.index()]();
52 const pointField& points = mesh.points();
53 const labelListList& meshEdgeFaces = mesh.edgeFaces();
55 const labelList& mp = masterFaceLayer.meshPoints();
56 const edgeList& zoneLocalEdges = masterFaceLayer.edges();
58 const labelList& meshEdges = zoneMesh[crackZoneID_.index()].meshEdges();
62 labelList addedPoints(mp.size(), -1);
64 // Go through boundary edges of the master patch. If all the faces from
65 // this patch are internal, mark the points in the addedPoints lookup
66 // with their original labels to stop duplication
67 label nIntEdges = masterFaceLayer.nInternalEdges();
71 label curEdgeID = nIntEdges;
72 curEdgeID < meshEdges.size();
76 const labelList& curFaces = meshEdgeFaces[meshEdges[curEdgeID]];
78 bool edgeIsInternal = true;
80 forAll (curFaces, faceI)
82 if (!mesh.isInternalFace(curFaces[faceI]))
84 // The edge belongs to a boundary face
85 edgeIsInternal = false;
92 // Reset the point creation
93 addedPoints[zoneLocalEdges[curEdgeID].start()] =
94 mp[zoneLocalEdges[curEdgeID].start()];
96 addedPoints[zoneLocalEdges[curEdgeID].end()] =
97 mp[zoneLocalEdges[curEdgeID].end()];
100 // Pout << "addedPoints before point creation: " << addedPoints << endl;
102 // Create new points for face zone
103 forAll (addedPoints, pointI)
105 if (addedPoints[pointI] < 0)
107 addedPoints[pointI] =
112 points[mp[pointI]], // point
113 mp[pointI], // master point
115 true // supports a cell
121 // Modify faces in the master zone and duplicate for the slave zone
123 const labelList& mf = zoneMesh[crackZoneID_.index()];
124 const boolList& mfFlip = zoneMesh[crackZoneID_.index()].flipMap();
125 const faceList& zoneFaces = masterFaceLayer.localFaces();
127 const faceList& faces = mesh.faces();
128 const labelList& own = mesh.faceOwner();
129 const labelList& nei = mesh.faceNeighbour();
133 const label curFaceID = mf[faceI];
135 // Build the face for the slave patch by renumbering
136 const face oldFace = zoneFaces[faceI].reverseFace();
138 face newFace(oldFace.size());
140 forAll (oldFace, pointI)
142 newFace[pointI] = addedPoints[oldFace[pointI]];
147 // Face needs to be flipped for the master patch
152 faces[curFaceID].reverseFace(), // modified face
153 curFaceID, // label of face being modified
154 nei[curFaceID], // owner
157 crackPatchID_.index(), // patch for face
158 false, // remove from zone
159 crackZoneID_.index(), // zone for face
160 !mfFlip[faceI] // face flip in zone
164 // Add renumbered face into the slave patch
170 own[curFaceID], // owner
174 curFaceID, // master face
176 crackPatchID_.index(), // patch to add the face to
189 faces[curFaceID], // modified face
190 curFaceID, // label of face being modified
191 own[curFaceID], // owner
194 crackPatchID_.index(), // patch for face
195 false, // remove from zone
196 crackZoneID_.index(), // zone for face
197 mfFlip[faceI] // face flip in zone
201 // Add renumbered face into the slave patch
207 nei[curFaceID], // owner
211 curFaceID, // master face
213 crackPatchID_.index(), // patch to add the face to
215 false // face flip in zone
221 // Modify the remaining faces of the master cells to reconnect to the new
224 // Algorithm: Go through all the cells of the master zone and make
225 // a map of faces to avoid duplicates. Do not insert the faces in
226 // the master patch (as they have already been dealt with). Make
227 // a master layer point renumbering map, which for every point in
228 // the master layer gives its new label. Loop through all faces in
229 // the map and attempt to renumber them using the master layer
230 // point renumbering map. Once the face is renumbered, compare it
231 // with the original face; if they are the same, the face has not
232 // changed; if not, modify the face but keep all of its old
233 // attributes (apart from the vertex numbers).
235 // Create the map of faces in the master cell layer
236 const labelList& mc =
237 mesh.faceZones()[crackZoneID_.index()].masterCells();
239 labelHashSet masterCellFaceMap(6*mc.size());
241 const cellList& cells = mesh.cells();
245 const labelList& curFaces = cells[mc[cellI]];
247 forAll (curFaces, faceI)
249 // Check if the face belongs to the master patch; if not add it
250 if (zoneMesh.whichZone(curFaces[faceI]) != crackZoneID_.index())
252 masterCellFaceMap.insert(curFaces[faceI]);
257 // Extend the map to include first neighbours of the master cells to
258 // deal with multiple corners.
259 { // Protection and memory management
260 // Make a map of master cells for quick reject
261 labelHashSet mcMap(2*mc.size());
265 mcMap.insert(mc[mcI]);
268 // Go through all the faces in the masterCellFaceMap. If the
269 // cells around them are not already used, add all of their
271 const labelList mcf = masterCellFaceMap.toc();
276 const label ownCell = own[mcf[mcfI]];
278 if (!mcMap.found(ownCell))
280 // Cell not found. Add its faces to the map
281 const cell& curFaces = cells[ownCell];
283 forAll (curFaces, faceI)
285 masterCellFaceMap.insert(curFaces[faceI]);
289 // Do the neighbour side if face is internal
290 if (mesh.isInternalFace(mcf[mcfI]))
292 const label neiCell = nei[mcf[mcfI]];
294 if (!mcMap.found(neiCell))
296 // Cell not found. Add its faces to the map
297 const cell& curFaces = cells[neiCell];
299 forAll (curFaces, faceI)
301 masterCellFaceMap.insert(curFaces[faceI]);
308 // Create the master layer point map
309 Map<label> masterLayerPointMap(2*mp.size());
313 masterLayerPointMap.insert
320 // Grab the list of faces of the master layer
321 const labelList masterCellFaces = masterCellFaceMap.toc();
323 forAll (masterCellFaces, faceI)
325 // Attempt to renumber the face using the masterLayerPointMap.
326 // Missing point remain the same
328 const label curFaceID = masterCellFaces[faceI];
330 const face& oldFace = faces[curFaceID];
332 face newFace(oldFace.size());
334 bool changed = false;
336 forAll (oldFace, pointI)
338 if (masterLayerPointMap.found(oldFace[pointI]))
342 newFace[pointI] = masterLayerPointMap.find(oldFace[pointI])();
346 newFace[pointI] = oldFace[pointI];
350 // If the face has changed, create a modification entry
353 if (mesh.isInternalFace(curFaceID))
360 curFaceID, // master face
361 own[curFaceID], // owner
362 nei[curFaceID], // neighbour
364 -1, // patch for face
365 false, // remove from zone
367 false // face zone flip
378 curFaceID, // master face
379 own[curFaceID], // owner
382 mesh.boundaryMesh().whichPatch(curFaceID), // patch
383 false, // remove from zone
385 false // face zone flip
392 // Break coupled (processor) faces
393 forAll (coupledFacesToBreak_, faceI)
395 const label& curFaceID = coupledFacesToBreak_[faceI];
401 faces[curFaceID], // face
402 curFaceID, // master face
403 own[curFaceID], // owner
406 crackPatchID_.index(), // patch
407 false, // remove from zone
409 false // face zone flip
414 // Clear the faces to open list
415 coupledFacesToBreak_.setSize(0);
419 Pout<< "void faceCracker::detachFaceCracker("
420 << "polyTopoChange& ref) const "
421 << " for object " << name() << " : "
422 << "Finished detaching faces" << endl;
427 // ************************************************************************* //