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()];
101 // Create new points for face zone
102 forAll (addedPoints, pointI)
104 if (addedPoints[pointI] < 0)
106 addedPoints[pointI] =
111 points[mp[pointI]], // point
112 mp[pointI], // master point
114 true // supports a cell
120 // Modify faces in the master zone and duplicate for the slave zone
122 const labelList& mf = zoneMesh[crackZoneID_.index()];
123 const boolList& mfFlip = zoneMesh[crackZoneID_.index()].flipMap();
124 const faceList& zoneFaces = masterFaceLayer.localFaces();
126 const faceList& faces = mesh.faces();
127 const labelList& own = mesh.faceOwner();
128 const labelList& nei = mesh.faceNeighbour();
132 const label curFaceID = mf[faceI];
134 // Build the face for the slave patch by renumbering
135 const face oldFace = zoneFaces[faceI].reverseFace();
137 face newFace(oldFace.size());
139 forAll (oldFace, pointI)
141 newFace[pointI] = addedPoints[oldFace[pointI]];
146 // Face needs to be flipped for the master patch
151 faces[curFaceID].reverseFace(), // modified face
152 curFaceID, // label of face being modified
153 nei[curFaceID], // owner
156 crackPatchID_.index(), // patch for face
157 false, // remove from zone
158 crackZoneID_.index(), // zone for face
159 !mfFlip[faceI] // face flip in zone
163 // Add renumbered face into the slave patch
169 own[curFaceID], // owner
173 curFaceID, // master face
175 crackPatchID_.index(), // patch to add the face to
188 faces[curFaceID], // modified face
189 curFaceID, // label of face being modified
190 own[curFaceID], // owner
193 crackPatchID_.index(), // patch for face
194 false, // remove from zone
195 crackZoneID_.index(), // zone for face
196 mfFlip[faceI] // face flip in zone
200 // Add renumbered face into the slave patch
206 nei[curFaceID], // owner
210 curFaceID, // master face
212 crackPatchID_.index(), // patch to add the face to
214 false // face flip in zone
220 // Modify the remaining faces of the master cells to reconnect to the new
223 // Algorithm: Go through all the cells of the master zone and make
224 // a map of faces to avoid duplicates. Do not insert the faces in
225 // the master patch (as they have already been dealt with). Make
226 // a master layer point renumbering map, which for every point in
227 // the master layer gives its new label. Loop through all faces in
228 // the map and attempt to renumber them using the master layer
229 // point renumbering map. Once the face is renumbered, compare it
230 // with the original face; if they are the same, the face has not
231 // changed; if not, modify the face but keep all of its old
232 // attributes (apart from the vertex numbers).
236 // Create the map of faces in the master cell layer
237 const labelList& mc =
238 mesh.faceZones()[crackZoneID_.index()].masterCells();
240 labelHashSet masterCellFaceMap(6*mc.size());
242 const cellList& cells = mesh.cells();
246 const labelList& curFaces = cells[mc[cellI]];
248 forAll (curFaces, faceI)
250 // Check if the face belongs to the master patch; if not add it
251 if (zoneMesh.whichZone(curFaces[faceI]) != crackZoneID_.index())
253 masterCellFaceMap.insert(curFaces[faceI]);
258 // // Extend the map to include first neighbours of the master cells to
259 // // deal with multiple corners.
260 // { // Protection and memory management
261 // // Make a map of master cells for quick reject
262 // labelHashSet mcMap(2*mc.size());
266 // mcMap.insert(mc[mcI]);
269 // // Go through all the faces in the masterCellFaceMap. If the
270 // // cells around them are not already used, add all of their
271 // // faces to the map
272 // const labelList mcf = masterCellFaceMap.toc();
274 // forAll (mcf, mcfI)
276 // // Do the owner side
277 // const label ownCell = own[mcf[mcfI]];
279 // if (!mcMap.found(ownCell))
281 // // Cell not found. Add its faces to the map
282 // const cell& curFaces = cells[ownCell];
284 // forAll (curFaces, faceI)
286 // masterCellFaceMap.insert(curFaces[faceI]);
290 // // Do the neighbour side if face is internal
291 // if (mesh.isInternalFace(mcf[mcfI]))
293 // const label neiCell = nei[mcf[mcfI]];
295 // if (!mcMap.found(neiCell))
297 // // Cell not found. Add its faces to the map
298 // const cell& curFaces = cells[neiCell];
300 // forAll (curFaces, faceI)
302 // masterCellFaceMap.insert(curFaces[faceI]);
310 // Extend the map to include first neighbours of the master cells to
311 // deal with multiple corners.
312 // Bug-fix: PC, HJ and ZT, 19 Feb 2013
313 // Add corner-neighbour faces
315 const labelListList& pointEdges = mesh.pointEdges();
316 const labelListList& faceEdges = mesh.faceEdges();
317 const labelListList& edgeCells = mesh.edgeCells();
321 const labelList& curMasterFacePoints = faces[mf[faceI]];
322 const labelList& curMasterFaceEdges = faceEdges[mf[faceI]];
323 const labelList& curMasterCellEdges = faceEdges[mc[faceI]];
325 labelHashSet masterCellEdges;
327 forAll(curMasterFacePoints, pointI)
329 const labelList& curPointEdges =
330 pointEdges[curMasterFacePoints[pointI]];
332 forAll(curPointEdges, edgeI)
334 bool belongToMasterCell = false;
336 forAll(curMasterCellEdges, eI)
338 if (curMasterCellEdges[eI] == curPointEdges[edgeI])
340 belongToMasterCell = true;
345 if (belongToMasterCell)
347 bool belongToMasterFace = false;
349 forAll(curMasterFaceEdges, eI)
351 if (curMasterFaceEdges[eI] == curPointEdges[edgeI])
353 belongToMasterFace = true;
358 if (!belongToMasterFace)
360 masterCellEdges.insert(curPointEdges[edgeI]);
366 labelList mcEdges = masterCellEdges.toc();
368 labelHashSet masterCellCells;
370 forAll(mcEdges, edgeI)
372 const labelList& curEdgeCells = edgeCells[mcEdges[edgeI]];
374 forAll(curEdgeCells, cellI)
376 if (curEdgeCells[cellI] != mc[faceI])
378 if (!masterCellCells.found(curEdgeCells[cellI]))
380 masterCellCells.insert(curEdgeCells[cellI]);
386 labelList mcCells = masterCellCells.toc();
388 forAll(mcCells, cellI)
390 const labelList& curFaces = cells[mcCells[cellI]];
392 forAll (curFaces, faceI)
394 masterCellFaceMap.insert(curFaces[faceI]);
400 // Create the master layer point map
401 Map<label> masterLayerPointMap(2*mp.size());
405 masterLayerPointMap.insert
412 // Grab the list of faces of the master layer
413 const labelList masterCellFaces = masterCellFaceMap.toc();
415 forAll (masterCellFaces, faceI)
417 // Attempt to renumber the face using the masterLayerPointMap.
418 // Missing point remain the same
420 const label curFaceID = masterCellFaces[faceI];
422 const face& oldFace = faces[curFaceID];
424 face newFace(oldFace.size());
426 bool changed = false;
428 forAll (oldFace, pointI)
430 if (masterLayerPointMap.found(oldFace[pointI]))
434 newFace[pointI] = masterLayerPointMap.find(oldFace[pointI])();
438 newFace[pointI] = oldFace[pointI];
442 // If the face has changed, create a modification entry
445 if (mesh.isInternalFace(curFaceID))
452 curFaceID, // master face
453 own[curFaceID], // owner
454 nei[curFaceID], // neighbour
456 -1, // patch for face
457 false, // remove from zone
459 false // face zone flip
470 curFaceID, // master face
471 own[curFaceID], // owner
474 mesh.boundaryMesh().whichPatch(curFaceID), // patch
475 false, // remove from zone
477 false // face zone flip
484 // Break coupled (processor) faces
485 forAll (coupledFacesToBreak_, faceI)
487 const label& curFaceID = coupledFacesToBreak_[faceI];
493 faces[curFaceID], // face
494 curFaceID, // master face
495 own[curFaceID], // owner
498 crackPatchID_.index(), // patch
499 false, // remove from zone
501 false // face zone flip
506 // Clear the faces to open list
507 coupledFacesToBreak_.setSize(0);
511 Pout<< "void faceCracker::detachFaceCracker("
512 << "polyTopoChange& ref) const "
513 << " for object " << name() << " : "
514 << "Finished detaching faces" << endl;
519 // ************************************************************************* //