1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 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, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 Couple sliding interface
32 Hrvoje Jasak, Wikki Ltd. All rights reserved. Copyright Hrvoje Jasak.
34 \*---------------------------------------------------------------------------*/
36 #include "slidingInterface.H"
37 #include "polyTopoChange.H"
39 #include "primitiveMesh.H"
40 #include "enrichedPatch.H"
41 #include "DynamicList.H"
43 #include "triPointRef.H"
45 #include "polyTopoChanger.H"
47 #include "standAlonePatch.H"
49 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
51 const Foam::scalar Foam::slidingInterface::edgeCoPlanarTol_
53 debug::tolerances("slidingEdgeCoPlanarTol", 0.8)
57 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
59 // Index of debug signs:
60 // . - loop of the edge-to-face interaction detection
61 // x - reversal of direction in edge-to-face interaction detection
62 // + - complete edge-to-face interaction detection
63 // z - incomplete edge-to-face interaction detection. This may be OK for edges
64 // crossing from one to the other side of multiply connected master patch
66 // e - adding a point on edge
67 // f - adding a point on face
68 // . - collecting edges off another face for edge-to-edge cut
69 // + - finished collection of edges
70 // * - cut both master and slave
71 // n - cutting new edge
72 // t - intersection exists but it is outside of tolerance
73 // x - missed slave edge in cut
74 // - - missed master edge in cut
75 // u - edge already used in cutting
77 void Foam::slidingInterface::coupleInterface(polyTopoChange& ref) const
81 Pout<< "void slidingInterface::coupleInterface"
82 << "(polyTopoChange& ref) : "
83 << "Coupling sliding interface " << name() << endl;
86 const polyMesh& mesh = topoChanger().mesh();
88 const pointField& points = mesh.allPoints();
89 const faceList& faces = mesh.faces();
91 const labelList& own = mesh.faceOwner();
92 const labelList& nei = mesh.faceNeighbour();
93 const faceZoneMesh& faceZones = mesh.faceZones();
95 // Note: master and slave patch will give already oriented faces from the
96 // face zone. They are flipped to correct orientation by the zone
97 // functionality. Therefore, the flip will simply be a true or false,
98 // depending on what should be done with the face, rather than
99 // reversing the existing face zone flip
102 const primitiveFacePatch& masterPatch =
103 faceZones[masterFaceZoneID_.index()]();
105 const labelList& masterPatchAddr = faceZones[masterFaceZoneID_.index()];
107 const primitiveFacePatch& slavePatch =
108 faceZones[slaveFaceZoneID_.index()]();
110 const labelList& slavePatchAddr = faceZones[slaveFaceZoneID_.index()];
112 const edgeList& masterEdges = masterPatch.edges();
113 const labelListList& masterPointEdges = masterPatch.pointEdges();
114 const labelList& masterMeshPoints = masterPatch.meshPoints();
115 const pointField& masterLocalPoints = masterPatch.localPoints();
116 const labelListList& masterFaceFaces = masterPatch.faceFaces();
117 const labelListList& masterFaceEdges = masterPatch.faceEdges();
118 const Map<label>& masterMeshPointMap = masterPatch.meshPointMap();
120 const edgeList& slaveEdges = slavePatch.edges();
121 const labelListList& slavePointEdges = slavePatch.pointEdges();
122 const labelList& slaveMeshPoints = slavePatch.meshPoints();
123 const pointField& slaveLocalPoints = slavePatch.localPoints();
124 const Map<label>& slaveMeshPointMap = slavePatch.meshPointMap();
125 const vectorField& slavePointNormals = slavePatch.pointNormals();
127 // Collect projection addressing
131 slavePointPointHitsPtr_
132 && slavePointEdgeHitsPtr_
133 && slavePointFaceHitsPtr_
134 && masterPointEdgeHitsPtr_
140 "void slidingInterface::coupleInterface("
141 "polyTopoChange& ref) const"
142 ) << "Point projection addressing not available."
143 << abort(FatalError);
146 const labelList& slavePointPointHits = *slavePointPointHitsPtr_;
147 const labelList& slavePointEdgeHits = *slavePointEdgeHitsPtr_;
148 const List<objectHit>& slavePointFaceHits = *slavePointFaceHitsPtr_;
149 const labelList& masterPointEdgeHits = *masterPointEdgeHitsPtr_;
150 const pointField& projectedSlavePoints = *projectedSlavePointsPtr_;
152 // Create enriched patch
153 enrichedPatch cutPatch
162 // Get reference to list of added point for the enriched patch.
163 // This will be used for point addition
164 Map<point>& pointMap = cutPatch.pointMap();
166 // Get reference to the list of merged points
167 Map<label>& pointMergeMap = cutPatch.pointMergeMap();
169 // Create mapping for every merged point of the slave patch
170 forAll (slavePointPointHits, pointI)
172 if (slavePointPointHits[pointI] >= 0)
174 // Pout<< "Inserting point merge pair: " << slaveMeshPoints[pointI]
175 // << " : " << masterMeshPoints[slavePointPointHits[pointI]]
179 slaveMeshPoints[pointI],
180 masterMeshPoints[slavePointPointHits[pointI]]
185 // Collect the list of used edges for every slave edge
187 List<labelHashSet> usedMasterEdges(slaveEdges.size());
189 // Collect of slave point hits
190 forAll (slavePointPointHits, pointI)
192 // For point hits, add all point-edges from master side to all point
193 const labelList& curSlaveEdges = slavePointEdges[pointI];
195 if (slavePointPointHits[pointI] > -1)
197 const labelList& curMasterEdges =
198 masterPointEdges[slavePointPointHits[pointI]];
200 // Mark all current master edges as used for all the current slave
202 forAll (curSlaveEdges, slaveEdgeI)
204 labelHashSet& sm = usedMasterEdges[curSlaveEdges[slaveEdgeI]];
206 forAll (curMasterEdges, masterEdgeI)
208 sm.insert(curMasterEdges[masterEdgeI]);
212 else if (slavePointEdgeHits[pointI] > -1)
214 // For edge hits, add the master edge
215 forAll (curSlaveEdges, slaveEdgeI)
217 usedMasterEdges[curSlaveEdges[slaveEdgeI]].insert
219 slavePointEdgeHits[pointI]
225 // Collect off master point hits
226 // For every master point that has hit an edge, add all edges coming from
227 // that point to the slave edge that has been hit
228 forAll (masterPointEdgeHits, masterPointI)
230 if (masterPointEdgeHits[masterPointI] > -1)
232 const labelList& curMasterEdges = masterPointEdges[masterPointI];
235 usedMasterEdges[masterPointEdgeHits[masterPointI]];
237 forAll (curMasterEdges, masterEdgeI)
239 sm.insert(curMasterEdges[masterEdgeI]);
244 // Pout << "used edges: " << endl;
245 // forAll (usedMasterEdges, edgeI)
247 // Pout<< "edge: " << edgeI << " used: "
248 // << usedMasterEdges[edgeI].toc() << endl;
251 // For every master and slave edge make a list of points to be added into
253 List<DynamicList<label> > pointsIntoMasterEdges(masterEdges.size());
254 List<DynamicList<label> > pointsIntoSlaveEdges(slaveEdges.size());
256 // Add all points from the slave patch that have hit the edge
257 forAll (slavePointEdgeHits, pointI)
259 if (slavePointEdgeHits[pointI] > -1)
261 // Create a new point on the master edge
264 masterEdges[slavePointEdgeHits[pointI]].line
267 ).nearestDist(projectedSlavePoints[pointI]).hitPoint();
274 edgeCutPoint, // point
275 slaveMeshPoints[pointI], // master point
276 cutPointZoneID_.index(), // zone for point
277 true // supports a cell
280 // Pout<< "Inserting merge pair off edge: "
281 // << slaveMeshPoints[pointI] << " "
282 // << newPoint << " cut point: " << edgeCutPoint
283 // << " orig: " << slaveLocalPoints[pointI]
284 // << " proj: " << projectedSlavePoints[pointI]
285 // << " master point: " << slaveMeshPoints[pointI] << endl;
287 // Add the new edge point into the merge map
288 pointMergeMap.insert(slaveMeshPoints[pointI], newPoint);
290 pointsIntoMasterEdges[slavePointEdgeHits[pointI]].append
295 // Add the point into the enriched patch map
305 // Pout<< newPoint << " = " << edgeCutPoint << endl;
315 // Add all points from the slave patch that have hit a face
316 forAll (slavePointFaceHits, pointI)
320 slavePointPointHits[pointI] < 0
321 && slavePointEdgeHits[pointI] < 0
322 && slavePointFaceHits[pointI].hit()
330 projectedSlavePoints[pointI], // point
331 slaveMeshPoints[pointI], // master point
332 cutPointZoneID_.index(), // zone for point
333 true // supports a cell
336 // Pout<< "Inserting merge pair off face: "
337 // << slaveMeshPoints[pointI] << " " << newPoint
338 // << " orig: " << slaveLocalPoints[pointI]
339 // << " at " << projectedSlavePoints[pointI]
340 // << " master point: " << slaveMeshPoints[pointI] << endl;
342 // Add the new edge point into the merge map
343 pointMergeMap.insert(slaveMeshPoints[pointI], newPoint);
345 // Add the point into the enriched patch map
349 projectedSlavePoints[pointI]
355 // Pout<< newPoint << " = "
356 // << projectedSlavePoints[pointI] << endl;
361 forAll (masterPointEdgeHits, pointI)
363 if (masterPointEdgeHits[pointI] > -1)
365 pointsIntoSlaveEdges[masterPointEdgeHits[pointI]].append
367 masterMeshPoints[pointI]
372 // Cut all slave edges.
373 // Collect all master edges the slave edge interacts with. Skip
374 // all the edges already marked as used. For every unused edge,
375 // calculate the cut and insert the new point into the master and
377 // For the edge selection algorithm, see, comment in
378 // slidingInterfaceProjectPoints.C.
379 // Edge cutting algoritm:
380 // As the master patch defines the cutting surface, the newly
381 // inserted point needs to be on the master edge. Also, in 3-D
382 // the pair of edges generally misses each other rather than
383 // intersect. Therefore, the intersection is calculated using the
384 // plane the slave edge defines during projection. The plane is
385 // defined by the centrepoint of the edge in the original
386 // configuration and the projected end points. In case of flat
387 // geometries (when the three points are colinear), the plane is
388 // defined by the two projected end-points and the slave edge
389 // normal used as the in-plane vector. When the intersection
390 // point is created, it is added as a new point for both the
391 // master and the slave edge.
392 // In order to be able to re-create the points on edges in mesh
393 // motion without the topology change, the edge pair used to
394 // create the cut point needs to be recorded in
395 // cutPointEdgePairMap
397 // Note. "Processing slave edges" code is repeated twice in the
398 // sliding intergace coupling in order to allow the point
399 // projection to be done separately from the actual cutting.
400 // Please change consistently with slidingInterfaceProjectPoints.C
404 Pout << "Processing slave edges " << endl;
407 if (!cutPointEdgePairMapPtr_)
411 "void slidingInterface::coupleInterface("
412 "polyTopoChange& ref) const"
413 ) << "Cut point edge pair map pointer not set."
414 << abort(FatalError);
417 Map<Pair<edge> >& addToCpepm = *cutPointEdgePairMapPtr_;
422 // Create a map of faces the edge can interact with
423 labelHashSet curFaceMap
425 nFacesPerSlaveEdge_*primitiveMesh::edgesPerFace_
428 labelHashSet addedFaces(2*primitiveMesh::edgesPerFace_);
430 forAll (slaveEdges, edgeI)
432 const edge& curEdge = slaveEdges[edgeI];
436 slavePointFaceHits[curEdge.start()].hit()
437 || slavePointFaceHits[curEdge.end()].hit()
440 labelHashSet& curUme = usedMasterEdges[edgeI];
441 // Pout<< "Doing edge " << edgeI << " curEdge: " << curEdge
442 // << " curUme: " << curUme << endl;
447 // Grab the faces for start and end points.
448 const label startFace =
449 slavePointFaceHits[curEdge.start()].hitObject();
450 const label endFace =
451 slavePointFaceHits[curEdge.end()].hitObject();
452 // Pout<< "startFace: " << slavePointFaceHits[curEdge.start()]
453 // << " endFace: " << slavePointFaceHits[curEdge.end()]
455 // Insert the start face into the list
456 curFaceMap.insert(startFace);
457 addedFaces.insert(startFace);
458 // Pout << "curFaceMap: " << curFaceMap.toc() << endl;
460 bool completed = false;
462 while (nSweeps < edgeFaceEscapeLimit_)
466 if (addedFaces.found(endFace))
471 // Add all face neighbours of face in the map
472 const labelList cf = addedFaces.toc();
477 const labelList& curNbrs = masterFaceFaces[cf[cfI]];
479 forAll (curNbrs, nbrI)
481 if (!curFaceMap.found(curNbrs[nbrI]))
483 curFaceMap.insert(curNbrs[nbrI]);
484 addedFaces.insert(curNbrs[nbrI]);
489 if (completed) break;
504 // It is impossible to reach the end from the start, probably
505 // due to disconnected domain. Do search in opposite direction
507 label nReverseSweeps = 0;
510 addedFaces.insert(endFace);
512 while (nReverseSweeps < edgeFaceEscapeLimit_)
516 if (addedFaces.found(startFace))
521 // Add all face neighbours of face in the map
522 const labelList cf = addedFaces.toc();
527 const labelList& curNbrs = masterFaceFaces[cf[cfI]];
529 forAll (curNbrs, nbrI)
531 if (!curFaceMap.found(curNbrs[nbrI]))
533 curFaceMap.insert(curNbrs[nbrI]);
534 addedFaces.insert(curNbrs[nbrI]);
539 if (completed) break;
565 // Create a map of edges the edge can interact with
566 labelHashSet curMasterEdgesMap
568 nFacesPerSlaveEdge_*primitiveMesh::edgesPerFace_
571 const labelList curFaces = curFaceMap.toc();
572 // Pout << "curFaces: " << curFaces << endl;
573 forAll (curFaces, faceI)
575 // Pout<< "face: " << curFaces[faceI] << " "
576 // << masterPatch[curFaces[faceI]]
578 // << masterPatch.localFaces()[curFaces[faceI]]
580 const labelList& me = masterFaceEdges[curFaces[faceI]];
584 curMasterEdgesMap.insert(me[meI]);
588 const labelList curMasterEdges = curMasterEdgesMap.toc();
590 // For all master edges to intersect, skip the ones
591 // already used and cut the rest with a cutting plane. If
592 // the intersection point, falls inside of both edges, it
595 // Note: The edge cutting code is repeated in
596 // slidingInterface::modifyMotionPoints. This is done for
597 // efficiency reasons and avoids multiple creation of cutting
598 // planes. Please update both simultaneously. HJ, 28/Jul/2003
600 const point& a = projectedSlavePoints[curEdge.start()];
601 const point& b = projectedSlavePoints[curEdge.end()];
606 slaveLocalPoints[curEdge.start()]
607 + slavePointNormals[curEdge.start()] // Add start normal
608 + slaveLocalPoints[curEdge.end()]
609 + slavePointNormals[curEdge.end()] // Add end normal
613 plane cutPlane(a, b, c);
614 // Pout << "a: " << a << " b: " << b << " c: " << c << " plane: " << cutPlane << endl;
616 linePointRef curSlaveLine = curEdge.line(projectedSlavePoints);
617 const scalar curSlaveLineMag = curSlaveLine.mag();
618 // Pout << "curSlaveLine: " << curSlaveLine << endl;
619 forAll (curMasterEdges, masterEdgeI)
621 if (!curUme.found(curMasterEdges[masterEdgeI]))
629 const label cmeIndex = curMasterEdges[masterEdgeI];
630 const edge& cme = masterEdges[cmeIndex];
631 // Pout<< "Edge " << cmeIndex << " cme: " << cme << " line: " << cme.line(masterLocalPoints) << endl;
633 cutPlane.lineIntersect
635 cme.line(masterLocalPoints)
640 cutOnMaster > edgeEndCutoffTol_
641 && cutOnMaster < 1.0 - edgeEndCutoffTol_
644 // Master is cut, check the slave
645 point masterCutPoint =
646 masterLocalPoints[cme.start()]
647 + cutOnMaster*cme.vec(masterLocalPoints);
650 curSlaveLine.nearestDist(masterCutPoint);
654 // Strict checking of slave cut to avoid capturing
655 // end points. HJ, 15/Oct/2004
660 - curSlaveLine.start()
661 ) & curSlaveLine.vec()
662 )/sqr(curSlaveLineMag);
664 // Calculate merge tolerance from the
665 // target edge length
667 edgeCoPlanarTol_*mag(b - a);
668 // Pout<< "cutOnMaster: " << cutOnMaster
669 // << " masterCutPoint: " << masterCutPoint
670 // << " slaveCutPoint: " << slaveCut.hitPoint()
671 // << " slaveCut.distance(): "
672 // << slaveCut.distance()
673 // << " slave length: " << mag(b - a)
674 // << " mergeTol: " << mergeTol
675 // << " 1: " << mag(b - a)
676 // << " 2: " << cme.line(masterLocalPoints).mag()
680 cutOnSlave > edgeEndCutoffTol_
681 && cutOnSlave < 1.0 - edgeEndCutoffTol_
682 && slaveCut.distance() < mergeTol
685 // Cut both master and slave. Add point
686 // to edge points The point is nominally
687 // added from the start of the master edge
688 // and added to the cut point zone
694 masterCutPoint, // point
695 masterMeshPoints[cme.start()],// m p
696 cutPointZoneID_.index(), // zone
700 // Pout << "Inserting point: " << newPoint
701 // << " as edge to edge intersection. "
702 // << "Slave edge: " << edgeI << " "
703 // << curEdge << " master edge: "
704 // << cmeIndex << " " << cme
705 // << " at " << masterCutPoint
706 // << " master point: "
707 // << masterMeshPoints[cme.start()] << endl;
709 pointsIntoSlaveEdges[edgeI].append(newPoint);
710 pointsIntoMasterEdges[cmeIndex].append(newPoint);
712 // Add the point into the enriched patch map
719 // Record which two edges intersect to
723 newPoint, // Cut point index
728 masterMeshPoints[cme.start()],
729 masterMeshPoints[cme.end()]
733 slaveMeshPoints[curEdge.start()],
734 slaveMeshPoints[curEdge.end()]
741 Pout<< " " << newPoint << " = "
742 << masterCutPoint << " ";
749 // Intersection exists but it is too far
767 // Missed master edge
785 } // End if both ends missing
786 } // End for all slave edges
788 // Pout << "pointsIntoMasterEdges: " << pointsIntoMasterEdges << endl;
789 // Pout << "pointsIntoSlaveEdges: " << pointsIntoSlaveEdges << endl;
791 // Re-pack the points into edges lists
792 labelListList pime(pointsIntoMasterEdges.size());
794 forAll (pointsIntoMasterEdges, i)
796 pime[i].transfer(pointsIntoMasterEdges[i].shrink());
799 labelListList pise(pointsIntoSlaveEdges.size());
801 forAll (pointsIntoSlaveEdges, i)
803 pise[i].transfer(pointsIntoSlaveEdges[i].shrink());
806 // Prepare the enriched faces
807 cutPatch.completePointMap();
809 cutPatch.calcEnrichedFaces
818 Info<< "Writing VTK file for enriched faces"
821 fileName fvPath(mesh.time().path()/"VTK");
823 standAlonePatch::writeVTK
825 fvPath/fileName(slaveFaceZoneID_.name() + "EnrichedPatch"),
826 cutPatch.localFaces(),
827 cutPatch.localPoints()
831 const faceList& cutFaces = cutPatch.cutFaces();
832 const labelList& cutFaceMaster = cutPatch.cutFaceMaster();
833 const labelList& cutFaceSlave = cutPatch.cutFaceSlave();
835 const labelList& masterFc = masterFaceCells();
836 const labelList& slaveFc = slaveFaceCells();
840 Info<< "Writing VTK file for cut faces"
843 fileName fvPath(mesh.time().path()/"VTK");
845 standAlonePatch::writeVTK
847 fvPath/fileName(slaveFaceZoneID_.name() + "CutFacesPatch"),
848 cutPatch.localCutFaces(),
849 cutPatch.localPoints()
853 // Couple the interface
856 // 1) Go through the cut faces and check if the cut face is the same as the
857 // defining master or slave. If so, modify the appropriate
858 // face and mark the other for relegation into the face zone.
859 // 2) If different, mark both sides for relegation and insert the new face
862 boolList orphanedMaster(masterPatch.size(), false);
863 boolList orphanedSlave(slavePatch.size(), false);
865 forAll (cutFaces, faceI)
867 const face& curCutFace = cutFaces[faceI];
868 const label curMaster = cutFaceMaster[faceI];
869 const label curSlave = cutFaceSlave[faceI];
871 // Pout<< "Doing insertion of face " << curCutFace << " " << faceI << ": ";
873 // Check if the face has changed topologically
874 bool insertedFace = false;
878 // Face has got a master
879 if (curCutFace == masterPatch[curMaster])
881 // Face is equal to master. Modify master face.
882 // Pout << "Face is equal to master and is ";
884 // If the face has got both master and slave, it is an
885 // internal face; othewise it's a patch face in the
886 // master patch. Keep it in the master face zone.
890 // Pout << "internal ";
891 if (masterFc[curMaster] < slaveFc[curSlave])
893 // Cut face should point into slave.
894 // Be careful about flips in zone!
895 // Pout << "without flip" << endl;
900 curCutFace, // new face
901 masterPatchAddr[curMaster], // master face id
902 masterFc[curMaster], // owner
903 slaveFc[curSlave], // neighbour
906 false, // remove from zone
907 masterFaceZoneID_.index(), // zone ID
908 // Bug fix: HJ, 24/Oct/2007
912 // Pout << "modifying master face. Old master: " << masterPatch[curMaster] << " new face: " << curCutFace.reverseFace() << " own: " << masterFc[curMaster] << " nei: " << slaveFc[curSlave] << endl;
916 // Cut face should point into master. Flip required.
917 // Be careful about flips in zone!
918 // Pout << "flipped" << endl;
923 curCutFace.reverseFace(), // new face
924 masterPatchAddr[curMaster], // master face id
925 slaveFc[curSlave], // owner
926 masterFc[curMaster], // neighbour
929 false, // remove from zone
930 masterFaceZoneID_.index(), // zone ID
931 // Bug fix: HJ, 24/Oct/2007
938 orphanedSlave[curSlave] = true;
946 curCutFace, // new face
947 masterPatchAddr[curMaster], // master face index
948 masterFc[curMaster], // owner
951 masterPatchID_.index(), // patch ID
952 false, // remove from zone
953 masterFaceZoneID_.index(), // zone ID
954 // Bug fix: HJ, 24/Oct/2007
963 else if (curSlave >= 0)
965 // Face has got a slave
967 // Renumber the slave face into merged labels
968 face rsf(slavePatch[curSlave]);
972 Map<label>::const_iterator mpIter = pointMergeMap.find(rsf[i]);
974 if (mpIter != pointMergeMap.end())
980 if (curCutFace == rsf)
982 // Face is equal to slave. Modify slave face.
983 // Pout << "Face is equal to slave and is ";
987 // Pout << "regular internal" << endl;
988 if (masterFc[curMaster] < slaveFc[curSlave])
994 curCutFace, // new face
995 slavePatchAddr[curSlave], // master face id
996 masterFc[curMaster], // owner
997 slaveFc[curSlave], // neighbour
1000 false, // remove from zone
1001 slaveFaceZoneID_.index(), // zone ID
1002 // Bug fix: HJ, 24/Oct/2007
1009 // Cut face should point into master.
1010 // Be careful about flips in zone!
1011 // Pout << "flipped internal" << endl;
1016 curCutFace.reverseFace(), // new face
1017 slavePatchAddr[curSlave], // master face id
1018 slaveFc[curSlave], // owner
1019 masterFc[curMaster], // neighbour
1022 false, // remove from zone
1023 slaveFaceZoneID_.index(), // zone ID
1024 // Bug fix: HJ, 24/Oct/2007
1030 // Orphan the master
1031 orphanedMaster[curMaster] = true;
1035 // Pout << "slave boundary" << endl;
1040 curCutFace, // new face
1041 slavePatchAddr[curSlave], // master face index
1042 slaveFc[curSlave], // owner
1045 slavePatchID_.index(), // patch ID
1046 false, // remove from zone
1047 slaveFaceZoneID_.index(), // zone ID
1048 // Bug fix: HJ, 24/Oct/2007
1054 insertedFace = true;
1061 "void slidingInterface::coupleInterface("
1062 "polyTopoChange& ref) const"
1063 ) << "Face " << faceI << " in cut faces has neither a master "
1064 << "nor a slave. Error in the cutting algorithm on modify."
1065 << abort(FatalError);
1070 // Face is different from both master and slave
1071 // Pout << "Face different from both master and slave" << endl;
1077 // Add internal face
1078 if (masterFc[curMaster] < slaveFc[curSlave])
1080 // Pout << "Adding internal face " << curCutFace << " owner: " << masterFc[curMaster] << " slave: " << slaveFc[curSlave] << " master face: " << masterPatchAddr[curMaster] << endl;
1081 // Cut face should point into slave.
1086 curCutFace, // new face
1087 masterFc[curMaster], // owner
1088 slaveFc[curSlave], // neighbour
1091 masterPatchAddr[curMaster], // master face id
1094 cutFaceZoneID_.index(), // zone ID
1101 // Cut face should point into master. Flip required.
1106 curCutFace.reverseFace(), // new face
1107 slaveFc[curSlave], // owner
1108 masterFc[curMaster], // neighbour
1111 masterPatchAddr[curMaster], // master face id
1114 cutFaceZoneID_.index(), // zone ID
1121 orphanedSlave[curSlave] = true;
1125 // Pout << "Adding solo master face " << curCutFace << " owner: " << masterFc[curMaster] << " master face: " << masterPatchAddr[curMaster] << endl;
1126 // Add master patch face
1131 curCutFace, // new face
1132 masterFc[curMaster], // owner
1136 masterPatchAddr[curMaster], // master face index
1138 masterPatchID_.index(), // patch ID
1139 cutFaceZoneID_.index(), // zone ID
1146 orphanedMaster[curMaster] = true;
1148 else if (curSlave >= 0)
1150 // Pout << "Adding solo slave face " << curCutFace << " owner: " << slaveFc[curSlave] << " master face: " << slavePatchAddr[curSlave] << endl;
1151 // Add slave patch face
1156 curCutFace, // new face
1157 slaveFc[curSlave], // owner
1161 slavePatchAddr[curSlave], // master face index
1163 slavePatchID_.index(), // patch ID
1164 cutFaceZoneID_.index(), // zone ID
1170 orphanedSlave[curSlave] = true;
1176 "void slidingInterface::coupleInterface("
1177 "polyTopoChange& ref) const"
1178 ) << "Face " << faceI << " in cut faces has neither a master "
1179 << "nor a slave. Error in the cutting algorithm on add."
1180 << abort(FatalError);
1185 // Move the orphaned faces into the face zone
1187 label nOrphanedMasters = 0;
1189 forAll (orphanedMaster, faceI)
1191 if (orphanedMaster[faceI])
1195 // vector n = masterPatch[faceI].normal(masterPatch.points());
1196 // Pout << "Doing orphaned master " << faceI << " normal: " << n/mag(n) << endl;
1197 // Recover original orientation
1202 masterPatch[faceI], // new face
1203 masterPatchAddr[faceI], // master face index
1208 false, // remove from zone
1209 masterFaceZoneID_.index(), // zone ID
1216 label nOrphanedSlaves = 0;
1218 forAll (orphanedSlave, faceI)
1220 if (orphanedSlave[faceI])
1223 // Pout<< "Orphaned slave face " << faceI << " "
1224 // << slavePatch[faceI] << endl;
1226 // Recover original orientation
1231 slavePatch[faceI], // new face
1232 slavePatchAddr[faceI], // slave face index
1237 false, // remove from zone
1238 slaveFaceZoneID_.index(), // zone ID
1247 Pout<< "Number of orphaned faces: "
1248 << "master = " << nOrphanedMasters << " out of "
1249 << orphanedMaster.size()
1250 << " slave = " << nOrphanedSlaves << " out of "
1251 << orphanedSlave.size() << endl;
1254 // Finished coupling the plane of sliding interface.
1256 // Modify faces influenced by the sliding interface
1257 // These are the faces belonging to the master and slave cell
1258 // layer which have not already been modified.
1259 // Modification comes in three types:
1260 // 1) eliminate the points that have been removed when the old sliding
1261 // interface has been removed
1262 // 2) Merge the slave points that have hit points on the master patch
1263 // 3) Introduce new points resulting from the new sliding interface cut
1265 // Collect all affected faces
1269 // Grab the list of faces in the layer
1270 const labelList& masterStickOuts = masterStickOutFaces();
1272 // Pout << "masterStickOuts: " << masterStickOuts << endl;
1274 // Re-create the master stick-out faces
1275 forAll (masterStickOuts, faceI)
1277 // Renumber the face and remove additional points
1279 const label curFaceID = masterStickOuts[faceI];
1281 const face& oldRichFace = faces[curFaceID];
1283 bool changed = false;
1285 // Remove removed points from the face
1286 face oldFace(oldRichFace.size());
1289 forAll (oldRichFace, pointI)
1291 if (ref.pointRemoved(oldRichFace[pointI]))
1298 oldFace[nOldFace] = oldRichFace[pointI];
1303 oldFace.setSize(nOldFace);
1305 // Pout<< "old rich master face: " << oldRichFace
1306 // << " old face: " << oldFace << endl;
1307 DynamicList<label> newFaceLabels(2*oldFace.size());
1309 forAll (oldFace, pointI)
1311 if (masterMeshPointMap.found(oldFace[pointI]))
1313 // Point is in master patch. Add it
1315 // If the point is a direct hit, grab its label; otherwise
1316 // keep the original
1317 if (pointMergeMap.found(oldFace[pointI]))
1320 newFaceLabels.append
1322 pointMergeMap.find(oldFace[pointI])()
1327 newFaceLabels.append(oldFace[pointI]);
1330 // Find if there are additional points inserted onto the edge
1331 // between current point and the next point
1333 // 1) Find all the edges in the master patch coming
1334 // out of the current point.
1335 // 2) If the next point in the face to pick the right edge
1336 const label localFirstLabel =
1337 masterMeshPointMap.find(oldFace[pointI])();
1339 const labelList& curEdges = masterPointEdges[localFirstLabel];
1341 const label nextLabel = oldFace.nextLabel(pointI);
1343 Map<label>::const_iterator mmpmIter =
1344 masterMeshPointMap.find(nextLabel);
1346 if (mmpmIter != masterMeshPointMap.end())
1348 // Pout<< "found label pair " << oldFace[pointI]
1349 // << " and " << nextLabel;
1350 // Find the points on the edge between them
1351 const label localNextLabel = mmpmIter();
1353 forAll (curEdges, curEdgeI)
1357 masterEdges[curEdges[curEdgeI]].otherVertex
1364 // Pout<< " found edge: " << curEdges[curEdgeI]
1367 // Get points on current edge
1368 const labelList& curPime =
1369 pime[curEdges[curEdgeI]];
1371 if (curPime.size() > 0)
1374 // Pout << "curPime: " << curPime << endl;
1375 // Insert the edge points into the face
1376 // in the correct order
1377 const point& startPoint =
1378 masterLocalPoints[localFirstLabel];
1381 masterLocalPoints[localNextLabel]
1386 scalarField edgePointWeights(curPime.size());
1388 forAll (curPime, curPimeI)
1390 edgePointWeights[curPimeI] =
1394 pointMap.find(curPime[curPimeI])()
1404 min(edgePointWeights) < 0
1405 || max(edgePointWeights) > 1
1410 "void slidingInterface::"
1412 "polyTopoChange& ref) const"
1413 ) << "Error in master stick-out edge "
1414 << "point collection."
1415 << abort(FatalError);
1419 // Go through the points and collect
1420 // them based on weights from lower to
1421 // higher. This gives the correct
1422 // order of points along the edge.
1426 passI < edgePointWeights.size();
1430 // Max weight can only be one, so
1431 // the sorting is done by
1433 label nextPoint = -1;
1436 forAll (edgePointWeights, wI)
1438 if (edgePointWeights[wI] < dist)
1440 dist = edgePointWeights[wI];
1445 // Insert the next point and reset
1446 // its weight to exclude it from
1448 newFaceLabels.append(curPime[nextPoint]);
1449 edgePointWeights[nextPoint] = GREAT;
1454 } // End of found edge
1455 } // End of looking through current edges
1460 newFaceLabels.append(oldFace[pointI]);
1466 if (newFaceLabels.size() < 3)
1470 "void slidingInterface::coupleInterface("
1471 "polyTopoChange& ref) const"
1472 ) << "Face " << curFaceID << " reduced to less than "
1473 << "3 points. Topological/cutting error A." << nl
1474 << "Old face: " << oldFace << " new face: " << newFaceLabels
1475 << abort(FatalError);
1478 // Get face zone and its flip
1479 label modifiedFaceZone = faceZones.whichZone(curFaceID);
1480 bool modifiedFaceZoneFlip = false;
1482 if (modifiedFaceZone >= 0)
1484 modifiedFaceZoneFlip =
1485 faceZones[modifiedFaceZone].flipMap()
1487 faceZones[modifiedFaceZone].whichFace(curFaceID)
1492 newFace.transfer(newFaceLabels.shrink());
1494 // Pout<< "Modifying master stick-out face " << curFaceID
1495 // << " old face: " << oldFace
1496 // << " new face: " << newFace << endl;
1499 label neiIndex = -1;
1500 if (mesh.isInternalFace(curFaceID))
1502 neiIndex = nei[curFaceID];
1509 newFace, // modified face
1510 curFaceID, // label of face being modified
1511 own[curFaceID], // owner
1512 neiIndex, // neighbour
1514 mesh.boundaryMesh().whichPatch(curFaceID), // patch for face
1515 false, // remove from zone
1516 modifiedFaceZone, // zone for face
1517 modifiedFaceZoneFlip // face flip in zone
1523 // Pout << "Finished master side" << endl;
1527 // Grab the list of faces in the layer
1528 const labelList& slaveStickOuts = slaveStickOutFaces();
1530 // Pout << "slaveStickOuts: " << slaveStickOuts << endl;
1532 const Map<label>& rpm = retiredPointMap();
1534 // Re-create the slave stick-out faces
1536 forAll (slaveStickOuts, faceI)
1538 // Renumber the face and remove additional points
1539 const label curFaceID = slaveStickOuts[faceI];
1541 const face& oldRichFace = faces[curFaceID];
1543 bool changed = false;
1545 // Remove removed points from the face
1546 face oldFace(oldRichFace.size());
1549 forAll (oldRichFace, pointI)
1553 rpm.found(oldRichFace[pointI])
1554 || slaveMeshPointMap.found(oldRichFace[pointI])
1557 // Point definitely live. Add it
1558 oldFace[nOldFace] = oldRichFace[pointI];
1563 ref.pointRemoved(oldRichFace[pointI])
1564 || masterMeshPointMap.found(oldRichFace[pointI])
1567 // Point removed and not on slave patch
1568 // (first if takes care of that!) or
1569 // point belonging to master patch
1575 oldFace[nOldFace] = oldRichFace[pointI];
1580 oldFace.setSize(nOldFace);
1582 DynamicList<label> newFaceLabels(2*oldFace.size());
1584 // Pout << "old rich slave face: " << oldRichFace << " old face: " << oldFace << endl;
1585 forAll (oldFace, pointI)
1587 // Try to find the point in retired points
1588 label curP = oldFace[pointI];
1590 Map<label>::const_iterator rpmIter = rpm.find(oldFace[pointI]);
1592 if (rpmIter != rpm.end())
1598 if (slaveMeshPointMap.found(curP))
1600 // Point is in slave patch. Add it
1602 // If the point is a direct hit, grab its label; otherwise
1603 // keep the original
1604 if (pointMergeMap.found(curP))
1607 newFaceLabels.append
1609 pointMergeMap.find(curP)()
1614 newFaceLabels.append(curP);
1617 // Find if there are additional points inserted onto the edge
1618 // between current point and the next point
1620 // 1) Find all the edges in the slave patch coming
1621 // out of the current point.
1622 // 2) Use the next point in the face to pick the right edge
1624 const label localFirstLabel =
1625 slaveMeshPointMap.find(curP)();
1627 const labelList& curEdges = slavePointEdges[localFirstLabel];
1629 label nextLabel = oldFace.nextLabel(pointI);
1631 Map<label>::const_iterator rpmNextIter =
1632 rpm.find(nextLabel);
1634 if (rpmNextIter != rpm.end())
1636 nextLabel = rpmNextIter();
1639 Map<label>::const_iterator mmpmIter =
1640 slaveMeshPointMap.find(nextLabel);
1642 if (mmpmIter != slaveMeshPointMap.end())
1644 // Both points on the slave patch.
1645 // Find the points on the edge between them
1646 const label localNextLabel = mmpmIter();
1648 forAll (curEdges, curEdgeI)
1652 slaveEdges[curEdges[curEdgeI]].otherVertex
1659 // Pout << " found edge: " << curEdges[curEdgeI] << endl;
1661 // Get points on current edge
1662 const labelList& curPise = pise[curEdges[curEdgeI]];
1664 if (curPise.size() > 0)
1667 // Pout << "curPise: " << curPise << endl;
1668 // Insert the edge points into the face
1669 // in the correct order
1670 const point& startPoint =
1671 projectedSlavePoints[localFirstLabel];
1674 projectedSlavePoints[localNextLabel]
1679 scalarField edgePointWeights(curPise.size());
1681 forAll (curPise, curPiseI)
1683 edgePointWeights[curPiseI] =
1687 pointMap.find(curPise[curPiseI])()
1697 min(edgePointWeights) < 0
1698 || max(edgePointWeights) > 1
1703 "void slidingInterface::"
1705 "polyTopoChange& ref) const"
1706 ) << "Error in slave stick-out edge "
1707 << "point collection."
1708 << abort(FatalError);
1712 // Go through the points and collect
1713 // them based on weights from lower to
1714 // higher. This gives the correct
1715 // order of points along the edge.
1719 passI < edgePointWeights.size();
1723 // Max weight can only be one, so
1724 // the sorting is done by
1726 label nextPoint = -1;
1729 forAll (edgePointWeights, wI)
1731 if (edgePointWeights[wI] < dist)
1733 dist = edgePointWeights[wI];
1738 // Insert the next point and reset
1739 // its weight to exclude it from
1741 newFaceLabels.append(curPise[nextPoint]);
1742 edgePointWeights[nextPoint] = GREAT;
1748 } // End of found edge
1749 } // End of looking through current edges
1753 newFaceLabels.append(oldFace[pointI]);
1759 if (newFaceLabels.size() < 3)
1763 "void slidingInterface::coupleInterface("
1764 "polyTopoChange& ref) const"
1765 ) << "Face " << curFaceID << " reduced to less than "
1766 << "3 points. Topological/cutting error B." << nl
1767 << "Old face: " << oldFace << " new face: " << newFaceLabels
1768 << abort(FatalError);
1771 // Get face zone and its flip
1772 label modifiedFaceZone = faceZones.whichZone(curFaceID);
1773 bool modifiedFaceZoneFlip = false;
1775 if (modifiedFaceZone >= 0)
1777 modifiedFaceZoneFlip =
1778 faceZones[modifiedFaceZone].flipMap()
1780 faceZones[modifiedFaceZone].whichFace(curFaceID)
1785 newFace.transfer(newFaceLabels.shrink());
1787 // Pout << "Modifying slave stick-out face " << curFaceID << " old face: " << oldFace << " new face: " << newFace << endl;
1790 label neiIndex = -1;
1791 if (mesh.isInternalFace(curFaceID))
1793 neiIndex = nei[curFaceID];
1800 newFace, // modified face
1801 curFaceID, // label of face being modified
1802 own[curFaceID], // owner
1803 neiIndex, // neighbour
1805 mesh.boundaryMesh().whichPatch(curFaceID), // patch for face
1806 false, // remove from zone
1807 modifiedFaceZone, // zone for face
1808 modifiedFaceZoneFlip // face flip in zone
1814 // Activate and retire slave patch points
1815 // This needs to be done last, so that the map of removed points
1816 // does not get damaged by point modifications
1818 if (!retiredPointMapPtr_)
1822 "void slidingInterface::coupleInterface("
1823 "polyTopoChange& ref) const"
1824 ) << "Retired point map pointer not set."
1825 << abort(FatalError);
1828 Map<label>& addToRpm = *retiredPointMapPtr_;
1830 // Clear the old map
1833 label nRetiredPoints = 0;
1835 forAll (slaveMeshPoints, pointI)
1837 if (pointMergeMap.found(slaveMeshPoints[pointI]))
1839 // Retire the point - only used for supporting the detached
1842 // Pout<< "Retired point " << slaveMeshPoints[pointI] << " "
1843 // << points[slaveMeshPoints[pointI]] << " Merged into "
1844 // << pointMergeMap.find(slaveMeshPoints[pointI])()
1845 // << " belongs to zone "
1846 // << mesh.pointZones().whichZone(slaveMeshPoints[pointI])
1852 slaveMeshPoints[pointI], // point ID
1853 points[slaveMeshPoints[pointI]], // point
1854 false, // remove from zone
1855 mesh.pointZones().whichZone(slaveMeshPoints[pointI]),// zone
1862 pointMergeMap.find(slaveMeshPoints[pointI])(),
1863 slaveMeshPoints[pointI]
1868 // Pout<< "Touching point " << slaveMeshPoints[pointI] << " at "
1869 // << points[slaveMeshPoints[pointI]] << " zone "
1870 // << mesh.pointZones().whichZone(slaveMeshPoints[pointI])
1872 //HJ This does nothing? HJ, 17/Dec/2008
1877 slaveMeshPoints[pointI], // point ID
1878 points[slaveMeshPoints[pointI]], // point
1879 false, // remove from zone
1880 mesh.pointZones().whichZone(slaveMeshPoints[pointI]),// zone
1889 Pout << "Retired " << nRetiredPoints << " out of "
1890 << slaveMeshPoints.size() << " points." << endl;
1893 // Grab cut face master and slave addressing
1894 if (cutFaceMasterPtr_) deleteDemandDrivenData(cutFaceMasterPtr_);
1895 cutFaceMasterPtr_ = new labelList(cutPatch.cutFaceMaster());
1897 if (cutFaceSlavePtr_) deleteDemandDrivenData(cutFaceSlavePtr_);
1898 cutFaceSlavePtr_ = new labelList(cutPatch.cutFaceSlave());
1900 // Finished coupling
1905 Pout<< "void slidingInterface::coupleInterface("
1906 << "polyTopoChange& ref) : "
1907 << "Finished coupling sliding interface " << name() << endl;
1912 // ************************************************************************* //