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).
237 // Create the map of faces in the master cell layer
238 const labelList& mc =
239 mesh.faceZones()[crackZoneID_.index()].masterCells();
241 labelHashSet masterCellFaceMap(6*mc.size());
243 const cellList& cells = mesh.cells();
247 const labelList& curFaces = cells[mc[cellI]];
249 forAll (curFaces, faceI)
251 // Check if the face belongs to the master patch; if not add it
252 if (zoneMesh.whichZone(curFaces[faceI]) != crackZoneID_.index())
254 masterCellFaceMap.insert(curFaces[faceI]);
259 // Extend the map to include first neighbours of the master cells to
260 // deal with multiple corners.
261 { // Protection and memory management
262 // Make a map of master cells for quick reject
263 labelHashSet mcMap(2*mc.size());
267 mcMap.insert(mc[mcI]);
270 // Go through all the faces in the masterCellFaceMap. If the
271 // cells around them are not already used, add all of their
273 const labelList mcf = masterCellFaceMap.toc();
278 const label ownCell = own[mcf[mcfI]];
280 if (!mcMap.found(ownCell))
282 // Cell not found. Add its faces to the map
283 const cell& curFaces = cells[ownCell];
285 forAll (curFaces, faceI)
287 masterCellFaceMap.insert(curFaces[faceI]);
289 //----------------extra loops--------------------------//
290 // philipc 1/Sep/13: add other faces of adjacent cell
291 const label otherFaceI = curFaces[faceI];
292 const label otherOwnCell = own[otherFaceI];
293 if (!mcMap.found(otherOwnCell))
295 // Cell not found. Add its faces to the map
296 const cell& curOtherFaces = cells[otherOwnCell];
297 forAll (curOtherFaces, oFaceI)
299 masterCellFaceMap.insert(curOtherFaces[oFaceI]);
303 // Do the neighbour side if face is internal
304 if (mesh.isInternalFace(otherFaceI))
306 const label otherNeiCell = nei[otherFaceI];
308 if (!mcMap.found(otherNeiCell))
310 // Cell not found. Add its faces to the map
311 const cell& curOtherFaces = cells[otherNeiCell];
313 forAll (curOtherFaces, oFaceI)
315 masterCellFaceMap.insert(curOtherFaces[oFaceI]);
319 //----------------end of extra loops-------------------//
323 // Do the neighbour side if face is internal
324 if (mesh.isInternalFace(mcf[mcfI]))
326 const label neiCell = nei[mcf[mcfI]];
328 if (!mcMap.found(neiCell))
330 // Cell not found. Add its faces to the map
331 const cell& curFaces = cells[neiCell];
333 forAll (curFaces, faceI)
335 masterCellFaceMap.insert(curFaces[faceI]);
337 //----------------extra loops--------------------------//
338 // philipc 1/Sep/13: add other faces of adjacent cell
339 const label otherFaceI = curFaces[faceI];
340 const label otherOwnCell = own[otherFaceI];
341 if (!mcMap.found(otherOwnCell))
343 // Cell not found. Add its faces to the map
344 const cell& curOtherFaces = cells[otherOwnCell];
345 forAll (curOtherFaces, oFaceI)
347 masterCellFaceMap.insert(curOtherFaces[oFaceI]);
351 // Do the neighbour side if face is internal
352 if (mesh.isInternalFace(otherFaceI))
354 const label otherNeiCell = nei[otherFaceI];
356 if (!mcMap.found(otherNeiCell))
358 // Cell not found. Add its faces to the map
359 const cell& curOtherFaces = cells[otherNeiCell];
361 forAll (curOtherFaces, oFaceI)
363 masterCellFaceMap.insert(curOtherFaces[oFaceI]);
367 //----------------end of extra loops-------------------//
375 // Extend the map to include first neighbours of the master cells to
376 // deal with multiple corners.
377 // Bug-fix: PC, HJ and ZT, 19 Feb 2013
378 // Add corner-neighbour faces
381 // const labelListList& pointEdges = mesh.pointEdges();
382 // const labelListList& faceEdges = mesh.faceEdges();
383 // const labelListList& edgeCells = mesh.edgeCells();
387 // const labelList& curMasterFacePoints = faces[mf[faceI]];
388 // const labelList& curMasterFaceEdges = faceEdges[mf[faceI]];
389 // const labelList& curMasterCellEdges = faceEdges[mc[faceI]];
391 // labelHashSet masterCellEdges;
393 // forAll(curMasterFacePoints, pointI)
395 // const labelList& curPointEdges =
396 // pointEdges[curMasterFacePoints[pointI]];
398 // forAll(curPointEdges, edgeI)
400 // bool belongToMasterCell = false;
402 // forAll(curMasterCellEdges, eI)
404 // if (curMasterCellEdges[eI] == curPointEdges[edgeI])
406 // belongToMasterCell = true;
411 // if (belongToMasterCell)
413 // bool belongToMasterFace = false;
415 // forAll(curMasterFaceEdges, eI)
417 // if (curMasterFaceEdges[eI] == curPointEdges[edgeI])
419 // belongToMasterFace = true;
424 // if (!belongToMasterFace)
426 // masterCellEdges.insert(curPointEdges[edgeI]);
432 // labelList mcEdges = masterCellEdges.toc();
434 // labelHashSet masterCellCells;
436 // forAll(mcEdges, edgeI)
438 // const labelList& curEdgeCells = edgeCells[mcEdges[edgeI]];
440 // forAll(curEdgeCells, cellI)
442 // if (curEdgeCells[cellI] != mc[faceI])
444 // if (!masterCellCells.found(curEdgeCells[cellI]))
446 // masterCellCells.insert(curEdgeCells[cellI]);
452 // labelList mcCells = masterCellCells.toc();
453 // Info << "mcCells " << mcCells << endl;
455 // forAll(mcCells, cellI)
457 // const labelList& curFaces = cells[mcCells[cellI]];
459 // forAll (curFaces, faceI)
461 // masterCellFaceMap.insert(curFaces[faceI]);
467 // Create the master layer point map
468 Map<label> masterLayerPointMap(2*mp.size());
472 masterLayerPointMap.insert
479 // Grab the list of faces of the master layer
480 const labelList masterCellFaces = masterCellFaceMap.toc();
482 forAll (masterCellFaces, faceI)
484 // Attempt to renumber the face using the masterLayerPointMap.
485 // Missing point remain the same
487 const label curFaceID = masterCellFaces[faceI];
489 const face& oldFace = faces[curFaceID];
491 face newFace(oldFace.size());
493 bool changed = false;
495 forAll (oldFace, pointI)
497 if (masterLayerPointMap.found(oldFace[pointI]))
501 newFace[pointI] = masterLayerPointMap.find(oldFace[pointI])();
505 newFace[pointI] = oldFace[pointI];
509 // If the face has changed, create a modification entry
512 if (mesh.isInternalFace(curFaceID))
519 curFaceID, // master face
520 own[curFaceID], // owner
521 nei[curFaceID], // neighbour
523 -1, // patch for face
524 false, // remove from zone
526 false // face zone flip
537 curFaceID, // master face
538 own[curFaceID], // owner
541 mesh.boundaryMesh().whichPatch(curFaceID), // patch
542 false, // remove from zone
544 false // face zone flip
551 // Break coupled (processor) faces
552 forAll (coupledFacesToBreak_, faceI)
554 const label& curFaceID = coupledFacesToBreak_[faceI];
560 faces[curFaceID], // face
561 curFaceID, // master face
562 own[curFaceID], // owner
565 crackPatchID_.index(), // patch
566 false, // remove from zone
568 false // face zone flip
573 // Clear the faces to open list
574 coupledFacesToBreak_.setSize(0);
578 Pout<< "void faceCracker::detachFaceCracker("
579 << "polyTopoChange& ref) const "
580 << " for object " << name() << " : "
581 << "Finished detaching faces" << endl;
586 // ************************************************************************* //