Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / solidModels / arbitraryCrack / faceCracker / detachFaceCracker_secondFixNotRight.C
blob81458a7ec8ae4ab47aa82355c29eee9b80d731f3
1 /*---------------------------------------------------------------------------*\
2   =========                 |
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 -------------------------------------------------------------------------------
8 License
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"
27 #include "polyMesh.H"
28 #include "primitiveMesh.H"
29 #include "polyTopoChange.H"
30 #include "polyTopoChanger.H"
32 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
34 void Foam::faceCracker::detachFaceCracker
36     polyTopoChange& ref
37 ) const
39     if (debug)
40     {
41         Pout<< "void faceCracker::detachFaceCracker("
42             << "polyTopoChange& ref) const "
43             << " for object " << name() << " : "
44             << "Detaching faces" << endl;
45     }
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();
60     // Create the points
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();
69     for
70     (
71         label curEdgeID = nIntEdges;
72         curEdgeID < meshEdges.size();
73         curEdgeID++
74     )
75     {
76         const labelList& curFaces = meshEdgeFaces[meshEdges[curEdgeID]];
78         bool edgeIsInternal = true;
80         forAll (curFaces, faceI)
81         {
82             if (!mesh.isInternalFace(curFaces[faceI]))
83             {
84                 // The edge belongs to a boundary face
85                 edgeIsInternal = false;
86                 break;
87             }
88         }
90         if (edgeIsInternal)
91         {
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()];
98         }
99     }
101     // Create new points for face zone
102     forAll (addedPoints, pointI)
103     {
104         if (addedPoints[pointI] < 0)
105         {
106             addedPoints[pointI] =
107                 ref.setAction
108                 (
109                     polyAddPoint
110                     (
111                         points[mp[pointI]],        // point
112                         mp[pointI],                // master point
113                         -1,                        // zone ID
114                         true                       // supports a cell
115                     )
116                 );
117         }
118     }
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();
130     forAll (mf, faceI)
131     {
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)
140         {
141             newFace[pointI] = addedPoints[oldFace[pointI]];
142         }
144         if (mfFlip[faceI])
145         {
146             // Face needs to be flipped for the master patch
147             ref.setAction
148             (
149                 polyModifyFace
150                 (
151                     faces[curFaceID].reverseFace(), // modified face
152                     curFaceID,                  // label of face being modified
153                     nei[curFaceID],                 // owner
154                     -1,                             // neighbour
155                     true,                           // face flip
156                     crackPatchID_.index(),          // patch for face
157                     false,                          // remove from zone
158                     crackZoneID_.index(),           // zone for face
159                     !mfFlip[faceI]                  // face flip in zone
160                 )
161             );
163             // Add renumbered face into the slave patch
164             ref.setAction
165             (
166                 polyAddFace
167                 (
168                     newFace,                        // face
169                     own[curFaceID],                 // owner
170                     -1,                             // neighbour
171                     -1,                             // master point
172                     -1,                             // master edge
173                     curFaceID,                      // master face
174                     false,                          // flip flux
175                     crackPatchID_.index(),          // patch to add the face to
176                     -1,                             // zone for face
177                     false                           // zone flip
178                 )
179             );
180         }
181         else
182         {
183             // No flip
184             ref.setAction
185             (
186                 polyModifyFace
187                 (
188                     faces[curFaceID],         // modified face
189                     curFaceID,                // label of face being modified
190                     own[curFaceID],           // owner
191                     -1,                       // neighbour
192                     false,                    // face flip
193                     crackPatchID_.index(),    // patch for face
194                     false,                    // remove from zone
195                     crackZoneID_.index(),     // zone for face
196                     mfFlip[faceI]             // face flip in zone
197                 )
198             );
200             // Add renumbered face into the slave patch
201             ref.setAction
202             (
203                 polyAddFace
204                 (
205                     newFace,                        // face
206                     nei[curFaceID],                 // owner
207                     -1,                             // neighbour
208                     -1,                             // master point
209                     -1,                             // master edge
210                     curFaceID,                      // master face
211                     true,                           // flip flux
212                     crackPatchID_.index(),          // patch to add the face to
213                     -1,                             // zone for face
214                     false                           // face flip in zone
215                 )
216             );
217         }
218     }
220     // Modify the remaining faces of the master cells to reconnect to the new
221     // layer of faces.
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();
244     forAll (mc, cellI)
245     {
246         const labelList& curFaces = cells[mc[cellI]];
248         forAll (curFaces, faceI)
249         {
250             // Check if the face belongs to the master patch; if not add it
251             if (zoneMesh.whichZone(curFaces[faceI]) != crackZoneID_.index())
252             {
253                 masterCellFaceMap.insert(curFaces[faceI]);
254             }
255         }
256     }
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());
264 //         forAll (mc, mcI)
265 //         {
266 //             mcMap.insert(mc[mcI]);
267 //         }
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)
275 //         {
276 //             // Do the owner side
277 //             const label ownCell = own[mcf[mcfI]];
279 //             if (!mcMap.found(ownCell))
280 //             {
281 //                 // Cell not found. Add its faces to the map
282 //                 const cell& curFaces = cells[ownCell];
284 //                 forAll (curFaces, faceI)
285 //                 {
286 //                     masterCellFaceMap.insert(curFaces[faceI]);
287 //                 }
288 //             }
290 //             // Do the neighbour side if face is internal
291 //             if (mesh.isInternalFace(mcf[mcfI]))
292 //             {
293 //                 const label neiCell = nei[mcf[mcfI]];
295 //                 if (!mcMap.found(neiCell))
296 //                 {
297 //                     // Cell not found. Add its faces to the map
298 //                     const cell& curFaces = cells[neiCell];
300 //                     forAll (curFaces, faceI)
301 //                     {
302 //                         masterCellFaceMap.insert(curFaces[faceI]);
303 //                     }
304 //                 }
305 //             }
306 //         }
307 //     }
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();
319     forAll(mf, faceI)
320     {
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)
328         {
329             const labelList& curPointEdges =
330                 pointEdges[curMasterFacePoints[pointI]];
332             forAll(curPointEdges, edgeI)
333             {
334                 bool belongToMasterCell = false;
336                 forAll(curMasterCellEdges, eI)
337                 {
338                     if (curMasterCellEdges[eI] == curPointEdges[edgeI])
339                     {
340                         belongToMasterCell = true;
341                         break;
342                     }
343                 }
345                 if (belongToMasterCell)
346                 {
347                     bool belongToMasterFace = false;
349                     forAll(curMasterFaceEdges, eI)
350                     {
351                         if (curMasterFaceEdges[eI] == curPointEdges[edgeI])
352                         {
353                             belongToMasterFace = true;
354                             break;
355                         }
356                     }
358                     if (!belongToMasterFace)
359                     {
360                         masterCellEdges.insert(curPointEdges[edgeI]);
361                     }
362                 }
363             }
364         }
366         labelList mcEdges = masterCellEdges.toc();
368         labelHashSet masterCellCells;
370         forAll(mcEdges, edgeI)
371         {
372             const labelList& curEdgeCells = edgeCells[mcEdges[edgeI]];
374             forAll(curEdgeCells, cellI)
375             {
376                 if (curEdgeCells[cellI] != mc[faceI])
377                 {
378                     if (!masterCellCells.found(curEdgeCells[cellI]))
379                     {
380                         masterCellCells.insert(curEdgeCells[cellI]);
381                     }
382                 }
383             }
384         }
386         labelList mcCells = masterCellCells.toc();
388         forAll(mcCells, cellI)
389         {
390             const labelList& curFaces = cells[mcCells[cellI]];
392             forAll (curFaces, faceI)
393             {
394                 masterCellFaceMap.insert(curFaces[faceI]);
395             }
396         }
397     }
400     // Create the master layer point map
401     Map<label> masterLayerPointMap(2*mp.size());
403     forAll (mp, pointI)
404     {
405         masterLayerPointMap.insert
406         (
407             mp[pointI],
408             addedPoints[pointI]
409         );
410     }
412     // Grab the list of faces of the master layer
413     const labelList masterCellFaces = masterCellFaceMap.toc();
415     forAll (masterCellFaces, faceI)
416     {
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)
429         {
430             if (masterLayerPointMap.found(oldFace[pointI]))
431             {
432                 changed = true;
434                 newFace[pointI] = masterLayerPointMap.find(oldFace[pointI])();
435             }
436             else
437             {
438                 newFace[pointI] = oldFace[pointI];
439             }
440         }
442         // If the face has changed, create a modification entry
443         if (changed)
444         {
445             if (mesh.isInternalFace(curFaceID))
446             {
447                 ref.setAction
448                 (
449                     polyModifyFace
450                     (
451                         newFace,                    // face
452                         curFaceID,                  // master face
453                         own[curFaceID],             // owner
454                         nei[curFaceID],             // neighbour
455                         false,                      // flip flux
456                         -1,                         // patch for face
457                         false,                      // remove from zone
458                         -1,                         // zone for face
459                         false                       // face zone flip
460                     )
461                 );
462             }
463             else
464             {
465                 ref.setAction
466                 (
467                     polyModifyFace
468                     (
469                         newFace,                     // face
470                         curFaceID,                   // master face
471                         own[curFaceID],              // owner
472                         -1,                          // neighbour
473                         false,                       // flip flux
474                         mesh.boundaryMesh().whichPatch(curFaceID), // patch
475                         false,                        // remove from zone
476                         -1,                           // zone for face
477                         false                         // face zone flip
478                     )
479                 );
480             }
481         }
482     }
484     // Break coupled (processor) faces
485     forAll (coupledFacesToBreak_, faceI)
486     {
487         const label& curFaceID = coupledFacesToBreak_[faceI];
489         ref.setAction
490         (
491             polyModifyFace
492             (
493                 faces[curFaceID],            // face
494                 curFaceID,                   // master face
495                 own[curFaceID],              // owner
496                 -1,                          // neighbour
497                 false,                       // flip flux
498                 crackPatchID_.index(),       // patch
499                 false,                       // remove from zone
500                 -1,                          // zone for face
501                 false                        // face zone flip
502             )
503         );
504     }
506     // Clear the faces to open list
507     coupledFacesToBreak_.setSize(0);
509     if (debug)
510     {
511         Pout<< "void faceCracker::detachFaceCracker("
512             << "polyTopoChange& ref) const "
513             << " for object " << name() << " : "
514             << "Finished detaching faces" << endl;
515     }
519 // ************************************************************************* //