1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "slidingInterface.H"
27 #include "polyTopoChange.H"
29 #include "primitiveMesh.H"
30 #include "enrichedPatch.H"
31 #include "DynamicList.H"
33 #include "triPointRef.H"
35 #include "polyTopoChanger.H"
36 #include "polyAddPoint.H"
37 #include "polyRemovePoint.H"
38 #include "polyAddFace.H"
39 #include "polyModifyPoint.H"
40 #include "polyModifyFace.H"
41 #include "polyRemoveFace.H"
43 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
45 const Foam::scalar Foam::slidingInterface::edgeCoPlanarTolDefault_ = 0.8;
47 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
49 // Index of debug signs:
50 // Index of debug signs:
51 // . - loop of the edge-to-face interaction detection
52 // x - reversal of direction in edge-to-face interaction detection
53 // + - complete edge-to-face interaction detection
54 // z - incomplete edge-to-face interaction detection. This may be OK for edges
55 // crossing from one to the other side of multiply connected master patch
57 // e - adding a point on edge
58 // f - adding a point on face
59 // . - collecting edges off another face for edge-to-edge cut
60 // + - finished collection of edges
61 // * - cut both master and slave
62 // n - cutting new edge
63 // t - intersection exists but it is outside of tolerance
64 // x - missed slave edge in cut
65 // - - missed master edge in cut
66 // u - edge already used in cutting
68 void Foam::slidingInterface::coupleInterface(polyTopoChange& ref) const
72 Pout<< "void slidingInterface::coupleInterface"
73 << "(polyTopoChange& ref) : "
74 << "Coupling sliding interface " << name() << endl;
77 const polyMesh& mesh = topoChanger().mesh();
79 const pointField& points = mesh.points();
80 const faceList& faces = mesh.faces();
82 const labelList& own = mesh.faceOwner();
83 const labelList& nei = mesh.faceNeighbour();
84 const faceZoneMesh& faceZones = mesh.faceZones();
86 const primitiveFacePatch& masterPatch =
87 faceZones[masterFaceZoneID_.index()]();
89 const labelList& masterPatchAddr = faceZones[masterFaceZoneID_.index()];
91 const boolList& masterPatchFlip =
92 faceZones[masterFaceZoneID_.index()].flipMap();
94 const primitiveFacePatch& slavePatch =
95 faceZones[slaveFaceZoneID_.index()]();
97 const labelList& slavePatchAddr = faceZones[slaveFaceZoneID_.index()];
99 const boolList& slavePatchFlip =
100 faceZones[slaveFaceZoneID_.index()].flipMap();
102 const edgeList& masterEdges = masterPatch.edges();
103 const labelListList& masterPointEdges = masterPatch.pointEdges();
104 const labelList& masterMeshPoints = masterPatch.meshPoints();
105 const pointField& masterLocalPoints = masterPatch.localPoints();
106 const labelListList& masterFaceFaces = masterPatch.faceFaces();
107 const labelListList& masterFaceEdges = masterPatch.faceEdges();
108 const Map<label>& masterMeshPointMap = masterPatch.meshPointMap();
110 const edgeList& slaveEdges = slavePatch.edges();
111 const labelListList& slavePointEdges = slavePatch.pointEdges();
112 const labelList& slaveMeshPoints = slavePatch.meshPoints();
113 const pointField& slaveLocalPoints = slavePatch.localPoints();
114 const Map<label>& slaveMeshPointMap = slavePatch.meshPointMap();
115 const vectorField& slavePointNormals = slavePatch.pointNormals();
117 // Collect projection addressing
121 slavePointPointHitsPtr_
122 && slavePointEdgeHitsPtr_
123 && slavePointFaceHitsPtr_
124 && masterPointEdgeHitsPtr_
130 "void slidingInterface::coupleInterface("
131 "polyTopoChange& ref) const"
132 ) << "Point projection addressing not available."
133 << abort(FatalError);
136 const labelList& slavePointPointHits = *slavePointPointHitsPtr_;
137 const labelList& slavePointEdgeHits = *slavePointEdgeHitsPtr_;
138 const List<objectHit>& slavePointFaceHits = *slavePointFaceHitsPtr_;
139 const labelList& masterPointEdgeHits = *masterPointEdgeHitsPtr_;
140 const pointField& projectedSlavePoints = *projectedSlavePointsPtr_;
142 // Create enriched patch
143 enrichedPatch cutPatch
152 // Get reference to list of added point for the enriched patch.
153 // This will be used for point addition
154 Map<point>& pointMap = cutPatch.pointMap();
156 // Get reference to the list of merged points
157 Map<label>& pointMergeMap = cutPatch.pointMergeMap();
159 // Create mapping for every merged point of the slave patch
160 forAll(slavePointPointHits, pointI)
162 if (slavePointPointHits[pointI] >= 0)
164 // Pout<< "Inserting point merge pair: " << slaveMeshPoints[pointI]
165 // << " : " << masterMeshPoints[slavePointPointHits[pointI]]
170 slaveMeshPoints[pointI],
171 masterMeshPoints[slavePointPointHits[pointI]]
176 // Collect the list of used edges for every slave edge
178 List<labelHashSet> usedMasterEdges(slaveEdges.size());
180 // Collect of slave point hits
181 forAll(slavePointPointHits, pointI)
183 // For point hits, add all point-edges from master side to all point
184 const labelList& curSlaveEdges = slavePointEdges[pointI];
186 if (slavePointPointHits[pointI] > -1)
188 const labelList& curMasterEdges =
189 masterPointEdges[slavePointPointHits[pointI]];
191 // Mark all current master edges as used for all the current slave
193 forAll(curSlaveEdges, slaveEdgeI)
195 labelHashSet& sm = usedMasterEdges[curSlaveEdges[slaveEdgeI]];
197 forAll(curMasterEdges, masterEdgeI)
199 sm.insert(curMasterEdges[masterEdgeI]);
203 else if (slavePointEdgeHits[pointI] > -1)
205 // For edge hits, add the master edge
206 forAll(curSlaveEdges, slaveEdgeI)
208 usedMasterEdges[curSlaveEdges[slaveEdgeI]].insert
210 slavePointEdgeHits[pointI]
216 // Collect off master point hits
217 // For every master point that has hit an edge, add all edges coming from
218 // that point to the slave edge that has been hit
219 forAll(masterPointEdgeHits, masterPointI)
221 if (masterPointEdgeHits[masterPointI] > -1)
223 const labelList& curMasterEdges = masterPointEdges[masterPointI];
226 usedMasterEdges[masterPointEdgeHits[masterPointI]];
228 forAll(curMasterEdges, masterEdgeI)
230 sm.insert(curMasterEdges[masterEdgeI]);
235 // Pout<< "used edges: " << endl;
236 // forAll(usedMasterEdges, edgeI)
238 // Pout<< "edge: " << edgeI
239 // << " used: " << usedMasterEdges[edgeI].toc()
243 // For every master and slave edge make a list of points to be added into
245 List<DynamicList<label> > pointsIntoMasterEdges(masterEdges.size());
246 List<DynamicList<label> > pointsIntoSlaveEdges(slaveEdges.size());
248 // Add all points from the slave patch that have hit the edge
249 forAll(slavePointEdgeHits, pointI)
251 if (slavePointEdgeHits[pointI] > -1)
253 // Create a new point on the master edge
256 masterEdges[slavePointEdgeHits[pointI]].line
259 ).nearestDist(projectedSlavePoints[pointI]).hitPoint();
266 edgeCutPoint, // point
267 slaveMeshPoints[pointI], // master point
268 cutPointZoneID_.index(), // zone for point
269 true // supports a cell
273 // Pout<< "Inserting merge pair off edge: "
274 // << slaveMeshPoints[pointI] << " " << newPoint
275 // << " cut point: " << edgeCutPoint
276 // << " orig: " << slaveLocalPoints[pointI]
277 // << " proj: " << projectedSlavePoints[pointI]
280 // Add the new edge point into the merge map
281 pointMergeMap.insert(slaveMeshPoints[pointI], newPoint);
283 pointsIntoMasterEdges[slavePointEdgeHits[pointI]].append
288 // Add the point into the enriched patch map
298 // Pout<< newPoint << " = " << edgeCutPoint << endl;
308 // Add all points from the slave patch that have hit a face
309 forAll(slavePointFaceHits, pointI)
313 slavePointPointHits[pointI] < 0
314 && slavePointEdgeHits[pointI] < 0
315 && slavePointFaceHits[pointI].hit()
323 projectedSlavePoints[pointI], // point
324 slaveMeshPoints[pointI], // master point
325 cutPointZoneID_.index(), // zone for point
326 true // supports a cell
330 // Pout<< "Inserting merge pair off face: "
331 // << slaveMeshPoints[pointI]
332 // << " " << newPoint
335 // Add the new edge point into the merge map
336 pointMergeMap.insert(slaveMeshPoints[pointI], newPoint);
338 // Add the point into the enriched patch map
342 projectedSlavePoints[pointI]
347 Pout<< "f: " << newPoint << " = "
348 << projectedSlavePoints[pointI] << endl;
353 forAll(masterPointEdgeHits, pointI)
355 if (masterPointEdgeHits[pointI] > -1)
357 pointsIntoSlaveEdges[masterPointEdgeHits[pointI]].append
359 masterMeshPoints[pointI]
364 // Cut all slave edges.
365 // Collect all master edges the slave edge interacts with. Skip
366 // all the edges already marked as used. For every unused edge,
367 // calculate the cut and insert the new point into the master and
369 // For the edge selection algorithm, see, comment in
370 // slidingInterfaceProjectPoints.C.
371 // Edge cutting algoritm:
372 // As the master patch defines the cutting surface, the newly
373 // inserted point needs to be on the master edge. Also, in 3-D
374 // the pair of edges generally misses each other rather than
375 // intersect. Therefore, the intersection is calculated using the
376 // plane the slave edge defines during projection. The plane is
377 // defined by the centrepoint of the edge in the original
378 // configuration and the projected end points. In case of flat
379 // geometries (when the three points are colinear), the plane is
380 // defined by the two projected end-points and the slave edge
381 // normal used as the in-plane vector. When the intersection
382 // point is created, it is added as a new point for both the
383 // master and the slave edge.
384 // In order to be able to re-create the points on edges in mesh
385 // motion without the topology change, the edge pair used to
386 // create the cut point needs to be recorded in
387 // cutPointEdgePairMap
389 // Note. "Processing slave edges" code is repeated twice in the
390 // sliding intergace coupling in order to allow the point
391 // projection to be done separately from the actual cutting.
392 // Please change consistently with slidingInterfaceProjectPoints.C
396 Pout<< "Processing slave edges " << endl;
399 if (!cutPointEdgePairMapPtr_)
403 "void slidingInterface::coupleInterface("
404 "polyTopoChange& ref) const"
405 ) << "Cut point edge pair map pointer not set."
406 << abort(FatalError);
409 Map<Pair<edge> >& addToCpepm = *cutPointEdgePairMapPtr_;
414 // Create a map of faces the edge can interact with
415 labelHashSet curFaceMap
417 nFacesPerSlaveEdge_*primitiveMesh::edgesPerFace_
420 labelHashSet addedFaces(2*primitiveMesh::edgesPerFace_);
422 forAll(slaveEdges, edgeI)
424 const edge& curEdge = slaveEdges[edgeI];
428 slavePointFaceHits[curEdge.start()].hit()
429 || slavePointFaceHits[curEdge.end()].hit()
432 labelHashSet& curUme = usedMasterEdges[edgeI];
434 // Pout<< "Doing edge " << edgeI
435 // << " curEdge: " << curEdge
436 // << " curUme: " << curUme
443 // Grab the faces for start and end points.
444 const label startFace =
445 slavePointFaceHits[curEdge.start()].hitObject();
446 const label endFace = slavePointFaceHits[curEdge.end()].hitObject();
448 // Pout<< "startFace: " << slavePointFaceHits[curEdge.start()]
449 // << " endFace: " << slavePointFaceHits[curEdge.end()]
452 // Insert the start face into the list
453 curFaceMap.insert(startFace);
454 addedFaces.insert(startFace);
456 // Pout<< "curFaceMap: " << curFaceMap.toc() << endl;
459 bool completed = false;
461 while (nSweeps < edgeFaceEscapeLimit_)
465 if (addedFaces.found(endFace))
470 // Add all face neighbours of face in the map
471 const labelList cf = addedFaces.toc();
476 const labelList& curNbrs = masterFaceFaces[cf[cfI]];
478 forAll(curNbrs, nbrI)
480 if (!curFaceMap.found(curNbrs[nbrI]))
482 curFaceMap.insert(curNbrs[nbrI]);
483 addedFaces.insert(curNbrs[nbrI]);
488 if (completed) break;
503 // It is impossible to reach the end from the start, probably
504 // due to disconnected domain. Do search in opposite direction
506 label nReverseSweeps = 0;
509 addedFaces.insert(endFace);
511 while (nReverseSweeps < edgeFaceEscapeLimit_)
515 if (addedFaces.found(startFace))
520 // Add all face neighbours of face in the map
521 const labelList cf = addedFaces.toc();
526 const labelList& curNbrs = masterFaceFaces[cf[cfI]];
528 forAll(curNbrs, nbrI)
530 if (!curFaceMap.found(curNbrs[nbrI]))
532 curFaceMap.insert(curNbrs[nbrI]);
533 addedFaces.insert(curNbrs[nbrI]);
538 if (completed) break;
564 // Create a map of edges the edge can interact with
565 labelHashSet curMasterEdgesMap
567 nFacesPerSlaveEdge_*primitiveMesh::edgesPerFace_
570 const labelList curFaces = curFaceMap.toc();
572 // Pout<< "curFaces: " << curFaces << endl;
574 forAll(curFaces, faceI)
576 // Pout<< "face: " << curFaces[faceI] << " "
577 // << masterPatch[curFaces[faceI]]
579 // << masterPatch.localFaces()[curFaces[faceI]]
582 const labelList& me = masterFaceEdges[curFaces[faceI]];
586 curMasterEdgesMap.insert(me[meI]);
590 const labelList curMasterEdges = curMasterEdgesMap.toc();
592 // For all master edges to intersect, skip the ones
593 // already used and cut the rest with a cutting plane. If
594 // the intersection point, falls inside of both edges, it
598 // The edge cutting code is repeated in
599 // slidingInterface::modifyMotionPoints. This is done for
600 // efficiency reasons and avoids multiple creation of cutting
601 // planes. Please update both simultaneously.
603 const point& a = projectedSlavePoints[curEdge.start()];
604 const point& b = projectedSlavePoints[curEdge.end()];
609 slaveLocalPoints[curEdge.start()]
610 + slavePointNormals[curEdge.start()] // Add start normal
611 + slaveLocalPoints[curEdge.end()]
612 + slavePointNormals[curEdge.end()] // Add end normal
616 plane cutPlane(a, b, c);
621 // << " plane: " << cutPlane
624 linePointRef curSlaveLine = curEdge.line(projectedSlavePoints);
625 const scalar curSlaveLineMag = curSlaveLine.mag();
627 // Pout<< "curSlaveLine: " << curSlaveLine << endl;
629 forAll(curMasterEdges, masterEdgeI)
631 if (!curUme.found(curMasterEdges[masterEdgeI]))
639 const label cmeIndex = curMasterEdges[masterEdgeI];
640 const edge& cme = masterEdges[cmeIndex];
642 // Pout<< "Edge " << cmeIndex
643 // << " cme: " << cme
644 // << " line: " << cme.line(masterLocalPoints)
648 cutPlane.lineIntersect
650 cme.line(masterLocalPoints)
655 cutOnMaster > edgeEndCutoffTol_
656 && cutOnMaster < 1.0 - edgeEndCutoffTol_
659 // Master is cut, check the slave
660 point masterCutPoint =
661 masterLocalPoints[cme.start()]
662 + cutOnMaster*cme.vec(masterLocalPoints);
665 curSlaveLine.nearestDist(masterCutPoint);
669 // Strict checking of slave cut to avoid capturing
675 - curSlaveLine.start()
676 ) & curSlaveLine.vec()
677 )/sqr(curSlaveLineMag);
679 // Calculate merge tolerance from the
680 // target edge length
681 scalar mergeTol = edgeCoPlanarTol_*mag(b - a);
683 // Pout<< "cutOnMaster: " << cutOnMaster
684 // << " masterCutPoint: " << masterCutPoint
685 // << " slaveCutPoint: " << slaveCut.hitPoint()
686 // << " slaveCut.distance(): "
687 // << slaveCut.distance()
688 // << " slave length: " << mag(b - a)
689 // << " mergeTol: " << mergeTol
690 // << " 1: " << mag(b - a)
692 // << cme.line(masterLocalPoints).mag()
697 cutOnSlave > edgeEndCutoffTol_
698 && cutOnSlave < 1.0 - edgeEndCutoffTol_
699 && slaveCut.distance() < mergeTol
702 // Cut both master and slave. Add point
703 // to edge points The point is nominally
704 // added from the start of the master edge
705 // and added to the cut point zone
711 masterCutPoint, // point
712 masterMeshPoints[cme.start()],// m p
713 cutPointZoneID_.index(), // zone
718 // Pout<< "Inserting point: " << newPoint
719 // << " as edge to edge intersection. "
721 // << edgeI << " " << curEdge
722 // << " master edge: "
723 // << cmeIndex << " " << cme
726 pointsIntoSlaveEdges[edgeI].append(newPoint);
727 pointsIntoMasterEdges[cmeIndex].append
732 // Add the point into the enriched patch map
739 // Record which two edges intersect to
743 newPoint, // Cut point index
748 masterMeshPoints[cme.start()],
749 masterMeshPoints[cme.end()]
753 slaveMeshPoints[curEdge.start()],
754 slaveMeshPoints[curEdge.end()]
761 Pout<< " " << newPoint << " = "
762 << masterCutPoint << " ";
769 // Intersection exists but it is too far
787 // Missed master edge
805 } // End if both ends missing
806 } // End for all slave edges
808 // Pout<< "pointsIntoMasterEdges: " << pointsIntoMasterEdges << endl;
809 // Pout<< "pointsIntoSlaveEdges: " << pointsIntoSlaveEdges << endl;
811 // Re-pack the points into edges lists
812 labelListList pime(pointsIntoMasterEdges.size());
814 forAll(pointsIntoMasterEdges, i)
816 pime[i].transfer(pointsIntoMasterEdges[i]);
819 labelListList pise(pointsIntoSlaveEdges.size());
821 forAll(pointsIntoSlaveEdges, i)
823 pise[i].transfer(pointsIntoSlaveEdges[i]);
826 // Prepare the enriched faces
827 cutPatch.calcEnrichedFaces
834 // Demand driven calculate the cut faces. Apart from the
835 // cutFaces/cutFaceMaster/cutFaceSlave no information from the cutPatch
837 const faceList& cutFaces = cutPatch.cutFaces();
838 const labelList& cutFaceMaster = cutPatch.cutFaceMaster();
839 const labelList& cutFaceSlave = cutPatch.cutFaceSlave();
841 const labelList& masterFc = masterFaceCells();
842 const labelList& slaveFc = slaveFaceCells();
844 // Couple the interface
847 // 1) Go through the cut faces and check if the cut face is the same as the
848 // defining master or slave. If so, modify the appropriate
849 // face and mark the other for relegation into the face zone.
850 // 2) If different, mark both sides for relegation and insert the new face
853 boolList orphanedMaster(masterPatch.size(), false);
854 boolList orphanedSlave(slavePatch.size(), false);
856 forAll(cutFaces, faceI)
858 const face& curCutFace = cutFaces[faceI];
859 const label curMaster = cutFaceMaster[faceI];
860 const label curSlave = cutFaceSlave[faceI];
862 // Pout<< "Doing insertion of face " << faceI << ": ";
864 // Check if the face has changed topologically
865 bool insertedFace = false;
869 // Face has got a master
870 if (curCutFace == masterPatch[curMaster])
872 // Face is equal to master. Modify master face.
873 // Pout<< "Face is equal to master and is ";
875 // If the face has got both master and slave, it is an
876 // internal face; otherwise it is a patch face in the
877 // master patch. Keep it in the master face zone.
881 // Pout<< "internal" << endl;
882 if (masterFc[curMaster] < slaveFc[curSlave])
884 // Cut face should point into slave.
885 // Be careful about flips in zone!
890 curCutFace, // new face
891 masterPatchAddr[curMaster], // master face id
892 masterFc[curMaster], // owner
893 slaveFc[curSlave], // neighbour
896 false, // remove from zone
897 masterFaceZoneID_.index(), // zone ID
898 masterPatchFlip[curMaster] // zone flip
902 // Pout<< "modifying master face. Old master: "
903 // << masterPatch[curMaster]
904 // << " new face: " << curCutFace.reverseFace()
905 // << " own: " << masterFc[curMaster]
906 // << " nei: " << slaveFc[curSlave] << endl;
910 // Cut face should point into master. Flip required.
911 // Be careful about flips in zone!
916 curCutFace.reverseFace(), // new face
917 masterPatchAddr[curMaster], // master face id
918 slaveFc[curSlave], // owner
919 masterFc[curMaster], // neighbour
922 false, // remove from zone
923 masterFaceZoneID_.index(), // zone ID
924 !masterPatchFlip[curMaster] // zone flip
930 orphanedSlave[curSlave] = true;
934 // Pout<< "master boundary" << endl;
939 curCutFace, // new face
940 masterPatchAddr[curMaster], // master face index
941 masterFc[curMaster], // owner
944 masterPatchID_.index(), // patch ID
945 false, // remove from zone
946 masterFaceZoneID_.index(), // zone ID
947 masterPatchFlip[curMaster] // zone flip
955 else if (curSlave >= 0)
957 // Face has got a slave
959 // Renumber the slave face into merged labels
960 face rsf(slavePatch[curSlave]);
964 Map<label>::const_iterator mpIter = pointMergeMap.find(rsf[i]);
966 if (mpIter != pointMergeMap.end())
972 if (curCutFace == rsf)
974 // Face is equal to slave. Modify slave face.
975 // Pout<< "Face is equal to slave and is ";
979 // Pout<< "regular internal" << endl;
980 if (masterFc[curMaster] < slaveFc[curSlave])
986 curCutFace, // new face
987 slavePatchAddr[curSlave], // master face id
988 masterFc[curMaster], // owner
989 slaveFc[curSlave], // neighbour
992 false, // remove from zone
993 slaveFaceZoneID_.index(), // zone ID
994 !slavePatchFlip[curMaster] // zone flip
1000 // Cut face should point into master.
1001 // Be careful about flips in zone!
1002 // Pout<< "flipped internal" << endl;
1007 curCutFace.reverseFace(), // new face
1008 slavePatchAddr[curSlave], // master face id
1009 slaveFc[curSlave], // owner
1010 masterFc[curMaster], // neighbour
1013 false, // remove from zone
1014 slaveFaceZoneID_.index(), // zone ID
1015 slavePatchFlip[curSlave] // zone flip
1020 // Orphan the master
1021 orphanedMaster[curMaster] = true;
1025 // Pout<< "slave boundary" << endl;
1030 curCutFace, // new face
1031 slavePatchAddr[curSlave], // master face index
1032 slaveFc[curSlave], // owner
1035 slavePatchID_.index(), // patch ID
1036 false, // remove from zone
1037 slaveFaceZoneID_.index(), // zone ID
1038 slavePatchFlip[curSlave] // zone flip
1043 insertedFace = true;
1050 "void slidingInterface::coupleInterface("
1051 "polyTopoChange& ref) const"
1052 ) << "Face " << faceI << " in cut faces has neither a master "
1053 << "nor a slave. Error in the cutting algorithm on modify."
1054 << abort(FatalError);
1059 // Face is different from both master and slave
1060 // Pout<< "Face different from both master and slave" << endl;
1066 // Add internal face
1067 if (masterFc[curMaster] < slaveFc[curSlave])
1069 // Pout<< "Adding internal face " << curCutFace
1070 // << " owner: " << masterFc[curMaster]
1071 // << " slave: " << slaveFc[curSlave]
1072 // << " master face: " << masterPatchAddr[curMaster]
1075 // Cut face should point into slave.
1080 curCutFace, // new face
1081 masterFc[curMaster], // owner
1082 slaveFc[curSlave], // neighbour
1085 masterPatchAddr[curMaster], // master face id
1088 cutFaceZoneID_.index(), // zone ID
1095 // Cut face should point into master. Flip required.
1100 curCutFace.reverseFace(), // new face
1101 slaveFc[curSlave], // owner
1102 masterFc[curMaster], // neighbour
1105 masterPatchAddr[curMaster], // master face id
1108 cutFaceZoneID_.index(), // zone ID
1115 orphanedSlave[curSlave] = true;
1119 // Pout<< "Adding solo master face " << curCutFace
1120 // << " owner: " << masterFc[curMaster]
1121 // << " master face: " << masterPatchAddr[curMaster]
1124 // Add master patch face
1129 curCutFace, // new face
1130 masterFc[curMaster], // owner
1134 masterPatchAddr[curMaster], // master face index
1136 masterPatchID_.index(), // patch ID
1137 cutFaceZoneID_.index(), // zone ID
1144 orphanedMaster[curMaster] = true;
1146 else if (curSlave >= 0)
1148 // Pout<< "Adding solo slave face " << curCutFace
1149 // << " owner: " << slaveFc[curSlave]
1150 // << " master face: " << slavePatchAddr[curSlave]
1153 // Add slave patch face
1158 curCutFace, // new face
1159 slaveFc[curSlave], // owner
1163 slavePatchAddr[curSlave], // master face index
1165 slavePatchID_.index(), // patch ID
1166 cutFaceZoneID_.index(), // zone ID
1172 orphanedSlave[curSlave] = true;
1178 "void slidingInterface::coupleInterface("
1179 "polyTopoChange& ref) const"
1180 ) << "Face " << faceI << " in cut faces has neither a master "
1181 << "nor a slave. Error in the cutting algorithm on add."
1182 << abort(FatalError);
1187 // Move the orphaned faces into the face zone
1188 // Pout<< "Orphaned master faces: " << orphanedMaster << endl;
1189 // Pout<< "Orphaned slave faces: " << orphanedSlave << endl;
1191 label nOrphanedMasters = 0;
1193 forAll(orphanedMaster, faceI)
1195 if (orphanedMaster[faceI])
1199 //// Recover original orientation
1204 // masterPatch[faceI], // new face
1205 // masterPatchAddr[faceI], // master face index
1208 // false, // flux flip
1210 // false, // remove from zone
1211 // masterFaceZoneID_.index(), // zone ID
1212 // false // zone flip
1216 //Pout<< "**MJ:deleting master face " << masterPatchAddr[faceI]
1217 // << " old verts:" << masterPatch[faceI] << endl;
1218 ref.setAction(polyRemoveFace(masterPatchAddr[faceI]));
1222 label nOrphanedSlaves = 0;
1224 forAll(orphanedSlave, faceI)
1226 if (orphanedSlave[faceI])
1230 //// Recover original orientation
1235 // slavePatch[faceI], // new face
1236 // slavePatchAddr[faceI], // slave face index
1239 // false, // flux flip
1241 // false, // remove from zone
1242 // slaveFaceZoneID_.index(), // zone ID
1243 // false // zone flip
1247 //Pout<< "**MJ:deleting slave face " << slavePatchAddr[faceI]
1248 // << " old verts:" << slavePatch[faceI] << endl;
1249 ref.setAction(polyRemoveFace(slavePatchAddr[faceI]));
1255 Pout<< "Number of orphaned faces: "
1256 << "master = " << nOrphanedMasters << " out of "
1257 << orphanedMaster.size()
1258 << " slave = " << nOrphanedSlaves << " out of "
1259 << orphanedSlave.size() << endl;
1262 // Finished coupling the plane of sliding interface.
1264 // Modify faces influenced by the sliding interface
1265 // These are the faces belonging to the master and slave cell
1266 // layer which have not already been modified.
1267 // Modification comes in three types:
1268 // 1) eliminate the points that have been removed when the old sliding
1269 // interface has been removed
1270 // 2) Merge the slave points that have hit points on the master patch
1271 // 3) Introduce new points resulting from the new sliding interface cut
1273 // Collect all affected faces
1277 // Grab the list of faces in the layer
1278 const labelList& masterStickOuts = masterStickOutFaces();
1280 // Pout<< "masterStickOuts: " << masterStickOuts << endl;
1282 // Re-create the master stick-out faces
1283 forAll(masterStickOuts, faceI)
1285 // Renumber the face and remove additional points
1287 const label curFaceID = masterStickOuts[faceI];
1289 const face& oldRichFace = faces[curFaceID];
1291 bool changed = false;
1293 // Remove removed points from the face
1294 face oldFace(oldRichFace.size());
1297 forAll(oldRichFace, pointI)
1299 if (ref.pointRemoved(oldRichFace[pointI]))
1306 oldFace[nOldFace] = oldRichFace[pointI];
1311 oldFace.setSize(nOldFace);
1313 // Pout<< "old rich master face: " << oldRichFace
1314 // << " old face: " << oldFace
1317 DynamicList<label> newFaceLabels(2*oldFace.size());
1319 forAll(oldFace, pointI)
1321 if (masterMeshPointMap.found(oldFace[pointI]))
1323 // Point is in master patch. Add it
1325 // If the point is a direct hit, grab its label; otherwise
1326 // keep the original
1327 if (pointMergeMap.found(oldFace[pointI]))
1330 newFaceLabels.append
1332 pointMergeMap.find(oldFace[pointI])()
1337 newFaceLabels.append(oldFace[pointI]);
1340 // Find if there are additional points inserted onto the edge
1341 // between current point and the next point
1343 // 1) Find all the edges in the master patch coming
1344 // out of the current point.
1345 // 2) If the next point in the face to pick the right edge
1346 const label localFirstLabel =
1347 masterMeshPointMap.find(oldFace[pointI])();
1349 const labelList& curEdges = masterPointEdges[localFirstLabel];
1351 const label nextLabel = oldFace.nextLabel(pointI);
1353 Map<label>::const_iterator mmpmIter =
1354 masterMeshPointMap.find(nextLabel);
1356 if (mmpmIter != masterMeshPointMap.end())
1358 // Pout<< "found label pair " << oldFace[pointI]
1359 // << " and " << nextLabel;
1360 // Find the points on the edge between them
1361 const label localNextLabel = mmpmIter();
1363 forAll(curEdges, curEdgeI)
1367 masterEdges[curEdges[curEdgeI]].otherVertex
1374 // Pout<< " found edge: " << curEdges[curEdgeI]
1377 // Get points on current edge
1378 const labelList& curPime = pime[curEdges[curEdgeI]];
1383 // Pout<< "curPime: " << curPime << endl;
1384 // Insert the edge points into the face
1385 // in the correct order
1386 const point& startPoint =
1387 masterLocalPoints[localFirstLabel];
1390 masterLocalPoints[localNextLabel]
1395 scalarField edgePointWeights(curPime.size());
1397 forAll(curPime, curPimeI)
1399 edgePointWeights[curPimeI] =
1403 pointMap.find(curPime[curPimeI])()
1413 min(edgePointWeights) < 0
1414 || max(edgePointWeights) > 1
1419 "void slidingInterface::"
1421 "polyTopoChange& ref) const"
1422 ) << "Error in master stick-out edge "
1423 << "point collection."
1424 << abort(FatalError);
1428 // Go through the points and collect
1429 // them based on weights from lower to
1430 // higher. This gives the correct
1431 // order of points along the edge.
1435 passI < edgePointWeights.size();
1439 // Max weight can only be one, so
1440 // the sorting is done by
1442 label nextPoint = -1;
1445 forAll(edgePointWeights, wI)
1447 if (edgePointWeights[wI] < dist)
1449 dist = edgePointWeights[wI];
1454 // Insert the next point and reset
1455 // its weight to exclude it from
1457 newFaceLabels.append(curPime[nextPoint]);
1458 edgePointWeights[nextPoint] = GREAT;
1463 } // End of found edge
1464 } // End of looking through current edges
1469 newFaceLabels.append(oldFace[pointI]);
1475 if (newFaceLabels.size() < 3)
1479 "void slidingInterface::coupleInterface("
1480 "polyTopoChange& ref) const"
1481 ) << "Face " << curFaceID << " reduced to less than "
1482 << "3 points. Topological/cutting error A." << nl
1483 << "Old face: " << oldFace << " new face: " << newFaceLabels
1484 << abort(FatalError);
1487 // Get face zone and its flip
1488 label modifiedFaceZone = faceZones.whichZone(curFaceID);
1489 bool modifiedFaceZoneFlip = false;
1491 if (modifiedFaceZone >= 0)
1493 modifiedFaceZoneFlip =
1494 faceZones[modifiedFaceZone].flipMap()
1496 faceZones[modifiedFaceZone].whichFace(curFaceID)
1501 newFace.transfer(newFaceLabels);
1503 // Pout<< "Modifying master stick-out face " << curFaceID
1504 // << " old face: " << oldFace
1505 // << " new face: " << newFace
1509 if (mesh.isInternalFace(curFaceID))
1515 newFace, // modified face
1516 curFaceID, // label of face being modified
1517 own[curFaceID], // owner
1518 nei[curFaceID], // neighbour
1520 -1, // patch for face
1521 false, // remove from zone
1522 modifiedFaceZone, // zone for face
1523 modifiedFaceZoneFlip // face flip in zone
1533 newFace, // modified face
1534 curFaceID, // label of face being modified
1535 own[curFaceID], // owner
1538 mesh.boundaryMesh().whichPatch(curFaceID),
1540 false, // remove from zone
1541 modifiedFaceZone, // zone for face
1542 modifiedFaceZoneFlip // face flip in zone
1549 // Pout<< "Finished master side" << endl;
1553 // Grab the list of faces in the layer
1554 const labelList& slaveStickOuts = slaveStickOutFaces();
1556 // Pout<< "slaveStickOuts: " << slaveStickOuts << endl;
1558 const Map<label>& rpm = retiredPointMap();
1560 // Re-create the slave stick-out faces
1562 forAll(slaveStickOuts, faceI)
1564 // Renumber the face and remove additional points
1565 const label curFaceID = slaveStickOuts[faceI];
1567 const face& oldRichFace = faces[curFaceID];
1569 bool changed = false;
1571 // Remove removed points from the face
1572 face oldFace(oldRichFace.size());
1575 forAll(oldRichFace, pointI)
1579 rpm.found(oldRichFace[pointI])
1580 || slaveMeshPointMap.found(oldRichFace[pointI])
1583 // Point definitely live. Add it
1584 oldFace[nOldFace] = oldRichFace[pointI];
1589 ref.pointRemoved(oldRichFace[pointI])
1590 || masterMeshPointMap.found(oldRichFace[pointI])
1593 // Point removed and not on slave patch
1594 // (first if takes care of that!) or
1595 // point belonging to master patch
1601 oldFace[nOldFace] = oldRichFace[pointI];
1606 oldFace.setSize(nOldFace);
1608 DynamicList<label> newFaceLabels(2*oldFace.size());
1610 // Pout<< "old rich slave face: " << oldRichFace
1611 // << " old face: " << oldFace
1614 forAll(oldFace, pointI)
1616 // Try to find the point in retired points
1617 label curP = oldFace[pointI];
1619 Map<label>::const_iterator rpmIter = rpm.find(oldFace[pointI]);
1621 if (rpmIter != rpm.end())
1627 if (slaveMeshPointMap.found(curP))
1629 // Point is in slave patch. Add it
1631 // If the point is a direct hit, grab its label; otherwise
1632 // keep the original
1633 if (pointMergeMap.found(curP))
1636 newFaceLabels.append
1638 pointMergeMap.find(curP)()
1643 newFaceLabels.append(curP);
1646 // Find if there are additional points inserted onto the edge
1647 // between current point and the next point
1649 // 1) Find all the edges in the slave patch coming
1650 // out of the current point.
1651 // 2) Use the next point in the face to pick the right edge
1653 const label localFirstLabel =
1654 slaveMeshPointMap.find(curP)();
1656 const labelList& curEdges = slavePointEdges[localFirstLabel];
1658 label nextLabel = oldFace.nextLabel(pointI);
1660 Map<label>::const_iterator rpmNextIter =
1661 rpm.find(nextLabel);
1663 if (rpmNextIter != rpm.end())
1665 nextLabel = rpmNextIter();
1668 Map<label>::const_iterator mmpmIter =
1669 slaveMeshPointMap.find(nextLabel);
1671 if (mmpmIter != slaveMeshPointMap.end())
1673 // Both points on the slave patch.
1674 // Find the points on the edge between them
1675 const label localNextLabel = mmpmIter();
1677 forAll(curEdges, curEdgeI)
1681 slaveEdges[curEdges[curEdgeI]].otherVertex
1688 // Pout<< " found edge: " << curEdges[curEdgeI]
1691 // Get points on current edge
1692 const labelList& curPise = pise[curEdges[curEdgeI]];
1697 // Pout<< "curPise: " << curPise << endl;
1698 // Insert the edge points into the face
1699 // in the correct order
1700 const point& startPoint =
1701 projectedSlavePoints[localFirstLabel];
1704 projectedSlavePoints[localNextLabel]
1709 scalarField edgePointWeights(curPise.size());
1711 forAll(curPise, curPiseI)
1713 edgePointWeights[curPiseI] =
1717 pointMap.find(curPise[curPiseI])()
1727 min(edgePointWeights) < 0
1728 || max(edgePointWeights) > 1
1733 "void slidingInterface::"
1735 "polyTopoChange& ref) const"
1736 ) << "Error in slave stick-out edge "
1737 << "point collection."
1738 << abort(FatalError);
1742 // Go through the points and collect
1743 // them based on weights from lower to
1744 // higher. This gives the correct
1745 // order of points along the edge.
1749 passI < edgePointWeights.size();
1753 // Max weight can only be one, so
1754 // the sorting is done by
1756 label nextPoint = -1;
1759 forAll(edgePointWeights, wI)
1761 if (edgePointWeights[wI] < dist)
1763 dist = edgePointWeights[wI];
1768 // Insert the next point and reset
1769 // its weight to exclude it from
1771 newFaceLabels.append(curPise[nextPoint]);
1772 edgePointWeights[nextPoint] = GREAT;
1778 } // End of found edge
1779 } // End of looking through current edges
1783 newFaceLabels.append(oldFace[pointI]);
1789 if (newFaceLabels.size() < 3)
1793 "void slidingInterface::coupleInterface("
1794 "polyTopoChange& ref) const"
1795 ) << "Face " << curFaceID << " reduced to less than "
1796 << "3 points. Topological/cutting error B." << nl
1797 << "Old face: " << oldFace << " new face: " << newFaceLabels
1798 << abort(FatalError);
1801 // Get face zone and its flip
1802 label modifiedFaceZone = faceZones.whichZone(curFaceID);
1803 bool modifiedFaceZoneFlip = false;
1805 if (modifiedFaceZone >= 0)
1807 modifiedFaceZoneFlip =
1808 faceZones[modifiedFaceZone].flipMap()
1810 faceZones[modifiedFaceZone].whichFace(curFaceID)
1815 newFace.transfer(newFaceLabels);
1817 // Pout<< "Modifying slave stick-out face " << curFaceID
1818 // << " old face: " << oldFace
1819 // << " new face: " << newFace
1823 if (mesh.isInternalFace(curFaceID))
1829 newFace, // modified face
1830 curFaceID, // label of face being modified
1831 own[curFaceID], // owner
1832 nei[curFaceID], // neighbour
1834 -1, // patch for face
1835 false, // remove from zone
1836 modifiedFaceZone, // zone for face
1837 modifiedFaceZoneFlip // face flip in zone
1847 newFace, // modified face
1848 curFaceID, // label of face being modified
1849 own[curFaceID], // owner
1852 mesh.boundaryMesh().whichPatch(curFaceID),
1854 false, // remove from zone
1855 modifiedFaceZone, // zone for face
1856 modifiedFaceZoneFlip // face flip in zone
1863 // Activate and retire slave patch points
1864 // This needs to be done last, so that the map of removed points
1865 // does not get damaged by point modifications
1867 if (!retiredPointMapPtr_)
1871 "void slidingInterface::coupleInterface("
1872 "polyTopoChange& ref) const"
1873 ) << "Retired point map pointer not set."
1874 << abort(FatalError);
1877 Map<label>& addToRpm = *retiredPointMapPtr_;
1879 // Clear the old map
1882 label nRetiredPoints = 0;
1884 forAll(slaveMeshPoints, pointI)
1886 if (pointMergeMap.found(slaveMeshPoints[pointI]))
1888 // Retire the point - only used for supporting the detached
1896 // slaveMeshPoints[pointI], // point ID
1897 // points[slaveMeshPoints[pointI]], // point
1898 // false, // remove from zone
1899 // mesh.pointZones().whichZone(slaveMeshPoints[pointI]),
1901 // false // in a cell
1904 //Pout<< "MJ retire slave point " << slaveMeshPoints[pointI]
1905 // << " coord " << points[slaveMeshPoints[pointI]]
1911 slaveMeshPoints[pointI]
1917 pointMergeMap.find(slaveMeshPoints[pointI])(),
1918 slaveMeshPoints[pointI]
1927 slaveMeshPoints[pointI], // point ID
1928 points[slaveMeshPoints[pointI]], // point
1929 false, // remove from zone
1930 mesh.pointZones().whichZone(slaveMeshPoints[pointI]),// zone
1939 Pout<< "Retired " << nRetiredPoints << " out of "
1940 << slaveMeshPoints.size() << " points." << endl;
1943 // Grab cut face master and slave addressing
1944 if (cutFaceMasterPtr_) deleteDemandDrivenData(cutFaceMasterPtr_);
1945 cutFaceMasterPtr_ = new labelList(cutPatch.cutFaceMaster());
1947 if (cutFaceSlavePtr_) deleteDemandDrivenData(cutFaceSlavePtr_);
1948 cutFaceSlavePtr_ = new labelList(cutPatch.cutFaceSlave());
1950 // Finished coupling
1955 Pout<< "void slidingInterface::coupleInterface("
1956 << "polyTopoChange& ref) : "
1957 << "Finished coupling sliding interface " << name() << endl;
1962 // ************************************************************************* //