FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

coupleSlidingInterface.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "slidingInterface.H"
00027 #include <dynamicMesh/polyTopoChange.H>
00028 #include <OpenFOAM/polyMesh.H>
00029 #include <OpenFOAM/primitiveMesh.H>
00030 #include <dynamicMesh/enrichedPatch.H>
00031 #include <OpenFOAM/DynamicList.H>
00032 #include <OpenFOAM/pointHit.H>
00033 #include <OpenFOAM/triPointRef.H>
00034 #include <OpenFOAM/plane.H>
00035 #include <dynamicMesh/polyTopoChanger.H>
00036 #include <dynamicMesh/polyAddPoint.H>
00037 #include <dynamicMesh/polyRemovePoint.H>
00038 #include <dynamicMesh/polyAddFace.H>
00039 #include <dynamicMesh/polyModifyPoint.H>
00040 #include <dynamicMesh/polyModifyFace.H>
00041 #include <dynamicMesh/polyRemoveFace.H>
00042 
00043 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00044 
00045 const Foam::scalar Foam::slidingInterface::edgeCoPlanarTolDefault_ = 0.8;
00046 
00047 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00048 
00049 // Index of debug signs:
00050 // Index of debug signs:
00051 // . - loop of the edge-to-face interaction detection
00052 // x - reversal of direction in edge-to-face interaction detection
00053 // + - complete edge-to-face interaction detection
00054 // z - incomplete edge-to-face interaction detection.  This may be OK for edges
00055 //     crossing from one to the other side of multiply connected master patch
00056 
00057 // e - adding a point on edge
00058 // f - adding a point on face
00059 // . - collecting edges off another face for edge-to-edge cut
00060 // + - finished collection of edges
00061 // * - cut both master and slave
00062 // n - cutting new edge
00063 // t - intersection exists but it is outside of tolerance
00064 // x - missed slave edge in cut
00065 // - - missed master edge in cut
00066 // u - edge already used in cutting
00067 
00068 void Foam::slidingInterface::coupleInterface(polyTopoChange& ref) const
00069 {
00070     if (debug)
00071     {
00072         Pout<< "void slidingInterface::coupleInterface"
00073             << "(polyTopoChange& ref) : "
00074             << "Coupling sliding interface " << name() << endl;
00075     }
00076 
00077     const polyMesh& mesh = topoChanger().mesh();
00078 
00079     const pointField& points = mesh.points();
00080     const faceList& faces = mesh.faces();
00081 
00082     const labelList& own = mesh.faceOwner();
00083     const labelList& nei = mesh.faceNeighbour();
00084     const faceZoneMesh& faceZones = mesh.faceZones();
00085 
00086     const primitiveFacePatch& masterPatch =
00087         faceZones[masterFaceZoneID_.index()]();
00088 
00089     const labelList& masterPatchAddr = faceZones[masterFaceZoneID_.index()];
00090 
00091     const boolList& masterPatchFlip =
00092         faceZones[masterFaceZoneID_.index()].flipMap();
00093 
00094     const primitiveFacePatch& slavePatch =
00095         faceZones[slaveFaceZoneID_.index()]();
00096 
00097     const labelList& slavePatchAddr = faceZones[slaveFaceZoneID_.index()];
00098 
00099     const boolList& slavePatchFlip =
00100         faceZones[slaveFaceZoneID_.index()].flipMap();
00101 
00102     const edgeList& masterEdges = masterPatch.edges();
00103     const labelListList& masterPointEdges = masterPatch.pointEdges();
00104     const labelList& masterMeshPoints = masterPatch.meshPoints();
00105     const pointField& masterLocalPoints = masterPatch.localPoints();
00106     const labelListList& masterFaceFaces = masterPatch.faceFaces();
00107     const labelListList& masterFaceEdges = masterPatch.faceEdges();
00108     const Map<label>& masterMeshPointMap = masterPatch.meshPointMap();
00109 
00110     const edgeList& slaveEdges = slavePatch.edges();
00111     const labelListList& slavePointEdges = slavePatch.pointEdges();
00112     const labelList& slaveMeshPoints = slavePatch.meshPoints();
00113     const pointField& slaveLocalPoints = slavePatch.localPoints();
00114     const Map<label>& slaveMeshPointMap = slavePatch.meshPointMap();
00115     const vectorField& slavePointNormals = slavePatch.pointNormals();
00116 
00117     // Collect projection addressing
00118     if
00119     (
00120         !(
00121             slavePointPointHitsPtr_
00122          && slavePointEdgeHitsPtr_
00123          && slavePointFaceHitsPtr_
00124          && masterPointEdgeHitsPtr_
00125         )
00126     )
00127     {
00128         FatalErrorIn
00129         (
00130             "void slidingInterface::coupleInterface("
00131             "polyTopoChange& ref) const"
00132         )   << "Point projection addressing not available."
00133             << abort(FatalError);
00134     }
00135 
00136     const labelList& slavePointPointHits = *slavePointPointHitsPtr_;
00137     const labelList& slavePointEdgeHits = *slavePointEdgeHitsPtr_;
00138     const List<objectHit>& slavePointFaceHits = *slavePointFaceHitsPtr_;
00139     const labelList& masterPointEdgeHits = *masterPointEdgeHitsPtr_;
00140     const pointField& projectedSlavePoints = *projectedSlavePointsPtr_;
00141 
00142     // Create enriched patch
00143     enrichedPatch cutPatch
00144     (
00145         masterPatch,
00146         slavePatch,
00147         slavePointPointHits,
00148         slavePointEdgeHits,
00149         slavePointFaceHits
00150     );
00151 
00152     // Get reference to list of added point for the enriched patch.
00153     // This will be used for point addition
00154     Map<point>& pointMap = cutPatch.pointMap();
00155 
00156     // Get reference to the list of merged points
00157     Map<label>& pointMergeMap = cutPatch.pointMergeMap();
00158 
00159     // Create mapping for every merged point of the slave patch
00160     forAll (slavePointPointHits, pointI)
00161     {
00162         if (slavePointPointHits[pointI] >= 0)
00163         {
00164 // Pout << "Inserting point merge pair: " << slaveMeshPoints[pointI] << " : " << masterMeshPoints[slavePointPointHits[pointI]] << endl;
00165             pointMergeMap.insert
00166             (
00167                 slaveMeshPoints[pointI],
00168                 masterMeshPoints[slavePointPointHits[pointI]]
00169             );
00170         }
00171     }
00172 
00173     // Collect the list of used edges for every slave edge
00174 
00175     List<labelHashSet> usedMasterEdges(slaveEdges.size());
00176 
00177     // Collect of slave point hits
00178     forAll (slavePointPointHits, pointI)
00179     {
00180         // For point hits, add all point-edges from master side to all point
00181         const labelList& curSlaveEdges = slavePointEdges[pointI];
00182 
00183         if (slavePointPointHits[pointI] > -1)
00184         {
00185             const labelList& curMasterEdges =
00186                 masterPointEdges[slavePointPointHits[pointI]];
00187 
00188             // Mark all current master edges as used for all the current slave
00189             // edges
00190             forAll (curSlaveEdges, slaveEdgeI)
00191             {
00192                 labelHashSet& sm = usedMasterEdges[curSlaveEdges[slaveEdgeI]];
00193 
00194                 forAll (curMasterEdges, masterEdgeI)
00195                 {
00196                     sm.insert(curMasterEdges[masterEdgeI]);
00197                 }
00198             }
00199         }
00200         else if (slavePointEdgeHits[pointI] > -1)
00201         {
00202             // For edge hits, add the master edge
00203             forAll (curSlaveEdges, slaveEdgeI)
00204             {
00205                 usedMasterEdges[curSlaveEdges[slaveEdgeI]].insert
00206                 (
00207                     slavePointEdgeHits[pointI]
00208                 );
00209             }
00210         }
00211     }
00212 
00213     // Collect off master point hits
00214     // For every master point that has hit an edge, add all edges coming from
00215     // that point to the slave edge that has been hit
00216     forAll (masterPointEdgeHits, masterPointI)
00217     {
00218         if (masterPointEdgeHits[masterPointI] > -1)
00219         {
00220             const labelList& curMasterEdges = masterPointEdges[masterPointI];
00221 
00222             labelHashSet& sm =
00223                 usedMasterEdges[masterPointEdgeHits[masterPointI]];
00224 
00225             forAll (curMasterEdges, masterEdgeI)
00226             {
00227                 sm.insert(curMasterEdges[masterEdgeI]);
00228             }
00229         }
00230     }
00231 
00232 //     Pout << "used edges: " << endl;
00233 //     forAll (usedMasterEdges, edgeI)
00234 //     {
00235 //         Pout << "edge: " << edgeI << " used: " << usedMasterEdges[edgeI].toc() << endl;
00236 //     }
00237 
00238     // For every master and slave edge make a list of points to be added into
00239     // that edge.
00240     List<DynamicList<label> > pointsIntoMasterEdges(masterEdges.size());
00241     List<DynamicList<label> > pointsIntoSlaveEdges(slaveEdges.size());
00242 
00243     // Add all points from the slave patch that have hit the edge
00244     forAll (slavePointEdgeHits, pointI)
00245     {
00246         if (slavePointEdgeHits[pointI] > -1)
00247         {
00248             // Create a new point on the master edge
00249 
00250             point edgeCutPoint =
00251                 masterEdges[slavePointEdgeHits[pointI]].line
00252                 (
00253                     masterLocalPoints
00254                 ).nearestDist(projectedSlavePoints[pointI]).hitPoint();
00255 
00256             label newPoint =
00257                 ref.setAction
00258                 (
00259                     polyAddPoint
00260                     (
00261                         edgeCutPoint,             // point
00262                         slaveMeshPoints[pointI],  // master point
00263                         cutPointZoneID_.index(),  // zone for point
00264                         true                      // supports a cell
00265                     )
00266                 );
00267 //             Pout << "Inserting merge pair off edge: " << slaveMeshPoints[pointI] << " " << newPoint << " cut point: " << edgeCutPoint << " orig: " << slaveLocalPoints[pointI] << " proj: " << projectedSlavePoints[pointI] << endl;
00268             // Add the new edge point into the merge map
00269             pointMergeMap.insert(slaveMeshPoints[pointI], newPoint);
00270 
00271             pointsIntoMasterEdges[slavePointEdgeHits[pointI]].append
00272             (
00273                 newPoint
00274             );
00275 
00276             // Add the point into the enriched patch map
00277             pointMap.insert
00278             (
00279                 newPoint,
00280                 edgeCutPoint
00281             );
00282 
00283             if (debug)
00284             {
00285                 Pout<< "e";
00286 //                 Pout<< newPoint << " = " << edgeCutPoint << endl;
00287             }
00288         }
00289     }
00290 
00291     if (debug)
00292     {
00293         Pout<< endl;
00294     }
00295 
00296     // Add all points from the slave patch that have hit a face
00297     forAll (slavePointFaceHits, pointI)
00298     {
00299         if
00300         (
00301             slavePointPointHits[pointI] < 0
00302          && slavePointEdgeHits[pointI] < 0
00303          && slavePointFaceHits[pointI].hit()
00304         )
00305         {
00306             label newPoint =
00307                 ref.setAction
00308                 (
00309                     polyAddPoint
00310                     (
00311                         projectedSlavePoints[pointI],   // point
00312                         slaveMeshPoints[pointI],        // master point
00313                         cutPointZoneID_.index(),        // zone for point
00314                         true                            // supports a cell
00315                     )
00316                 );
00317 //             Pout << "Inserting merge pair off face: " << slaveMeshPoints[pointI] << " " << newPoint << endl;
00318             // Add the new edge point into the merge map
00319             pointMergeMap.insert(slaveMeshPoints[pointI], newPoint);
00320 
00321             // Add the point into the enriched patch map
00322             pointMap.insert
00323             (
00324                 newPoint,
00325                 projectedSlavePoints[pointI]
00326             );
00327 
00328             if (debug)
00329             {
00330                 Pout<< "f: " << newPoint << " = "
00331                     << projectedSlavePoints[pointI] << endl;
00332             }
00333         }
00334     }
00335 
00336     forAll (masterPointEdgeHits, pointI)
00337     {
00338         if (masterPointEdgeHits[pointI] > -1)
00339         {
00340             pointsIntoSlaveEdges[masterPointEdgeHits[pointI]].append
00341             (
00342                 masterMeshPoints[pointI]
00343             );
00344         }
00345     }
00346 
00347     // Cut all slave edges.
00348     // Collect all master edges the slave edge interacts with.  Skip
00349     // all the edges already marked as used.  For every unused edge,
00350     // calculate the cut and insert the new point into the master and
00351     // slave edge.
00352     // For the edge selection algorithm, see, comment in
00353     // slidingInterfaceProjectPoints.C.
00354     // Edge cutting algoritm:
00355     // As the master patch defines the cutting surface, the newly
00356     // inserted point needs to be on the master edge.  Also, in 3-D
00357     // the pair of edges generally misses each other rather than
00358     // intersect.  Therefore, the intersection is calculated using the
00359     // plane the slave edge defines during projection.  The plane is
00360     // defined by the centrepoint of the edge in the original
00361     // configuration and the projected end points.  In case of flat
00362     // geometries (when the three points are colinear), the plane is
00363     // defined by the two projected end-points and the slave edge
00364     // normal used as the in-plane vector.  When the intersection
00365     // point is created, it is added as a new point for both the
00366     // master and the slave edge.
00367     // In order to be able to re-create the points on edges in mesh
00368     // motion without the topology change, the edge pair used to
00369     // create the cut point needs to be recorded in
00370     // cutPointEdgePairMap
00371 
00372     // Note.  "Processing slave edges" code is repeated twice in the
00373     // sliding intergace coupling in order to allow the point
00374     // projection to be done separately from the actual cutting.
00375     // Please change consistently with slidingInterfaceProjectPoints.C
00376     //
00377     if (debug)
00378     {
00379         Pout << "Processing slave edges " << endl;
00380     }
00381 
00382     if (!cutPointEdgePairMapPtr_)
00383     {
00384         FatalErrorIn
00385         (
00386             "void slidingInterface::coupleInterface("
00387             "polyTopoChange& ref) const"
00388         )   << "Cut point edge pair map pointer not set."
00389             << abort(FatalError);
00390     }
00391 
00392     Map<Pair<edge> >& addToCpepm = *cutPointEdgePairMapPtr_;
00393 
00394     // Clear the old map
00395     addToCpepm.clear();
00396 
00397     // Create a map of faces the edge can interact with
00398     labelHashSet curFaceMap
00399     (
00400         nFacesPerSlaveEdge_*primitiveMesh::edgesPerFace_
00401     );
00402 
00403     labelHashSet addedFaces(2*primitiveMesh::edgesPerFace_);
00404 
00405     forAll (slaveEdges, edgeI)
00406     {
00407         const edge& curEdge = slaveEdges[edgeI];
00408 
00409         if
00410         (
00411             slavePointFaceHits[curEdge.start()].hit()
00412          || slavePointFaceHits[curEdge.end()].hit()
00413         )
00414         {
00415             labelHashSet& curUme = usedMasterEdges[edgeI];
00416 //             Pout<< "Doing edge " << edgeI << " curEdge: " << curEdge << " curUme: " << curUme << endl;
00417             // Clear the maps
00418             curFaceMap.clear();
00419             addedFaces.clear();
00420 
00421             // Grab the faces for start and end points.
00422             const label startFace =
00423                 slavePointFaceHits[curEdge.start()].hitObject();
00424             const label endFace = slavePointFaceHits[curEdge.end()].hitObject();
00425 //             Pout << "startFace: " << slavePointFaceHits[curEdge.start()] << " endFace: " << slavePointFaceHits[curEdge.end()] << endl;
00426             // Insert the start face into the list
00427             curFaceMap.insert(startFace);
00428             addedFaces.insert(startFace);
00429 //             Pout << "curFaceMap: " << curFaceMap.toc() << endl;
00430             label nSweeps = 0;
00431             bool completed = false;
00432 
00433             while (nSweeps < edgeFaceEscapeLimit_)
00434             {
00435                 nSweeps++;
00436 
00437                 if (addedFaces.found(endFace))
00438                 {
00439                     completed = true;
00440                 }
00441 
00442                 // Add all face neighbours of face in the map
00443                 const labelList cf = addedFaces.toc();
00444                 addedFaces.clear();
00445 
00446                 forAll (cf, cfI)
00447                 {
00448                     const labelList& curNbrs = masterFaceFaces[cf[cfI]];
00449 
00450                     forAll (curNbrs, nbrI)
00451                     {
00452                         if (!curFaceMap.found(curNbrs[nbrI]))
00453                         {
00454                             curFaceMap.insert(curNbrs[nbrI]);
00455                             addedFaces.insert(curNbrs[nbrI]);
00456                         }
00457                     }
00458                 }
00459 
00460                 if (completed) break;
00461 
00462                 if (debug)
00463                 {
00464                     Pout << ".";
00465                 }
00466             }
00467 
00468             if (!completed)
00469             {
00470                 if (debug)
00471                 {
00472                     Pout << "x";
00473                 }
00474 
00475                 // It is impossible to reach the end from the start, probably
00476                 // due to disconnected domain.  Do search in opposite direction
00477 
00478                 label nReverseSweeps = 0;
00479 
00480                 addedFaces.clear();
00481                 addedFaces.insert(endFace);
00482 
00483                 while (nReverseSweeps < edgeFaceEscapeLimit_)
00484                 {
00485                     nReverseSweeps++;
00486 
00487                     if (addedFaces.found(startFace))
00488                     {
00489                         completed = true;
00490                     }
00491 
00492                     // Add all face neighbours of face in the map
00493                     const labelList cf = addedFaces.toc();
00494                     addedFaces.clear();
00495 
00496                     forAll (cf, cfI)
00497                     {
00498                         const labelList& curNbrs = masterFaceFaces[cf[cfI]];
00499 
00500                         forAll (curNbrs, nbrI)
00501                         {
00502                             if (!curFaceMap.found(curNbrs[nbrI]))
00503                             {
00504                                 curFaceMap.insert(curNbrs[nbrI]);
00505                                 addedFaces.insert(curNbrs[nbrI]);
00506                             }
00507                         }
00508                     }
00509 
00510                     if (completed) break;
00511 
00512                     if (debug)
00513                     {
00514                         Pout << ".";
00515                     }
00516                 }
00517             }
00518 
00519             if (completed)
00520             {
00521                 if (debug)
00522                 {
00523                     Pout << "+ ";
00524                 }
00525             }
00526             else
00527             {
00528                 if (debug)
00529                 {
00530                     Pout << "z ";
00531                 }
00532             }
00533 
00534             // Collect the edges
00535 
00536             // Create a map of edges the edge can interact with
00537             labelHashSet curMasterEdgesMap
00538             (
00539                 nFacesPerSlaveEdge_*primitiveMesh::edgesPerFace_
00540             );
00541 
00542             const labelList curFaces = curFaceMap.toc();
00543 //             Pout << "curFaces: " << curFaces << endl;
00544             forAll (curFaces, faceI)
00545             {
00546 //                 Pout<< "face: " << curFaces[faceI] << " "
00547 //                     << masterPatch[curFaces[faceI]]
00548 //                     << " local: "
00549 //                     << masterPatch.localFaces()[curFaces[faceI]]
00550 //                     << endl;
00551                 const labelList& me = masterFaceEdges[curFaces[faceI]];
00552 
00553                 forAll (me, meI)
00554                 {
00555                     curMasterEdgesMap.insert(me[meI]);
00556                 }
00557             }
00558 
00559             const labelList curMasterEdges = curMasterEdgesMap.toc();
00560 
00561             // For all master edges to intersect, skip the ones
00562             // already used and cut the rest with a cutting plane.  If
00563             // the intersection point, falls inside of both edges, it
00564             // is valid.
00565 
00566             // Note.
00567             // The edge cutting code is repeated in
00568             // slidingInterface::modifyMotionPoints.  This is done for
00569             // efficiency reasons and avoids multiple creation of cutting
00570             // planes.  Please update both simultaneously.
00571 
00572             const point& a = projectedSlavePoints[curEdge.start()];
00573             const point& b = projectedSlavePoints[curEdge.end()];
00574 
00575             point c =
00576                 0.5*
00577                 (
00578                     slaveLocalPoints[curEdge.start()]
00579                   + slavePointNormals[curEdge.start()] // Add start normal
00580                   + slaveLocalPoints[curEdge.end()]
00581                   + slavePointNormals[curEdge.end()] // Add end normal
00582                 );
00583 
00584             // Create the plane
00585             plane cutPlane(a, b, c);
00586 //             Pout << "a: " << a << " b: " << b << " c: " << c << " plane: " << cutPlane << endl;
00587 
00588             linePointRef curSlaveLine = curEdge.line(projectedSlavePoints);
00589             const scalar curSlaveLineMag = curSlaveLine.mag();
00590 //             Pout << "curSlaveLine: " << curSlaveLine << endl;
00591             forAll (curMasterEdges, masterEdgeI)
00592             {
00593                 if (!curUme.found(curMasterEdges[masterEdgeI]))
00594                 {
00595                     // New edge
00596                     if (debug)
00597                     {
00598                         Pout << "n";
00599                     }
00600 
00601                     const label cmeIndex = curMasterEdges[masterEdgeI];
00602                     const edge& cme = masterEdges[cmeIndex];
00603 //                     Pout<< "Edge " << cmeIndex << " cme: " << cme << " line: " << cme.line(masterLocalPoints) << endl;
00604                     scalar cutOnMaster =
00605                         cutPlane.lineIntersect
00606                         (
00607                             cme.line(masterLocalPoints)
00608                         );
00609 
00610                     if
00611                     (
00612                         cutOnMaster > edgeEndCutoffTol_
00613                      && cutOnMaster < 1.0 - edgeEndCutoffTol_
00614                     )
00615                     {
00616                         // Master is cut, check the slave
00617                         point masterCutPoint =
00618                             masterLocalPoints[cme.start()]
00619                           + cutOnMaster*cme.vec(masterLocalPoints);
00620 
00621                         pointHit slaveCut =
00622                             curSlaveLine.nearestDist(masterCutPoint);
00623 
00624                         if (slaveCut.hit())
00625                         {
00626                             // Strict checking of slave cut to avoid capturing
00627                             // end points.
00628                             scalar cutOnSlave =
00629                                 (
00630                                     (
00631                                         slaveCut.hitPoint()
00632                                       - curSlaveLine.start()
00633                                     ) & curSlaveLine.vec()
00634                                 )/sqr(curSlaveLineMag);
00635 
00636                             // Calculate merge tolerance from the
00637                             // target edge length
00638                             scalar mergeTol =
00639                                 edgeCoPlanarTol_*mag(b - a);
00640 //                             Pout << "cutOnMaster: " << cutOnMaster << " masterCutPoint: " << masterCutPoint << " slaveCutPoint: " << slaveCut.hitPoint() << " slaveCut.distance(): " << slaveCut.distance() << " slave length: " << mag(b - a) << " mergeTol: " << mergeTol << " 1: " << mag(b - a) << " 2: " << cme.line(masterLocalPoints).mag() << endl;
00641                             if
00642                             (
00643                                 cutOnSlave > edgeEndCutoffTol_
00644                              && cutOnSlave < 1.0 - edgeEndCutoffTol_
00645                              && slaveCut.distance() < mergeTol
00646                             )
00647                             {
00648                                 // Cut both master and slave.  Add point
00649                                 // to edge points The point is nominally
00650                                 // added from the start of the master edge
00651                                 // and added to the cut point zone
00652                                 label newPoint =
00653                                     ref.setAction
00654                                     (
00655                                         polyAddPoint
00656                                         (
00657                                             masterCutPoint,           // point
00658                                             masterMeshPoints[cme.start()],// m p
00659                                             cutPointZoneID_.index(),  // zone
00660                                             true                      // active
00661                                         )
00662                                     );
00663 //                                 Pout << "Inserting point: " << newPoint << " as edge to edge intersection.  Slave edge: " << edgeI << " " << curEdge << " master edge: " << cmeIndex << " " << cme << endl;
00664                                 pointsIntoSlaveEdges[edgeI].append(newPoint);
00665                                 pointsIntoMasterEdges[cmeIndex].append(newPoint);
00666 
00667                                 // Add the point into the enriched patch map
00668                                 pointMap.insert
00669                                 (
00670                                     newPoint,
00671                                     masterCutPoint
00672                                 );
00673 
00674                                 // Record which two edges intersect to
00675                                 // create cut point
00676                                 addToCpepm.insert
00677                                 (
00678                                     newPoint,    // Cut point index
00679                                     Pair<edge>
00680                                     (
00681                                         edge
00682                                         (
00683                                             masterMeshPoints[cme.start()],
00684                                             masterMeshPoints[cme.end()]
00685                                         ),    // Master edge
00686                                         edge
00687                                         (
00688                                             slaveMeshPoints[curEdge.start()],
00689                                             slaveMeshPoints[curEdge.end()]
00690                                         )// Slave edge
00691                                     )
00692                                 );
00693 
00694                                 if (debug)
00695                                 {
00696                                     Pout<< " " << newPoint << " = "
00697                                         << masterCutPoint << " ";
00698                                 }
00699                             }
00700                             else
00701                             {
00702                                 if (debug)
00703                                 {
00704                                     // Intersection exists but it is too far
00705                                     Pout << "t";
00706                                 }
00707                             }
00708                         }
00709                         else
00710                         {
00711                             if (debug)
00712                             {
00713                                 // Missed slave edge
00714                                 Pout << "x";
00715                             }
00716                         }
00717                     }
00718                     else
00719                     {
00720                         if (debug)
00721                         {
00722                             // Missed master edge
00723                             Pout << "-";
00724                         }
00725                     }
00726                 }
00727                 else
00728                 {
00729                     if (debug)
00730                     {
00731                         Pout << "u";
00732                     }
00733                 }
00734             }
00735 
00736             if (debug)
00737             {
00738                 Pout << endl;
00739             }
00740         } // End if both ends missing
00741     } // End for all slave edges
00742 
00743 //     Pout << "pointsIntoMasterEdges: " << pointsIntoMasterEdges << endl;
00744 //     Pout << "pointsIntoSlaveEdges: " << pointsIntoSlaveEdges << endl;
00745 
00746     // Re-pack the points into edges lists
00747     labelListList pime(pointsIntoMasterEdges.size());
00748 
00749     forAll (pointsIntoMasterEdges, i)
00750     {
00751         pime[i].transfer(pointsIntoMasterEdges[i]);
00752     }
00753 
00754     labelListList pise(pointsIntoSlaveEdges.size());
00755 
00756     forAll (pointsIntoSlaveEdges, i)
00757     {
00758         pise[i].transfer(pointsIntoSlaveEdges[i]);
00759     }
00760 
00761     // Prepare the enriched faces
00762     cutPatch.calcEnrichedFaces
00763     (
00764         pime,
00765         pise,
00766         projectedSlavePoints
00767     );
00768 
00769     // Demand driven calculate the cut faces. Apart from the
00770     // cutFaces/cutFaceMaster/cutFaceSlave no information from the cutPatch
00771     // is used anymore!
00772     const faceList& cutFaces = cutPatch.cutFaces();
00773     const labelList& cutFaceMaster = cutPatch.cutFaceMaster();
00774     const labelList& cutFaceSlave = cutPatch.cutFaceSlave();
00775 
00776     const labelList& masterFc = masterFaceCells();
00777     const labelList& slaveFc = slaveFaceCells();
00778 
00779     // Couple the interface
00780 
00781     // Algorithm:
00782     // 1) Go through the cut faces and check if the cut face is the same as the
00783     //    defining master or slave.  If so, modify the appropriate
00784     //    face and mark the other for relegation into the face zone.
00785     // 2) If different, mark both sides for relegation and insert the new face
00786 
00787 
00788     boolList orphanedMaster(masterPatch.size(), false);
00789     boolList orphanedSlave(slavePatch.size(), false);
00790 
00791     forAll (cutFaces, faceI)
00792     {
00793         const face& curCutFace = cutFaces[faceI];
00794         const label curMaster = cutFaceMaster[faceI];
00795         const label curSlave = cutFaceSlave[faceI];
00796 
00797 //         Pout << "Doing insertion of face " << faceI << ": ";
00798 
00799         // Check if the face has changed topologically
00800         bool insertedFace = false;
00801 
00802         if (curMaster >= 0)
00803         {
00804             // Face has got a master
00805             if (curCutFace == masterPatch[curMaster])
00806             {
00807                 // Face is equal to master.  Modify master face.
00808 //                 Pout << "Face is equal to master and is ";
00809 
00810                 // If the face has got both master and slave, it is an
00811                 // internal face; otherwise it is a patch face in the
00812                 // master patch.  Keep it in the master face zone.
00813 
00814                 if (curSlave >= 0)
00815                 {
00816 //                     Pout << "internal" << endl;
00817                     if (masterFc[curMaster] < slaveFc[curSlave])
00818                     {
00819                         // Cut face should point into slave.
00820                         // Be careful about flips in zone!
00821                         ref.setAction
00822                         (
00823                             polyModifyFace
00824                             (
00825                                 curCutFace,                  // new face
00826                                 masterPatchAddr[curMaster],  // master face id
00827                                 masterFc[curMaster],         // owner
00828                                 slaveFc[curSlave],           // neighbour
00829                                 false,                       // flux flip
00830                                 -1,                          // patch ID
00831                                 false,                       // remove from zone
00832                                 masterFaceZoneID_.index(),   // zone ID
00833                                 masterPatchFlip[curMaster]   // zone flip
00834                             )
00835                         );
00836 //                         Pout << "modifying master face. Old master: " << masterPatch[curMaster] << " new face: " << curCutFace.reverseFace() << " own: " << masterFc[curMaster] << " nei: " << slaveFc[curSlave] << endl;
00837                     }
00838                     else
00839                     {
00840                         // Cut face should point into master.  Flip required.
00841                         // Be careful about flips in zone!
00842                         ref.setAction
00843                         (
00844                             polyModifyFace
00845                             (
00846                                 curCutFace.reverseFace(),    // new face
00847                                 masterPatchAddr[curMaster],  // master face id
00848                                 slaveFc[curSlave],           // owner
00849                                 masterFc[curMaster],         // neighbour
00850                                 true,                        // flux flip
00851                                 -1,                          // patch ID
00852                                 false,                       // remove from zone
00853                                 masterFaceZoneID_.index(),   // zone ID
00854                                 !masterPatchFlip[curMaster]  // zone flip
00855                             )
00856                         );
00857                     }
00858 
00859                     // Orphan the slave
00860                     orphanedSlave[curSlave] = true;
00861                 }
00862                 else
00863                 {
00864 //                     Pout << "master boundary" << endl;
00865                     ref.setAction
00866                     (
00867                         polyModifyFace
00868                         (
00869                             curCutFace,                  // new face
00870                             masterPatchAddr[curMaster],  // master face index
00871                             masterFc[curMaster],         // owner
00872                             -1,                          // neighbour
00873                             false,                       // flux flip
00874                             masterPatchID_.index(),      // patch ID
00875                             false,                       // remove from zone
00876                             masterFaceZoneID_.index(),   // zone ID
00877                             masterPatchFlip[curMaster]   // zone flip
00878                         )
00879                     );
00880                 }
00881 
00882                 insertedFace = true;
00883             }
00884         }
00885         else if (curSlave >= 0)
00886         {
00887             // Face has got a slave
00888 
00889             // Renumber the slave face into merged labels
00890             face rsf(slavePatch[curSlave]);
00891 
00892             forAll (rsf, i)
00893             {
00894                 Map<label>::const_iterator mpIter = pointMergeMap.find(rsf[i]);
00895 
00896                 if (mpIter != pointMergeMap.end())
00897                 {
00898                     rsf[i] = mpIter();
00899                 }
00900             }
00901 
00902             if (curCutFace == rsf)
00903             {
00904                 // Face is equal to slave.  Modify slave face.
00905 //                 Pout << "Face is equal to slave and is ";
00906 
00907                 if (curMaster >= 0)
00908                 {
00909 //                     Pout << "regular internal" << endl;
00910                     if (masterFc[curMaster] < slaveFc[curSlave])
00911                     {
00912                         ref.setAction
00913                         (
00914                             polyModifyFace
00915                             (
00916                                 curCutFace,                  // new face
00917                                 slavePatchAddr[curSlave],    // master face id
00918                                 masterFc[curMaster],         // owner
00919                                 slaveFc[curSlave],           // neighbour
00920                                 true,                        // flux flip
00921                                 -1,                          // patch ID
00922                                 false,                       // remove from zone
00923                                 slaveFaceZoneID_.index(),    // zone ID
00924                                 !slavePatchFlip[curMaster]   // zone flip
00925                             )
00926                         );
00927                     }
00928                     else
00929                     {
00930                         // Cut face should point into master.
00931                         // Be careful about flips in zone!
00932 //                         Pout << "flipped internal" << endl;
00933                         ref.setAction
00934                         (
00935                             polyModifyFace
00936                             (
00937                                 curCutFace.reverseFace(),    // new face
00938                                 slavePatchAddr[curSlave],    // master face id
00939                                 slaveFc[curSlave],           // owner
00940                                 masterFc[curMaster],         // neighbour
00941                                 false,                       // flux flip
00942                                 -1,                          // patch ID
00943                                 false,                       // remove from zone
00944                                 slaveFaceZoneID_.index(),    // zone ID
00945                                 slavePatchFlip[curSlave]     // zone flip
00946                             )
00947                         );
00948                     }
00949 
00950                     // Orphan the master
00951                     orphanedMaster[curMaster] = true;
00952                 }
00953                 else
00954                 {
00955 //                     Pout << "slave boundary" << endl;
00956                     ref.setAction
00957                     (
00958                         polyModifyFace
00959                         (
00960                             curCutFace,                  // new face
00961                             slavePatchAddr[curSlave],    // master face index
00962                             slaveFc[curSlave],           // owner
00963                             -1,                          // neighbour
00964                             false,                       // flux flip
00965                             slavePatchID_.index(),       // patch ID
00966                             false,                       // remove from zone
00967                             slaveFaceZoneID_.index(),    // zone ID
00968                             slavePatchFlip[curSlave]     // zone flip
00969                         )
00970                     );
00971                 }
00972 
00973                 insertedFace = true;
00974             }
00975         }
00976         else
00977         {
00978             FatalErrorIn
00979             (
00980                 "void slidingInterface::coupleInterface("
00981                 "polyTopoChange& ref) const"
00982             )   << "Face " << faceI << " in cut faces has neither a master "
00983                 << "nor a slave.  Error in the cutting algorithm on modify."
00984                 << abort(FatalError);
00985         }
00986 
00987         if (!insertedFace)
00988         {
00989             // Face is different from both master and slave
00990 //             Pout << "Face different from both master and slave" << endl;
00991 
00992             if (curMaster >= 0)
00993             {
00994                 if (curSlave >= 0)
00995                 {
00996                     // Add internal face
00997                     if (masterFc[curMaster] < slaveFc[curSlave])
00998                     {
00999 //                         Pout << "Adding internal face " << curCutFace << " owner: " << masterFc[curMaster] << " slave: " << slaveFc[curSlave] << " master face: " << masterPatchAddr[curMaster] << endl;
01000                         // Cut face should point into slave.
01001                         ref.setAction
01002                         (
01003                             polyAddFace
01004                             (
01005                                 curCutFace,                  // new face
01006                                 masterFc[curMaster],         // owner
01007                                 slaveFc[curSlave],           // neighbour
01008                                 -1,                          // master point
01009                                 -1,                          // master edge
01010                                 masterPatchAddr[curMaster],  // master face id
01011                                 false,                       // flux flip
01012                                 -1,                          // patch ID
01013                                 cutFaceZoneID_.index(),      // zone ID
01014                                 false                        // zone flip
01015                             )
01016                         );
01017                     }
01018                     else
01019                     {
01020                         // Cut face should point into master.  Flip required.
01021                         ref.setAction
01022                         (
01023                             polyAddFace
01024                             (
01025                                 curCutFace.reverseFace(),    // new face
01026                                 slaveFc[curSlave],           // owner
01027                                 masterFc[curMaster],         // neighbour
01028                                 -1,                          // master point
01029                                 -1,                          // master edge
01030                                 masterPatchAddr[curMaster],  // master face id
01031                                 true,                        // flux flip
01032                                 -1,                          // patch ID
01033                                 cutFaceZoneID_.index(),      // zone ID
01034                                 true                         // zone flip
01035                             )
01036                         );
01037                     }
01038 
01039                     // Orphan slave
01040                     orphanedSlave[curSlave] = true;
01041                 }
01042                 else
01043                 {
01044 //                 Pout << "Adding solo master face " << curCutFace << " owner: " << masterFc[curMaster] << " master face: " << masterPatchAddr[curMaster] << endl;
01045                     // Add master patch face
01046                     ref.setAction
01047                     (
01048                         polyAddFace
01049                         (
01050                             curCutFace,                  // new face
01051                             masterFc[curMaster],         // owner
01052                             -1,                          // neighbour
01053                             -1,                          // master point
01054                             -1,                          // master edge
01055                             masterPatchAddr[curMaster],  // master face index
01056                             false,                       // flux flip
01057                             masterPatchID_.index(),      // patch ID
01058                             cutFaceZoneID_.index(),      // zone ID
01059                             false                        // zone flip
01060                         )
01061                     );
01062                 }
01063 
01064                 // Orphan master
01065                 orphanedMaster[curMaster] = true;
01066             }
01067             else if (curSlave >= 0)
01068             {
01069 //                 Pout << "Adding solo slave face " << curCutFace << " owner: " << slaveFc[curSlave] << " master face: " << slavePatchAddr[curSlave] << endl;
01070                 // Add slave patch face
01071                 ref.setAction
01072                 (
01073                     polyAddFace
01074                     (
01075                         curCutFace,                  // new face
01076                         slaveFc[curSlave],           // owner
01077                         -1,                          // neighbour
01078                         -1,                          // master point
01079                         -1,                          // master edge
01080                         slavePatchAddr[curSlave],    // master face index
01081                         false,                       // flux flip
01082                         slavePatchID_.index(),       // patch ID
01083                         cutFaceZoneID_.index(),      // zone ID
01084                         false                        // zone flip
01085                     )
01086                 );
01087 
01088                 // Orphan slave
01089                 orphanedSlave[curSlave] = true;
01090             }
01091             else
01092             {
01093                 FatalErrorIn
01094                 (
01095                     "void slidingInterface::coupleInterface("
01096                     "polyTopoChange& ref) const"
01097                 )   << "Face " << faceI << " in cut faces has neither a master "
01098                     << "nor a slave.  Error in the cutting algorithm on add."
01099                     << abort(FatalError);
01100             }
01101         }
01102     }
01103 
01104     // Move the orphaned faces into the face zone
01105 //     Pout << "Orphaned master faces: " << orphanedMaster << endl;
01106 //     Pout << "Orphaned slave faces: " << orphanedSlave << endl;
01107 
01108     label nOrphanedMasters = 0;
01109 
01110     forAll (orphanedMaster, faceI)
01111     {
01112         if (orphanedMaster[faceI])
01113         {
01114             nOrphanedMasters++;
01115 
01117             //ref.setAction
01118             //(
01119             //    polyModifyFace
01120             //    (
01121             //        masterPatch[faceI],                 // new face
01122             //        masterPatchAddr[faceI],             // master face index
01123             //        -1,                                 // owner
01124             //        -1,                                 // neighbour
01125             //        false,                              // flux flip
01126             //        -1,                                 // patch ID
01127             //        false,                              // remove from zone
01128             //        masterFaceZoneID_.index(),          // zone ID
01129             //        false                               // zone flip
01130             //    )
01131             //);
01132 
01133             //Pout<< "**MJ:deleting master face " << masterPatchAddr[faceI]
01134             //    << " old verts:" << masterPatch[faceI] << endl;
01135             ref.setAction(polyRemoveFace(masterPatchAddr[faceI]));
01136         }
01137     }
01138 
01139     label nOrphanedSlaves = 0;
01140 
01141     forAll (orphanedSlave, faceI)
01142     {
01143         if (orphanedSlave[faceI])
01144         {
01145             nOrphanedSlaves++;
01146 
01148             //ref.setAction
01149             //(
01150             //    polyModifyFace
01151             //    (
01152             //        slavePatch[faceI],                // new face
01153             //        slavePatchAddr[faceI],            // slave face index
01154             //        -1,                               // owner
01155             //        -1,                               // neighbour
01156             //        false,                            // flux flip
01157             //        -1,                               // patch ID
01158             //        false,                            // remove from zone
01159             //        slaveFaceZoneID_.index(),         // zone ID
01160             //        false                             // zone flip
01161             //    )
01162             //);
01163 
01164             //Pout<< "**MJ:deleting slave face " << slavePatchAddr[faceI]
01165             //    << " old verts:" << slavePatch[faceI] << endl;
01166             ref.setAction(polyRemoveFace(slavePatchAddr[faceI]));
01167         }
01168     }
01169 
01170     if (debug)
01171     {
01172         Pout<< "Number of orphaned faces: "
01173             << "master = " << nOrphanedMasters << " out of "
01174             << orphanedMaster.size()
01175             << " slave = " << nOrphanedSlaves << " out of "
01176             << orphanedSlave.size() << endl;
01177     }
01178 
01179     // Finished coupling the plane of sliding interface.
01180 
01181     // Modify faces influenced by the sliding interface
01182     // These are the faces belonging to the master and slave cell
01183     // layer which have not already been modified.
01184     // Modification comes in three types:
01185     // 1) eliminate the points that have been removed when the old sliding
01186     //    interface has been removed
01187     // 2) Merge the slave points that have hit points on the master patch
01188     // 3) Introduce new points resulting from the new sliding interface cut
01189 
01190     // Collect all affected faces
01191 
01192     // Master side
01193 
01194     // Grab the list of faces in the layer
01195     const labelList& masterStickOuts = masterStickOutFaces();
01196 
01197 //     Pout << "masterStickOuts: " << masterStickOuts << endl;
01198 
01199     // Re-create the master stick-out faces
01200     forAll (masterStickOuts, faceI)
01201     {
01202         // Renumber the face and remove additional points
01203 
01204         const label curFaceID = masterStickOuts[faceI];
01205 
01206         const face& oldRichFace = faces[curFaceID];
01207 
01208         bool changed = false;
01209 
01210         // Remove removed points from the face
01211         face oldFace(oldRichFace.size());
01212         label nOldFace = 0;
01213 
01214         forAll (oldRichFace, pointI)
01215         {
01216             if (ref.pointRemoved(oldRichFace[pointI]))
01217             {
01218                 changed = true;
01219             }
01220             else
01221             {
01222                 // Point off patch
01223                 oldFace[nOldFace] = oldRichFace[pointI];
01224                 nOldFace++;
01225             }
01226         }
01227 
01228         oldFace.setSize(nOldFace);
01229 
01230 //         Pout << "old rich master face: " << oldRichFace << " old face: " << oldFace << endl;
01231         DynamicList<label> newFaceLabels(2*oldFace.size());
01232 
01233         forAll (oldFace, pointI)
01234         {
01235             if (masterMeshPointMap.found(oldFace[pointI]))
01236             {
01237                 // Point is in master patch. Add it
01238 
01239                 // If the point is a direct hit, grab its label; otherwise
01240                 // keep the original
01241                 if (pointMergeMap.found(oldFace[pointI]))
01242                 {
01243                     changed = true;
01244                     newFaceLabels.append
01245                     (
01246                         pointMergeMap.find(oldFace[pointI])()
01247                     );
01248                 }
01249                 else
01250                 {
01251                     newFaceLabels.append(oldFace[pointI]);
01252                 }
01253 
01254                 // Find if there are additional points inserted onto the edge
01255                 // between current point and the next point
01256                 // Algorithm:
01257                 // 1) Find all the edges in the master patch coming
01258                 //    out of the current point.
01259                 // 2) If the next point in the face to pick the right edge
01260                 const label localFirstLabel =
01261                     masterMeshPointMap.find(oldFace[pointI])();
01262 
01263                 const labelList& curEdges = masterPointEdges[localFirstLabel];
01264 
01265                 const label  nextLabel = oldFace.nextLabel(pointI);
01266 
01267                 Map<label>::const_iterator mmpmIter =
01268                     masterMeshPointMap.find(nextLabel);
01269 
01270                 if (mmpmIter != masterMeshPointMap.end())
01271                 {
01272 //                     Pout << "found label pair " << oldFace[pointI] << " and " << nextLabel;
01273                     // Find the points on the edge between them
01274                     const label localNextLabel = mmpmIter();
01275 
01276                     forAll (curEdges, curEdgeI)
01277                     {
01278                         if
01279                         (
01280                             masterEdges[curEdges[curEdgeI]].otherVertex
01281                             (
01282                                 localFirstLabel
01283                             )
01284                          == localNextLabel
01285                         )
01286                         {
01287 //                             Pout << " found edge: " << curEdges[curEdgeI] << endl;
01288 
01289                             // Get points on current edge
01290                             const labelList& curPime = pime[curEdges[curEdgeI]];
01291 
01292                             if (curPime.size())
01293                             {
01294                                 changed = true;
01295                                 // Pout << "curPime: " << curPime << endl;
01296                                 // Insert the edge points into the face
01297                                 // in the correct order
01298                                 const point& startPoint =
01299                                     masterLocalPoints[localFirstLabel];
01300 
01301                                 vector e =
01302                                     masterLocalPoints[localNextLabel]
01303                                   - startPoint;
01304 
01305                                 e /= magSqr(e);
01306 
01307                                 scalarField edgePointWeights(curPime.size());
01308 
01309                                 forAll (curPime, curPimeI)
01310                                 {
01311                                     edgePointWeights[curPimeI] =
01312                                         (
01313                                             e
01314                                           & (
01315                                               pointMap.find(curPime[curPimeI])()
01316                                             - startPoint
01317                                             )
01318                                         );
01319                                 }
01320 
01321                                 if (debug)
01322                                 {
01323                                     if
01324                                     (
01325                                         min(edgePointWeights) < 0
01326                                      || max(edgePointWeights) > 1
01327                                     )
01328                                     {
01329                                         FatalErrorIn
01330                                         (
01331                                             "void slidingInterface::"
01332                                             "coupleInterface("
01333                                             "polyTopoChange& ref) const"
01334                                         )   << "Error in master stick-out edge "
01335                                             << "point collection."
01336                                             << abort(FatalError);
01337                                     }
01338                                 }
01339 
01340                                 // Go through the points and collect
01341                                 // them based on weights from lower to
01342                                 // higher.  This gives the correct
01343                                 // order of points along the edge.
01344                                 for
01345                                 (
01346                                     label passI = 0;
01347                                     passI < edgePointWeights.size();
01348                                     passI++
01349                                 )
01350                                 {
01351                                     // Max weight can only be one, so
01352                                     // the sorting is done by
01353                                     // elimination.
01354                                     label nextPoint = -1;
01355                                     scalar dist = 2;
01356 
01357                                     forAll (edgePointWeights, wI)
01358                                     {
01359                                         if (edgePointWeights[wI] < dist)
01360                                         {
01361                                             dist = edgePointWeights[wI];
01362                                             nextPoint = wI;
01363                                         }
01364                                     }
01365 
01366                                     // Insert the next point and reset
01367                                     // its weight to exclude it from
01368                                     // future picks
01369                                     newFaceLabels.append(curPime[nextPoint]);
01370                                     edgePointWeights[nextPoint] = GREAT;
01371                                 }
01372                             }
01373 
01374                             break;
01375                         } // End of found edge
01376                     } // End of looking through current edges
01377                 }
01378             }
01379             else
01380             {
01381                 newFaceLabels.append(oldFace[pointI]);
01382             }
01383         }
01384 
01385         if (changed)
01386         {
01387             if (newFaceLabels.size() < 3)
01388             {
01389                 FatalErrorIn
01390                 (
01391                     "void slidingInterface::coupleInterface("
01392                     "polyTopoChange& ref) const"
01393                 )   << "Face " << curFaceID << " reduced to less than "
01394                     << "3 points.  Topological/cutting error A." << nl
01395                     << "Old face: " << oldFace << " new face: " << newFaceLabels
01396                     << abort(FatalError);
01397             }
01398 
01399             // Get face zone and its flip
01400             label modifiedFaceZone = faceZones.whichZone(curFaceID);
01401             bool modifiedFaceZoneFlip = false;
01402 
01403             if (modifiedFaceZone >= 0)
01404             {
01405                 modifiedFaceZoneFlip =
01406                     faceZones[modifiedFaceZone].flipMap()
01407                     [
01408                         faceZones[modifiedFaceZone].whichFace(curFaceID)
01409                     ];
01410             }
01411 
01412             face newFace;
01413             newFace.transfer(newFaceLabels);
01414 
01415             //Pout << "Modifying master stick-out face " << curFaceID
01416             //    << " old face: " << oldFace << " new face: " << newFace << endl;
01417 
01418             // Modify the face
01419             if (mesh.isInternalFace(curFaceID))
01420             {
01421                 ref.setAction
01422                 (
01423                     polyModifyFace
01424                     (
01425                         newFace,                // modified face
01426                         curFaceID,              // label of face being modified
01427                         own[curFaceID],         // owner
01428                         nei[curFaceID],         // neighbour
01429                         false,                  // face flip
01430                         -1,                     // patch for face
01431                         false,                  // remove from zone
01432                         modifiedFaceZone,       // zone for face
01433                         modifiedFaceZoneFlip    // face flip in zone
01434                     )
01435                 );
01436             }
01437             else
01438             {
01439                 ref.setAction
01440                 (
01441                     polyModifyFace
01442                     (
01443                         newFace,                // modified face
01444                         curFaceID,              // label of face being modified
01445                         own[curFaceID],         // owner
01446                         -1,                     // neighbour
01447                         false,                  // face flip
01448                         mesh.boundaryMesh().whichPatch(curFaceID), // patch for face
01449                         false,                  // remove from zone
01450                         modifiedFaceZone,       // zone for face
01451                         modifiedFaceZoneFlip    // face flip in zone
01452                     )
01453                 );
01454             }
01455         }
01456     }
01457 
01458 //     Pout << "Finished master side" << endl;
01459 
01460     // Slave side
01461 
01462     // Grab the list of faces in the layer
01463     const labelList& slaveStickOuts = slaveStickOutFaces();
01464 
01465 //     Pout << "slaveStickOuts: " << slaveStickOuts << endl;
01466 
01467     const Map<label>& rpm = retiredPointMap();
01468 
01469     // Re-create the slave stick-out faces
01470 
01471     forAll (slaveStickOuts, faceI)
01472     {
01473         // Renumber the face and remove additional points
01474         const label curFaceID = slaveStickOuts[faceI];
01475 
01476         const face& oldRichFace = faces[curFaceID];
01477 
01478         bool changed = false;
01479 
01480         // Remove removed points from the face
01481         face oldFace(oldRichFace.size());
01482         label nOldFace = 0;
01483 
01484         forAll (oldRichFace, pointI)
01485         {
01486             if
01487             (
01488                 rpm.found(oldRichFace[pointI])
01489              || slaveMeshPointMap.found(oldRichFace[pointI])
01490             )
01491             {
01492                 // Point definitely live. Add it
01493                 oldFace[nOldFace] = oldRichFace[pointI];
01494                 nOldFace++;
01495             }
01496             else if
01497             (
01498                 ref.pointRemoved(oldRichFace[pointI])
01499              || masterMeshPointMap.found(oldRichFace[pointI])
01500             )
01501             {
01502                 // Point removed and not on slave patch
01503                 // (first if takes care of that!) or
01504                 // point belonging to master patch
01505                 changed = true;
01506             }
01507             else
01508             {
01509                 // Point off patch
01510                 oldFace[nOldFace] = oldRichFace[pointI];
01511                 nOldFace++;
01512             }
01513         }
01514 
01515         oldFace.setSize(nOldFace);
01516 
01517         DynamicList<label> newFaceLabels(2*oldFace.size());
01518 
01519 //         Pout << "old rich slave face: " << oldRichFace << " old face: " << oldFace << endl;
01520         forAll (oldFace, pointI)
01521         {
01522             // Try to find the point in retired points
01523             label curP = oldFace[pointI];
01524 
01525             Map<label>::const_iterator rpmIter = rpm.find(oldFace[pointI]);
01526 
01527             if (rpmIter != rpm.end())
01528             {
01529                 changed = true;
01530                 curP = rpmIter();
01531             }
01532 
01533             if (slaveMeshPointMap.found(curP))
01534             {
01535                 // Point is in slave patch. Add it
01536 
01537                 // If the point is a direct hit, grab its label; otherwise
01538                 // keep the original
01539                 if (pointMergeMap.found(curP))
01540                 {
01541                     changed = true;
01542                     newFaceLabels.append
01543                     (
01544                         pointMergeMap.find(curP)()
01545                     );
01546                 }
01547                 else
01548                 {
01549                     newFaceLabels.append(curP);
01550                 }
01551 
01552                 // Find if there are additional points inserted onto the edge
01553                 // between current point and the next point
01554                 // Algorithm:
01555                 // 1) Find all the edges in the slave patch coming
01556                 //    out of the current point.
01557                 // 2) Use the next point in the face to pick the right edge
01558 
01559                 const label localFirstLabel =
01560                     slaveMeshPointMap.find(curP)();
01561 
01562                 const labelList& curEdges = slavePointEdges[localFirstLabel];
01563 
01564                 label nextLabel = oldFace.nextLabel(pointI);
01565 
01566                 Map<label>::const_iterator rpmNextIter =
01567                     rpm.find(nextLabel);
01568 
01569                 if (rpmNextIter != rpm.end())
01570                 {
01571                     nextLabel = rpmNextIter();
01572                 }
01573 
01574                 Map<label>::const_iterator mmpmIter =
01575                     slaveMeshPointMap.find(nextLabel);
01576 
01577                 if (mmpmIter != slaveMeshPointMap.end())
01578                 {
01579                     // Both points on the slave patch.
01580                     // Find the points on the edge between them
01581                     const label localNextLabel = mmpmIter();
01582 
01583                     forAll (curEdges, curEdgeI)
01584                     {
01585                         if
01586                         (
01587                             slaveEdges[curEdges[curEdgeI]].otherVertex
01588                             (
01589                                 localFirstLabel
01590                             )
01591                          == localNextLabel
01592                         )
01593                         {
01594 //                             Pout << " found edge: " << curEdges[curEdgeI] << endl;
01595 
01596                             // Get points on current edge
01597                             const labelList& curPise = pise[curEdges[curEdgeI]];
01598 
01599                             if (curPise.size())
01600                             {
01601                                 changed = true;
01602 //                                 Pout << "curPise: " << curPise << endl;
01603                                 // Insert the edge points into the face
01604                                 // in the correct order
01605                                 const point& startPoint =
01606                                     projectedSlavePoints[localFirstLabel];
01607 
01608                                 vector e =
01609                                     projectedSlavePoints[localNextLabel]
01610                                   - startPoint;
01611 
01612                                 e /= magSqr(e);
01613 
01614                                 scalarField edgePointWeights(curPise.size());
01615 
01616                                 forAll (curPise, curPiseI)
01617                                 {
01618                                     edgePointWeights[curPiseI] =
01619                                     (
01620                                         e
01621                                       & (
01622                                             pointMap.find(curPise[curPiseI])()
01623                                           - startPoint
01624                                         )
01625                                     );
01626                                 }
01627 
01628                                 if (debug)
01629                                 {
01630                                     if
01631                                     (
01632                                         min(edgePointWeights) < 0
01633                                      || max(edgePointWeights) > 1
01634                                     )
01635                                     {
01636                                         FatalErrorIn
01637                                         (
01638                                             "void slidingInterface::"
01639                                             "coupleInterface("
01640                                             "polyTopoChange& ref) const"
01641                                         )   << "Error in slave stick-out edge "
01642                                             << "point collection."
01643                                             << abort(FatalError);
01644                                         }
01645                                     }
01646 
01647                                 // Go through the points and collect
01648                                 // them based on weights from lower to
01649                                 // higher.  This gives the correct
01650                                 // order of points along the edge.
01651                                 for
01652                                 (
01653                                     label passI = 0;
01654                                     passI < edgePointWeights.size();
01655                                     passI++
01656                                 )
01657                                 {
01658                                     // Max weight can only be one, so
01659                                     // the sorting is done by
01660                                     // elimination.
01661                                     label nextPoint = -1;
01662                                     scalar dist = 2;
01663 
01664                                     forAll (edgePointWeights, wI)
01665                                     {
01666                                         if (edgePointWeights[wI] < dist)
01667                                         {
01668                                             dist = edgePointWeights[wI];
01669                                             nextPoint = wI;
01670                                         }
01671                                     }
01672 
01673                                     // Insert the next point and reset
01674                                     // its weight to exclude it from
01675                                     // future picks
01676                                     newFaceLabels.append(curPise[nextPoint]);
01677                                     edgePointWeights[nextPoint] = GREAT;
01678                                 }
01679                             }
01680 
01681                             break;
01682                         }
01683                     } // End of found edge
01684                 } // End of looking through current edges
01685             }
01686             else
01687             {
01688                 newFaceLabels.append(oldFace[pointI]);
01689             }
01690         }
01691 
01692         if (changed)
01693         {
01694             if (newFaceLabels.size() < 3)
01695             {
01696                 FatalErrorIn
01697                 (
01698                     "void slidingInterface::coupleInterface("
01699                     "polyTopoChange& ref) const"
01700                 )   << "Face " << curFaceID << " reduced to less than "
01701                     << "3 points.  Topological/cutting error B." << nl
01702                     << "Old face: " << oldFace << " new face: " << newFaceLabels
01703                     << abort(FatalError);
01704             }
01705 
01706             // Get face zone and its flip
01707             label modifiedFaceZone = faceZones.whichZone(curFaceID);
01708             bool modifiedFaceZoneFlip = false;
01709 
01710             if (modifiedFaceZone >= 0)
01711             {
01712                 modifiedFaceZoneFlip =
01713                     faceZones[modifiedFaceZone].flipMap()
01714                     [
01715                         faceZones[modifiedFaceZone].whichFace(curFaceID)
01716                     ];
01717             }
01718 
01719             face newFace;
01720             newFace.transfer(newFaceLabels);
01721 
01722 //             Pout << "Modifying slave stick-out face " << curFaceID << " old face: " << oldFace << " new face: " << newFace << endl;
01723 
01724             // Modify the face
01725             if (mesh.isInternalFace(curFaceID))
01726             {
01727                 ref.setAction
01728                 (
01729                     polyModifyFace
01730                     (
01731                         newFace,                // modified face
01732                         curFaceID,              // label of face being modified
01733                         own[curFaceID],         // owner
01734                         nei[curFaceID],         // neighbour
01735                         false,                  // face flip
01736                         -1,                     // patch for face
01737                         false,                  // remove from zone
01738                         modifiedFaceZone,       // zone for face
01739                         modifiedFaceZoneFlip    // face flip in zone
01740                     )
01741                 );
01742             }
01743             else
01744             {
01745                 ref.setAction
01746                 (
01747                     polyModifyFace
01748                     (
01749                         newFace,                // modified face
01750                         curFaceID,              // label of face being modified
01751                         own[curFaceID],         // owner
01752                         -1,                     // neighbour
01753                         false,                  // face flip
01754                         mesh.boundaryMesh().whichPatch(curFaceID), // patch for face
01755                         false,                  // remove from zone
01756                         modifiedFaceZone,       // zone for face
01757                         modifiedFaceZoneFlip    // face flip in zone
01758                     )
01759                 );
01760             }
01761         }
01762     }
01763 
01764     // Activate and retire slave patch points
01765     // This needs to be done last, so that the map of removed points
01766     // does not get damaged by point modifications
01767 
01768     if (!retiredPointMapPtr_)
01769     {
01770         FatalErrorIn
01771         (
01772             "void slidingInterface::coupleInterface("
01773             "polyTopoChange& ref) const"
01774         )   << "Retired point map pointer not set."
01775             << abort(FatalError);
01776     }
01777 
01778     Map<label>& addToRpm = *retiredPointMapPtr_;
01779 
01780     // Clear the old map
01781     addToRpm.clear();
01782 
01783     label nRetiredPoints = 0;
01784 
01785     forAll (slaveMeshPoints, pointI)
01786     {
01787         if (pointMergeMap.found(slaveMeshPoints[pointI]))
01788         {
01789             // Retire the point - only used for supporting the detached
01790             // slave patch
01791             nRetiredPoints++;
01792 
01793             //ref.setAction
01794             //(
01795             //    polyModifyPoint
01796             //    (
01797             //        slaveMeshPoints[pointI],             // point ID
01798             //        points[slaveMeshPoints[pointI]],     // point
01799             //        false,                               // remove from zone
01800             //        mesh.pointZones().whichZone(slaveMeshPoints[pointI]),// zone
01801             //        false                                // in a cell
01802             //    )
01803             //);
01804             //Pout<< "MJ retire slave point " << slaveMeshPoints[pointI]
01805             //    << " coord " << points[slaveMeshPoints[pointI]]
01806             //    << endl;
01807             ref.setAction
01808             (
01809                 polyRemovePoint
01810                 (
01811                     slaveMeshPoints[pointI]
01812                 )
01813             );
01814 
01815             addToRpm.insert
01816             (
01817                 pointMergeMap.find(slaveMeshPoints[pointI])(),
01818                 slaveMeshPoints[pointI]
01819             );
01820         }
01821         else
01822         {
01823             ref.setAction
01824             (
01825                 polyModifyPoint
01826                 (
01827                     slaveMeshPoints[pointI],             // point ID
01828                     points[slaveMeshPoints[pointI]],     // point
01829                     false,                               // remove from zone
01830                     mesh.pointZones().whichZone(slaveMeshPoints[pointI]),// zone
01831                     true                                 // in a cell
01832                 )
01833             );
01834         }
01835     }
01836 
01837     if (debug)
01838     {
01839         Pout << "Retired " << nRetiredPoints << " out of "
01840             << slaveMeshPoints.size() << " points." << endl;
01841     }
01842 
01843     // Grab cut face master and slave addressing
01844     if (cutFaceMasterPtr_) deleteDemandDrivenData(cutFaceMasterPtr_);
01845     cutFaceMasterPtr_ = new labelList(cutPatch.cutFaceMaster());
01846 
01847     if (cutFaceSlavePtr_) deleteDemandDrivenData(cutFaceSlavePtr_);
01848     cutFaceSlavePtr_ = new labelList(cutPatch.cutFaceSlave());
01849 
01850     // Finished coupling
01851     attached_ = true;
01852 
01853     if (debug)
01854     {
01855         Pout<< "void slidingInterface::coupleInterface("
01856             << "polyTopoChange& ref) : "
01857             << "Finished coupling sliding interface " << name() << endl;
01858     }
01859 }
01860 
01861 
01862 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines