Bugfix: Cumulative bug fixes for SP Windows and Misc. Author: Inno Gatin and Hrvoje...
[foam-extend-3.2.git] / src / solidModels / arbitraryCrack / faceCracker / detachFaceCracker.C
blobd4d0b8ada0d33d11f5c142e028df573c1a292bc0
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     }
100 // Pout << "addedPoints before point creation: " << addedPoints << endl;
102     // Create new points for face zone
103     forAll (addedPoints, pointI)
104     {
105         if (addedPoints[pointI] < 0)
106         {
107             addedPoints[pointI] =
108                 ref.setAction
109                 (
110                     polyAddPoint
111                     (
112                         points[mp[pointI]],        // point
113                         mp[pointI],                // master point
114                         -1,                        // zone ID
115                         true                       // supports a cell
116                     )
117                 );
118         }
119     }
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();
131     forAll (mf, faceI)
132     {
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)
141         {
142             newFace[pointI] = addedPoints[oldFace[pointI]];
143         }
145         if (mfFlip[faceI])
146         {
147             // Face needs to be flipped for the master patch
148             ref.setAction
149             (
150                 polyModifyFace
151                 (
152                     faces[curFaceID].reverseFace(), // modified face
153                     curFaceID,                  // label of face being modified
154                     nei[curFaceID],                 // owner
155                     -1,                             // neighbour
156                     true,                           // face flip
157                     crackPatchID_.index(),          // patch for face
158                     false,                          // remove from zone
159                     crackZoneID_.index(),           // zone for face
160                     !mfFlip[faceI]                  // face flip in zone
161                 )
162             );
164             // Add renumbered face into the slave patch
165             ref.setAction
166             (
167                 polyAddFace
168                 (
169                     newFace,                        // face
170                     own[curFaceID],                 // owner
171                     -1,                             // neighbour
172                     -1,                             // master point
173                     -1,                             // master edge
174                     curFaceID,                      // master face
175                     false,                          // flip flux
176                     crackPatchID_.index(),          // patch to add the face to
177                     -1,                             // zone for face
178                     false                           // zone flip
179                 )
180             );
181         }
182         else
183         {
184             // No flip
185             ref.setAction
186             (
187                 polyModifyFace
188                 (
189                     faces[curFaceID],         // modified face
190                     curFaceID,                // label of face being modified
191                     own[curFaceID],           // owner
192                     -1,                       // neighbour
193                     false,                    // face flip
194                     crackPatchID_.index(),    // patch for face
195                     false,                    // remove from zone
196                     crackZoneID_.index(),     // zone for face
197                     mfFlip[faceI]             // face flip in zone
198                 )
199             );
201             // Add renumbered face into the slave patch
202             ref.setAction
203             (
204                 polyAddFace
205                 (
206                     newFace,                        // face
207                     nei[curFaceID],                 // owner
208                     -1,                             // neighbour
209                     -1,                             // master point
210                     -1,                             // master edge
211                     curFaceID,                      // master face
212                     true,                           // flip flux
213                     crackPatchID_.index(),          // patch to add the face to
214                     -1,                             // zone for face
215                     false                           // face flip in zone
216                 )
217             );
218         }
219     }
221     // Modify the remaining faces of the master cells to reconnect to the new
222     // layer of faces.
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();
245     forAll (mc, cellI)
246     {
247         const labelList& curFaces = cells[mc[cellI]];
249         forAll (curFaces, faceI)
250         {
251             // Check if the face belongs to the master patch; if not add it
252             if (zoneMesh.whichZone(curFaces[faceI]) != crackZoneID_.index())
253             {
254                 masterCellFaceMap.insert(curFaces[faceI]);
255             }
256         }
257     }
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());
265         forAll (mc, mcI)
266         {
267             mcMap.insert(mc[mcI]);
268         }
270         // Go through all the faces in the masterCellFaceMap.  If the
271         // cells around them are not already used, add all of their
272         // faces to the map
273         const labelList mcf = masterCellFaceMap.toc();
275         forAll (mcf, mcfI)
276         {
277             // Do the owner side
278             const label ownCell = own[mcf[mcfI]];
280             if (!mcMap.found(ownCell))
281             {
282                 // Cell not found. Add its faces to the map
283                 const cell& curFaces = cells[ownCell];
285                 forAll (curFaces, faceI)
286                 {
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))
294             {
295               // Cell not found. Add its faces to the map
296               const cell& curOtherFaces = cells[otherOwnCell];
297               forAll (curOtherFaces, oFaceI)
298             {
299               masterCellFaceMap.insert(curOtherFaces[oFaceI]);
300             }
301             }
303           // Do the neighbour side if face is internal
304           if (mesh.isInternalFace(otherFaceI))
305             {
306               const label otherNeiCell = nei[otherFaceI];
308               if (!mcMap.found(otherNeiCell))
309             {
310               // Cell not found. Add its faces to the map
311               const cell& curOtherFaces = cells[otherNeiCell];
313               forAll (curOtherFaces, oFaceI)
314                 {
315                   masterCellFaceMap.insert(curOtherFaces[oFaceI]);
316                 }
317             }
318             }
319           //----------------end of extra loops-------------------//
320                 }
321             }
323             // Do the neighbour side if face is internal
324             if (mesh.isInternalFace(mcf[mcfI]))
325             {
326                 const label neiCell = nei[mcf[mcfI]];
328                 if (!mcMap.found(neiCell))
329                 {
330                     // Cell not found. Add its faces to the map
331                     const cell& curFaces = cells[neiCell];
333                     forAll (curFaces, faceI)
334                     {
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))
342             {
343               // Cell not found. Add its faces to the map
344               const cell& curOtherFaces = cells[otherOwnCell];
345               forAll (curOtherFaces, oFaceI)
346                 {
347                   masterCellFaceMap.insert(curOtherFaces[oFaceI]);
348                 }
349             }
351               // Do the neighbour side if face is internal
352               if (mesh.isInternalFace(otherFaceI))
353             {
354               const label otherNeiCell = nei[otherFaceI];
356               if (!mcMap.found(otherNeiCell))
357                 {
358                   // Cell not found. Add its faces to the map
359                   const cell& curOtherFaces = cells[otherNeiCell];
361                   forAll (curOtherFaces, oFaceI)
362                 {
363                   masterCellFaceMap.insert(curOtherFaces[oFaceI]);
364                 }
365                 }
366             }
367               //----------------end of extra loops-------------------//
368                     }
369                 }
370             }
371         }
372     }
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
379     // NOT WORKKING
381     // const labelListList& pointEdges = mesh.pointEdges();
382     // const labelListList& faceEdges = mesh.faceEdges();
383     // const labelListList& edgeCells = mesh.edgeCells();
385     // forAll(mf, faceI)
386     // {
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)
394     //     {
395     //         const labelList& curPointEdges =
396     //             pointEdges[curMasterFacePoints[pointI]];
398     //         forAll(curPointEdges, edgeI)
399     //         {
400     //             bool belongToMasterCell = false;
402     //             forAll(curMasterCellEdges, eI)
403     //             {
404     //                 if (curMasterCellEdges[eI] == curPointEdges[edgeI])
405     //                 {
406     //                     belongToMasterCell = true;
407     //                     break;
408     //                 }
409     //             }
411     //             if (belongToMasterCell)
412     //             {
413     //                 bool belongToMasterFace = false;
415     //                 forAll(curMasterFaceEdges, eI)
416     //                 {
417     //                     if (curMasterFaceEdges[eI] == curPointEdges[edgeI])
418     //                     {
419     //                         belongToMasterFace = true;
420     //                         break;
421     //                     }
422     //                 }
424     //                 if (!belongToMasterFace)
425     //                 {
426     //                     masterCellEdges.insert(curPointEdges[edgeI]);
427     //                 }
428     //             }
429     //         }
430     //     }
432     //     labelList mcEdges = masterCellEdges.toc();
434     //     labelHashSet masterCellCells;
436     //     forAll(mcEdges, edgeI)
437     //     {
438     //         const labelList& curEdgeCells = edgeCells[mcEdges[edgeI]];
440     //         forAll(curEdgeCells, cellI)
441     //         {
442     //             if (curEdgeCells[cellI] != mc[faceI])
443     //             {
444     //                 if (!masterCellCells.found(curEdgeCells[cellI]))
445     //                 {
446     //                     masterCellCells.insert(curEdgeCells[cellI]);
447     //                 }
448     //             }
449     //         }
450     //     }
452     //     labelList mcCells = masterCellCells.toc();
453     //     Info << "mcCells " << mcCells << endl;
455     //     forAll(mcCells, cellI)
456     //     {
457     //         const labelList& curFaces = cells[mcCells[cellI]];
459     //         forAll (curFaces, faceI)
460     //         {
461     //             masterCellFaceMap.insert(curFaces[faceI]);
462     //         }
463     //     }
464     // }
467     // Create the master layer point map
468     Map<label> masterLayerPointMap(2*mp.size());
470     forAll (mp, pointI)
471     {
472         masterLayerPointMap.insert
473         (
474             mp[pointI],
475             addedPoints[pointI]
476         );
477     }
479     // Grab the list of faces of the master layer
480     const labelList masterCellFaces = masterCellFaceMap.toc();
482     forAll (masterCellFaces, faceI)
483     {
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)
496         {
497             if (masterLayerPointMap.found(oldFace[pointI]))
498             {
499                 changed = true;
501                 newFace[pointI] = masterLayerPointMap.find(oldFace[pointI])();
502             }
503             else
504             {
505                 newFace[pointI] = oldFace[pointI];
506             }
507         }
509         // If the face has changed, create a modification entry
510         if (changed)
511         {
512             if (mesh.isInternalFace(curFaceID))
513             {
514                 ref.setAction
515                 (
516                     polyModifyFace
517                     (
518                         newFace,                    // face
519                         curFaceID,                  // master face
520                         own[curFaceID],             // owner
521                         nei[curFaceID],             // neighbour
522                         false,                      // flip flux
523                         -1,                         // patch for face
524                         false,                      // remove from zone
525                         -1,                         // zone for face
526                         false                       // face zone flip
527                     )
528                 );
529             }
530             else
531             {
532                 ref.setAction
533                 (
534                     polyModifyFace
535                     (
536                         newFace,                     // face
537                         curFaceID,                   // master face
538                         own[curFaceID],              // owner
539                         -1,                          // neighbour
540                         false,                       // flip flux
541                         mesh.boundaryMesh().whichPatch(curFaceID), // patch
542                         false,                        // remove from zone
543                         -1,                           // zone for face
544                         false                         // face zone flip
545                     )
546                 );
547             }
548         }
549     }
551     // Break coupled (processor) faces
552     forAll (coupledFacesToBreak_, faceI)
553     {
554         const label& curFaceID = coupledFacesToBreak_[faceI];
556         ref.setAction
557         (
558             polyModifyFace
559             (
560                 faces[curFaceID],            // face
561                 curFaceID,                   // master face
562                 own[curFaceID],              // owner
563                 -1,                          // neighbour
564                 false,                       // flip flux
565                 crackPatchID_.index(),       // patch
566                 false,                       // remove from zone
567                 -1,                          // zone for face
568                 false                        // face zone flip
569             )
570         );
571     }
573     // Clear the faces to open list
574     coupledFacesToBreak_.setSize(0);
576     if (debug)
577     {
578         Pout<< "void faceCracker::detachFaceCracker("
579             << "polyTopoChange& ref) const "
580             << " for object " << name() << " : "
581             << "Finished detaching faces" << endl;
582     }
586 // ************************************************************************* //