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).
235 // Create the map of faces in the master cell layer
236 // Bug-fix: PC, HJ and ZT, 19 Feb 2013
238 labelHashSet masterCellFaceMap(12*mf.size());
240 const labelListList& pointFaces = mesh.pointFaces();
244 const labelList& curFacePoints = faces[mf[faceI]];
246 forAll(curFacePoints, pointI)
248 const labelList& curPointFaces =
249 pointFaces[curFacePoints[pointI]];
251 forAll(curPointFaces, fI)
255 zoneMesh.whichZone(curPointFaces[fI])
256 != crackZoneID_.index()
259 masterCellFaceMap.insert(curPointFaces[fI]);
266 // // Create the map of faces in the master cell layer
267 // const labelList& mc =
268 // mesh.faceZones()[crackZoneID_.index()].masterCells();
270 // labelHashSet masterCellFaceMap(6*mc.size());
272 // const cellList& cells = mesh.cells();
274 // forAll (mc, cellI)
276 // const labelList& curFaces = cells[mc[cellI]];
278 // forAll (curFaces, faceI)
280 // // Check if the face belongs to the master patch; if not add it
281 // if (zoneMesh.whichZone(curFaces[faceI]) != crackZoneID_.index())
283 // masterCellFaceMap.insert(curFaces[faceI]);
288 // // Extend the map to include first neighbours of the master cells to
289 // // deal with multiple corners.
290 // { // Protection and memory management
291 // // Make a map of master cells for quick reject
292 // labelHashSet mcMap(2*mc.size());
296 // mcMap.insert(mc[mcI]);
299 // // Go through all the faces in the masterCellFaceMap. If the
300 // // cells around them are not already used, add all of their
301 // // faces to the map
302 // const labelList mcf = masterCellFaceMap.toc();
304 // forAll (mcf, mcfI)
306 // // Do the owner side
307 // const label ownCell = own[mcf[mcfI]];
309 // if (!mcMap.found(ownCell))
311 // // Cell not found. Add its faces to the map
312 // const cell& curFaces = cells[ownCell];
314 // forAll (curFaces, faceI)
316 // masterCellFaceMap.insert(curFaces[faceI]);
320 // // Do the neighbour side if face is internal
321 // if (mesh.isInternalFace(mcf[mcfI]))
323 // const label neiCell = nei[mcf[mcfI]];
325 // if (!mcMap.found(neiCell))
327 // // Cell not found. Add its faces to the map
328 // const cell& curFaces = cells[neiCell];
330 // forAll (curFaces, faceI)
332 // masterCellFaceMap.insert(curFaces[faceI]);
339 // Create the master layer point map
340 Map<label> masterLayerPointMap(2*mp.size());
344 masterLayerPointMap.insert
351 // Grab the list of faces of the master layer
352 const labelList masterCellFaces = masterCellFaceMap.toc();
354 forAll (masterCellFaces, faceI)
356 // Attempt to renumber the face using the masterLayerPointMap.
357 // Missing point remain the same
359 const label curFaceID = masterCellFaces[faceI];
361 const face& oldFace = faces[curFaceID];
363 face newFace(oldFace.size());
365 bool changed = false;
367 forAll (oldFace, pointI)
369 if (masterLayerPointMap.found(oldFace[pointI]))
373 newFace[pointI] = masterLayerPointMap.find(oldFace[pointI])();
377 newFace[pointI] = oldFace[pointI];
381 // If the face has changed, create a modification entry
384 if (mesh.isInternalFace(curFaceID))
391 curFaceID, // master face
392 own[curFaceID], // owner
393 nei[curFaceID], // neighbour
395 -1, // patch for face
396 false, // remove from zone
398 false // face zone flip
409 curFaceID, // master face
410 own[curFaceID], // owner
413 mesh.boundaryMesh().whichPatch(curFaceID), // patch
414 false, // remove from zone
416 false // face zone flip
423 // Break coupled (processor) faces
424 forAll (coupledFacesToBreak_, faceI)
426 const label& curFaceID = coupledFacesToBreak_[faceI];
432 faces[curFaceID], // face
433 curFaceID, // master face
434 own[curFaceID], // owner
437 crackPatchID_.index(), // patch
438 false, // remove from zone
440 false // face zone flip
445 // Clear the faces to open list
446 coupledFacesToBreak_.setSize(0);
450 Pout<< "void faceCracker::detachFaceCracker("
451 << "polyTopoChange& ref) const "
452 << " for object " << name() << " : "
453 << "Finished detaching faces" << endl;
458 // ************************************************************************* //