coupleSlidingInterface.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2017-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "slidingInterface.H"
30 #include "polyTopoChange.H"
31 #include "polyMesh.H"
32 #include "primitiveMesh.H"
33 #include "enrichedPatch.H"
34 #include "DynamicList.H"
35 #include "pointHit.H"
36 #include "triPointRef.H"
37 #include "plane.H"
38 #include "polyTopoChanger.H"
39 #include "polyAddPoint.H"
40 #include "polyRemovePoint.H"
41 #include "polyAddFace.H"
42 #include "polyModifyPoint.H"
43 #include "polyModifyFace.H"
44 #include "polyRemoveFace.H"
45 
46 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
47 
48 const Foam::scalar Foam::slidingInterface::edgeCoPlanarTolDefault_ = 0.8;
49 
50 
51 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
52 
53 // Index of debug signs:
54 // Index of debug signs:
55 // . - loop of the edge-to-face interaction detection
56 // x - reversal of direction in edge-to-face interaction detection
57 // + - complete edge-to-face interaction detection
58 // z - incomplete edge-to-face interaction detection. This may be OK for edges
59 // crossing from one to the other side of multiply connected master patch
60 
61 // e - adding a point on edge
62 // f - adding a point on face
63 // . - collecting edges off another face for edge-to-edge cut
64 // + - finished collection of edges
65 // * - cut both master and slave
66 // n - cutting new edge
67 // t - intersection exists but it is outside of tolerance
68 // x - missed slave edge in cut
69 // - - missed master edge in cut
70 // u - edge already used in cutting
71 
72 void Foam::slidingInterface::coupleInterface(polyTopoChange& ref) const
73 {
74  if (debug)
75  {
76  Pout<< FUNCTION_NAME << nl
77  << ": Coupling sliding interface " << name() << endl;
78  }
79 
80  const polyMesh& mesh = topoChanger().mesh();
81  const pointField& points = mesh.points();
82  const faceList& faces = mesh.faces();
83  const labelList& own = mesh.faceOwner();
84  const labelList& nei = mesh.faceNeighbour();
85  const faceZoneMesh& faceZones = mesh.faceZones();
86 
87  const primitiveFacePatch& masterPatch =
88  faceZones[masterFaceZoneID_.index()]();
89 
90  const labelList& masterPatchAddr = faceZones[masterFaceZoneID_.index()];
91 
92  const boolList& masterPatchFlip =
93  faceZones[masterFaceZoneID_.index()].flipMap();
94 
95  const primitiveFacePatch& slavePatch =
96  faceZones[slaveFaceZoneID_.index()]();
97 
98  const labelList& slavePatchAddr = faceZones[slaveFaceZoneID_.index()];
99 
100  const boolList& slavePatchFlip =
101  faceZones[slaveFaceZoneID_.index()].flipMap();
102 
103  const edgeList& masterEdges = masterPatch.edges();
104  const labelListList& masterPointEdges = masterPatch.pointEdges();
105  const labelList& masterMeshPoints = masterPatch.meshPoints();
106  const pointField& masterLocalPoints = masterPatch.localPoints();
107  const labelListList& masterFaceFaces = masterPatch.faceFaces();
108  const labelListList& masterFaceEdges = masterPatch.faceEdges();
109  const Map<label>& masterMeshPointMap = masterPatch.meshPointMap();
110 
111  const edgeList& slaveEdges = slavePatch.edges();
112  const labelListList& slavePointEdges = slavePatch.pointEdges();
113  const labelList& slaveMeshPoints = slavePatch.meshPoints();
114  const pointField& slaveLocalPoints = slavePatch.localPoints();
115  const Map<label>& slaveMeshPointMap = slavePatch.meshPointMap();
116  const vectorField& slavePointNormals = slavePatch.pointNormals();
117 
118  // Collect projection addressing
119  if
120  (
121  !(
122  slavePointPointHitsPtr_
123  && slavePointEdgeHitsPtr_
124  && slavePointFaceHitsPtr_
125  && masterPointEdgeHitsPtr_
126  )
127  )
128  {
130  << "Point projection addressing not available."
131  << abort(FatalError);
132  }
133 
134  const labelList& slavePointPointHits = *slavePointPointHitsPtr_;
135  const labelList& slavePointEdgeHits = *slavePointEdgeHitsPtr_;
136  const List<objectHit>& slavePointFaceHits = *slavePointFaceHitsPtr_;
137  const labelList& masterPointEdgeHits = *masterPointEdgeHitsPtr_;
138  const pointField& projectedSlavePoints = *projectedSlavePointsPtr_;
139 
140  // Create enriched patch
141  enrichedPatch cutPatch
142  (
143  masterPatch,
144  slavePatch,
145  slavePointPointHits,
146  slavePointEdgeHits,
147  slavePointFaceHits
148  );
149 
150  // Get reference to list of added point for the enriched patch.
151  // This will be used for point addition
152  Map<point>& pointMap = cutPatch.pointMap();
153 
154  // Get reference to the list of merged points
155  Map<label>& pointMergeMap = cutPatch.pointMergeMap();
156 
157  // Create mapping for every merged point of the slave patch
158  forAll(slavePointPointHits, pointi)
159  {
160  const label slaveHitPti = slavePointPointHits[pointi];
161 
162  if (slaveHitPti >= 0)
163  {
164  pointMergeMap.insert
165  (
166  slaveMeshPoints[pointi],
167  masterMeshPoints[slaveHitPti]
168  );
169  }
170  }
171 
172 
173  // Collect the list of used edges for every slave edge
174 
175  List<labelHashSet> usedMasterEdges(slaveEdges.size());
176 
177  // Collect of slave point hits
178  forAll(slavePointPointHits, pointi)
179  {
180  // For point hits, add all point-edges from master side to all point
181  const labelList& curSlaveEdges = slavePointEdges[pointi];
182 
183  if (slavePointPointHits[pointi] > -1)
184  {
185  const labelList& curMasterEdges =
186  masterPointEdges[slavePointPointHits[pointi]];
187 
188  // Mark all current master edges as used for all the current slave
189  // edges
190  for (const label slaveEdgei : curSlaveEdges)
191  {
192  usedMasterEdges[slaveEdgei].insert(curMasterEdges);
193  }
194  }
195  else if (slavePointEdgeHits[pointi] > -1)
196  {
197  // For edge hits, add the master edge
198  for (const label slaveEdgei : curSlaveEdges)
199  {
200  usedMasterEdges[slaveEdgei].insert
201  (
202  slavePointEdgeHits[pointi]
203  );
204  }
205  }
206  }
207 
208  // Collect off master point hits
209  // For every master point that has hit an edge, add all edges coming from
210  // that point to the slave edge that has been hit
211  forAll(masterPointEdgeHits, masterPointi)
212  {
213  if (masterPointEdgeHits[masterPointi] > -1)
214  {
215  const labelList& curMasterEdges = masterPointEdges[masterPointi];
216 
217  usedMasterEdges[masterPointEdgeHits[masterPointi]].insert
218  (
219  curMasterEdges
220  );
221  }
222  }
223 
224  // Pout<< "used edges: " << endl;
225  // forAll(usedMasterEdges, edgei)
226  // {
227  // Pout<< "edge: " << edgei
228  // << " used: " << usedMasterEdges[edgei].toc()
229  // << endl;
230  // }
231 
232  // For every master and slave edge make a list of points to be added into
233  // that edge.
234  List<DynamicList<label>> pointsIntoMasterEdges(masterEdges.size());
235  List<DynamicList<label>> pointsIntoSlaveEdges(slaveEdges.size());
236 
237  // Add all points from the slave patch that have hit the edge
238  forAll(slavePointEdgeHits, pointi)
239  {
240  if (slavePointEdgeHits[pointi] > -1)
241  {
242  // Create a new point on the master edge
243 
244  const point edgeCutPoint =
245  masterEdges[slavePointEdgeHits[pointi]].line
246  (
247  masterLocalPoints
248  ).nearestDist(projectedSlavePoints[pointi]).hitPoint();
249 
250  const label newPointi =
251  ref.setAction
252  (
253  polyAddPoint
254  (
255  edgeCutPoint, // point
256  slaveMeshPoints[pointi], // master point
257  cutPointZoneID_.index(), // zone for point
258  true // supports a cell
259  )
260  );
261 
262  // Add the new edge point into the merge map
263  pointMergeMap.insert
264  (
265  slaveMeshPoints[pointi],
266  newPointi
267  );
268 
269  pointsIntoMasterEdges[slavePointEdgeHits[pointi]].append
270  (
271  newPointi
272  );
273 
274  // Add the point into the enriched patch map
275  pointMap.insert
276  (
277  newPointi,
278  edgeCutPoint
279  );
280 
281  if (debug)
282  {
283  Pout<< "e";
284 
285  // Pout<< "Inserting merge pair off edge: "
286  // << slaveMeshPoints[pointi] << " " << newPointi
287  // << " cut point: " << edgeCutPoint
288  // << " orig: " << slaveLocalPoints[pointi]
289  // << " proj: " << projectedSlavePoints[pointi]
290  // << endl;
291 
292  // Pout<< newPointi << " = " << edgeCutPoint << endl;
293  }
294  }
295  }
296 
297  if (debug)
298  {
299  Pout<< endl;
300  }
301 
302  // Add all points from the slave patch that have hit a face
303  forAll(slavePointFaceHits, pointi)
304  {
305  if
306  (
307  slavePointPointHits[pointi] < 0
308  && slavePointEdgeHits[pointi] < 0
309  && slavePointFaceHits[pointi].hit()
310  )
311  {
312  const label newPointi =
313  ref.setAction
314  (
315  polyAddPoint
316  (
317  projectedSlavePoints[pointi], // point
318  slaveMeshPoints[pointi], // master point
319  cutPointZoneID_.index(), // zone for point
320  true // supports a cell
321  )
322  );
323 
324  // Pout<< "Inserting merge pair off face: "
325  // << slaveMeshPoints[pointi]
326  // << " " << newPointi
327  // << endl;
328 
329  // Add the new edge point into the merge map
330  pointMergeMap.insert
331  (
332  slaveMeshPoints[pointi],
333  newPointi
334  );
335 
336  // Add the point into the enriched patch map
337  pointMap.insert
338  (
339  newPointi,
340  projectedSlavePoints[pointi]
341  );
342 
343  if (debug)
344  {
345  Pout<< "f: " << newPointi << " = "
346  << projectedSlavePoints[pointi] << endl;
347  }
348  }
349  }
350 
351  forAll(masterPointEdgeHits, pointi)
352  {
353  if (masterPointEdgeHits[pointi] > -1)
354  {
355  pointsIntoSlaveEdges[masterPointEdgeHits[pointi]].append
356  (
357  masterMeshPoints[pointi]
358  );
359  }
360  }
361 
362  // Cut all slave edges.
363  // Collect all master edges the slave edge interacts with. Skip
364  // all the edges already marked as used. For every unused edge,
365  // calculate the cut and insert the new point into the master and
366  // slave edge.
367  // For the edge selection algorithm, see, comment in
368  // slidingInterfaceProjectPoints.C.
369  // Edge cutting algorithm:
370  // As the master patch defines the cutting surface, the newly
371  // inserted point needs to be on the master edge. Also, in 3-D
372  // the pair of edges generally misses each other rather than
373  // intersect. Therefore, the intersection is calculated using the
374  // plane the slave edge defines during projection. The plane is
375  // defined by the centrepoint of the edge in the original
376  // configuration and the projected end points. In case of flat
377  // geometries (when the three points are colinear), the plane is
378  // defined by the two projected end-points and the slave edge
379  // normal used as the in-plane vector. When the intersection
380  // point is created, it is added as a new point for both the
381  // master and the slave edge.
382  // In order to be able to re-create the points on edges in mesh
383  // motion without the topology change, the edge pair used to
384  // create the cut point needs to be recorded in
385  // cutPointEdgePairMap
386 
387  // Note. "Processing slave edges" code is repeated twice in the
388  // sliding interface coupling in order to allow the point
389  // projection to be done separately from the actual cutting.
390  // Please change consistently with slidingInterfaceProjectPoints.C
391  //
392  if (debug)
393  {
394  Pout<< "Processing slave edges" << endl;
395  }
396 
397  if (!cutPointEdgePairMapPtr_)
398  {
400  << "Cut point edge pair map pointer not set."
401  << abort(FatalError);
402  }
403 
404  Map<Pair<edge>>& addToCpepm = *cutPointEdgePairMapPtr_;
405 
406  // Clear the old map
407  addToCpepm.clear();
408 
409  // Create a map of faces the edge can interact with
410  labelHashSet curFaceMap
411  (
412  nFacesPerSlaveEdge_*primitiveMesh::edgesPerFace_
413  );
414 
416 
417  forAll(slaveEdges, edgeI)
418  {
419  const edge& curEdge = slaveEdges[edgeI];
420 
421  if
422  (
423  slavePointFaceHits[curEdge.start()].hit()
424  || slavePointFaceHits[curEdge.end()].hit()
425  )
426  {
427  labelHashSet& curUme = usedMasterEdges[edgeI];
428 
429  // Pout<< "Doing edge " << edgeI
430  // << " curEdge: " << curEdge
431  // << " curUme: " << curUme
432  // << endl;
433 
434  // Grab the faces for start and end points.
435  const label startFace =
436  slavePointFaceHits[curEdge.start()].hitObject();
437 
438  const label endFace =
439  slavePointFaceHits[curEdge.end()].hitObject();
440 
441  // Pout<< "startFace: " << slavePointFaceHits[curEdge.start()]
442  // << " endFace: " << slavePointFaceHits[curEdge.end()]
443  // << endl;
444 
445  bool completed = false;
446 
447  if (!completed)
448  {
449  // Forward sweep
450 
451  // Clear the maps
452  curFaceMap.clear();
453  addedFaces.clear();
454 
455  // Insert the start face into the list
456  curFaceMap.insert(startFace);
457  addedFaces.insert(startFace);
458 
459  // Pout<< "curFaceMap: " << curFaceMap.toc() << endl;
460 
461  for
462  (
463  label nSweeps = 0;
464  nSweeps < edgeFaceEscapeLimit_;
465  ++nSweeps
466  )
467  {
468  completed = addedFaces.found(endFace);
469 
470  // Add all face neighbours of face in the map
471  const labelList cf(addedFaces.toc());
472  addedFaces.clear();
473 
474  for (const label cfi : cf)
475  {
476  const labelList& curNbrs = masterFaceFaces[cfi];
477 
478  for (const label nbri : curNbrs)
479  {
480  if (curFaceMap.insert(nbri))
481  {
482  addedFaces.insert(nbri);
483  }
484  }
485  }
486 
487  if (completed) break;
488 
489  if (debug)
490  {
491  Pout<< ".";
492  }
493  }
494  }
495 
496  if (!completed)
497  {
498  // Reverse sweep
499 
500  if (debug)
501  {
502  Pout<< "x";
503  }
504 
505  // It is impossible to reach the end from the start, probably
506  // due to disconnected domain. Do search in opposite direction
507 
508  addedFaces.clear();
509  addedFaces.insert(endFace);
510 
511  for
512  (
513  label nSweeps = 0;
514  nSweeps < edgeFaceEscapeLimit_;
515  ++nSweeps
516  )
517  {
518  completed = addedFaces.found(startFace);
519 
520  // Add all face neighbours of face in the map
521  const labelList cf(addedFaces.toc());
522  addedFaces.clear();
523 
524  for (const label cfi : cf)
525  {
526  const labelList& curNbrs = masterFaceFaces[cfi];
527 
528  for (const label nbri : curNbrs)
529  {
530  if (curFaceMap.insert(nbri))
531  {
532  addedFaces.insert(nbri);
533  }
534  }
535  }
536 
537  if (completed) break;
538 
539  if (debug)
540  {
541  Pout<< ".";
542  }
543  }
544  }
545 
546  if (completed)
547  {
548  if (debug)
549  {
550  Pout<< "+ ";
551  }
552  }
553  else
554  {
555  if (debug)
556  {
557  Pout<< "z ";
558  }
559  }
560 
561  // Collect the edges
562 
563  // Create a map of edges the edge can interact with
564  labelHashSet curMasterEdgesMap
565  (
566  nFacesPerSlaveEdge_*primitiveMesh::edgesPerFace_
567  );
568 
569  for (const label facei : curFaceMap)
570  {
571  // Pout<< "face: " << facei << " "
572  // << masterPatch[facei]
573  // << " local: "
574  // << masterPatch.localFaces()[facei]
575  // << endl;
576 
577  curMasterEdgesMap.insert(masterFaceEdges[facei]);
578  }
579 
580  const labelList curMasterEdges(curMasterEdgesMap.toc());
581  curMasterEdgesMap.clear();
582 
583  // For all master edges to intersect, skip the ones
584  // already used and cut the rest with a cutting plane. If
585  // the intersection point, falls inside of both edges, it
586  // is valid.
587 
588  // Note.
589  // The edge cutting code is repeated in
590  // slidingInterface::modifyMotionPoints. This is done for
591  // efficiency reasons and avoids multiple creation of cutting
592  // planes. Please update both simultaneously.
593 
594  const point& a = projectedSlavePoints[curEdge.start()];
595  const point& b = projectedSlavePoints[curEdge.end()];
596 
597  const point c =
598  0.5*
599  (
600  slaveLocalPoints[curEdge.start()]
601  + slavePointNormals[curEdge.start()] // Add start normal
602  + slaveLocalPoints[curEdge.end()]
603  + slavePointNormals[curEdge.end()] // Add end normal
604  );
605 
606  // Create the plane
607  const plane cutPlane(a, b, c);
608 
609  // Pout<< "a: " << a
610  // << " b: " << b
611  // << " c: " << c
612  // << " plane: " << cutPlane
613  // << endl;
614 
615  const linePointRef curSlaveLine =
616  curEdge.line(projectedSlavePoints);
617 
618  const scalar curSlaveLineMag = curSlaveLine.mag();
619 
620  // Pout<< "curSlaveLine: " << curSlaveLine << endl;
621 
622  for (const label cmeIndex : curMasterEdges)
623  {
624  if (!curUme.found(cmeIndex))
625  {
626  // New edge
627  if (debug)
628  {
629  Pout<< "n";
630  }
631 
632  const edge& cme = masterEdges[cmeIndex];
633 
634  // Pout<< "Edge " << cmeIndex
635  // << " cme: " << cme
636  // << " line: " << cme.line(masterLocalPoints)
637  // << endl;
638 
639  const scalar cutOnMaster =
640  cutPlane.lineIntersect
641  (
642  cme.line(masterLocalPoints)
643  );
644 
645  if
646  (
647  cutOnMaster > edgeEndCutoffTol_
648  && cutOnMaster < 1.0 - edgeEndCutoffTol_
649  )
650  {
651  // Master is cut, check the slave
652  const point masterCutPoint =
653  masterLocalPoints[cme.start()]
654  + cutOnMaster*cme.vec(masterLocalPoints);
655 
656  const pointHit slaveCut =
657  curSlaveLine.nearestDist(masterCutPoint);
658 
659  if (slaveCut.hit())
660  {
661  // Strict checking of slave cut to avoid capturing
662  // end points.
663  const scalar cutOnSlave =
664  (
665  (
666  slaveCut.hitPoint()
667  - curSlaveLine.start()
668  ) & curSlaveLine.vec()
669  )/sqr(curSlaveLineMag);
670 
671  // Calculate merge tolerance from the
672  // target edge length
673  const scalar mergeTol = edgeCoPlanarTol_*mag(b - a);
674 
675  // Pout<< "cutOnMaster: " << cutOnMaster
676  // << " masterCutPoint: " << masterCutPoint
677  // << " slaveCutPoint: " << slaveCut.hitPoint()
678  // << " slaveCut.distance(): "
679  // << slaveCut.distance()
680  // << " slave length: " << mag(b - a)
681  // << " mergeTol: " << mergeTol
682  // << " 1: " << mag(b - a)
683  // << " 2: "
684  // << cme.line(masterLocalPoints).mag()
685  // << endl;
686 
687  if
688  (
689  cutOnSlave > edgeEndCutoffTol_
690  && cutOnSlave < 1.0 - edgeEndCutoffTol_
691  && slaveCut.distance() < mergeTol
692  )
693  {
694  // Cut both master and slave. Add point
695  // to edge points The point is nominally
696  // added from the start of the master edge
697  // and added to the cut point zone
698  const label newPointi =
699  ref.setAction
700  (
701  polyAddPoint
702  (
703  masterCutPoint, // point
704  masterMeshPoints[cme.start()],// m p
705  cutPointZoneID_.index(), // zone
706  true // active
707  )
708  );
709 
710  // Pout<< "Inserting point: " << newPointi
711  // << " as edge to edge intersection. "
712  // << "Slave edge: "
713  // << edgeI << " " << curEdge
714  // << " master edge: "
715  // << cmeIndex << " " << cme
716  // << endl;
717 
718  pointsIntoSlaveEdges[edgeI].append
719  (
720  newPointi
721  );
722  pointsIntoMasterEdges[cmeIndex].append
723  (
724  newPointi
725  );
726 
727  // Add the point into the enriched patch map
728  pointMap.insert
729  (
730  newPointi,
731  masterCutPoint
732  );
733 
734  // Record which two edges intersect to
735  // create cut point
736  addToCpepm.insert
737  (
738  newPointi, // Cut point index
739  Pair<edge>
740  (
741  edge
742  (
743  masterMeshPoints[cme.start()],
744  masterMeshPoints[cme.end()]
745  ), // Master edge
746  edge
747  (
748  slaveMeshPoints[curEdge.start()],
749  slaveMeshPoints[curEdge.end()]
750  ) // Slave edge
751  )
752  );
753 
754  if (debug)
755  {
756  Pout<< " " << newPointi << " = "
757  << masterCutPoint << " ";
758  }
759  }
760  else
761  {
762  if (debug)
763  {
764  // Intersection exists but it is too far
765  Pout<< "t";
766  }
767  }
768  }
769  else
770  {
771  if (debug)
772  {
773  // Missed slave edge
774  Pout<< "x";
775  }
776  }
777  }
778  else
779  {
780  if (debug)
781  {
782  // Missed master edge
783  Pout<< "-";
784  }
785  }
786  }
787  else
788  {
789  if (debug)
790  {
791  Pout<< "u";
792  }
793  }
794  }
795 
796  if (debug)
797  {
798  Pout<< endl;
799  }
800  } // End if both ends missing
801  } // End for all slave edges
802 
803 // Pout<< "pointsIntoMasterEdges: " << pointsIntoMasterEdges << endl;
804 // Pout<< "pointsIntoSlaveEdges: " << pointsIntoSlaveEdges << endl;
805 
806  // Re-pack the points into edges lists
807  labelListList pime(pointsIntoMasterEdges.size());
808 
809  forAll(pointsIntoMasterEdges, i)
810  {
811  pime[i].transfer(pointsIntoMasterEdges[i]);
812  }
813 
814  labelListList pise(pointsIntoSlaveEdges.size());
815 
816  forAll(pointsIntoSlaveEdges, i)
817  {
818  pise[i].transfer(pointsIntoSlaveEdges[i]);
819  }
820 
821  // Prepare the enriched faces
822  cutPatch.calcEnrichedFaces
823  (
824  pime,
825  pise,
826  projectedSlavePoints
827  );
828 
829  // Demand driven calculate the cut faces. Apart from the
830  // cutFaces/cutFaceMaster/cutFaceSlave no information from the cutPatch
831  // is used anymore!
832  const faceList& cutFaces = cutPatch.cutFaces();
833  const labelList& cutFaceMaster = cutPatch.cutFaceMaster();
834  const labelList& cutFaceSlave = cutPatch.cutFaceSlave();
835 
836  const labelList& masterFc = masterFaceCells();
837  const labelList& slaveFc = slaveFaceCells();
838 
839  // Couple the interface
840 
841  // Algorithm:
842  // 1) Go through the cut faces and check if the cut face is the same as the
843  // defining master or slave. If so, modify the appropriate
844  // face and mark the other for relegation into the face zone.
845  // 2) If different, mark both sides for relegation and insert the new face
846 
847 
848  boolList orphanedMaster(masterPatch.size(), false);
849  boolList orphanedSlave(slavePatch.size(), false);
850 
851  forAll(cutFaces, facei)
852  {
853  const face& curCutFace = cutFaces[facei];
854  const label curMaster = cutFaceMaster[facei];
855  const label curSlave = cutFaceSlave[facei];
856 
857 // Pout<< "Doing insertion of face " << facei << ": ";
858 
859  // Check if the face has changed topologically
860  bool insertedFace = false;
861 
862  if (curMaster >= 0)
863  {
864  // Face has got a master
865  if (curCutFace == masterPatch[curMaster])
866  {
867  // Face is equal to master. Modify master face.
868 // Pout<< "Face is equal to master and is ";
869 
870  // If the face has got both master and slave, it is an
871  // internal face; otherwise it is a patch face in the
872  // master patch. Keep it in the master face zone.
873 
874  if (curSlave >= 0)
875  {
876 // Pout<< "internal" << endl;
877  if (masterFc[curMaster] < slaveFc[curSlave])
878  {
879  // Cut face should point into slave.
880  // Be careful about flips in zone!
881  ref.setAction
882  (
883  polyModifyFace
884  (
885  curCutFace, // new face
886  masterPatchAddr[curMaster], // master face id
887  masterFc[curMaster], // owner
888  slaveFc[curSlave], // neighbour
889  false, // flux flip
890  -1, // patch ID
891  false, // remove from zone
892  masterFaceZoneID_.index(), // zone ID
893  masterPatchFlip[curMaster] // zone flip
894  )
895  );
896 
897  // Pout<< "modifying master face. Old master: "
898  // << masterPatch[curMaster]
899  // << " new face: " << curCutFace.reverseFace()
900  // << " own: " << masterFc[curMaster]
901  // << " nei: " << slaveFc[curSlave] << endl;
902  }
903  else
904  {
905  // Cut face should point into master. Flip required.
906  // Be careful about flips in zone!
907  ref.setAction
908  (
909  polyModifyFace
910  (
911  curCutFace.reverseFace(), // new face
912  masterPatchAddr[curMaster], // master face id
913  slaveFc[curSlave], // owner
914  masterFc[curMaster], // neighbour
915  true, // flux flip
916  -1, // patch ID
917  false, // remove from zone
918  masterFaceZoneID_.index(), // zone ID
919  !masterPatchFlip[curMaster] // zone flip
920  )
921  );
922  }
923 
924  // Orphan the slave
925  orphanedSlave[curSlave] = true;
926  }
927  else
928  {
929 // Pout<< "master boundary" << endl;
930  ref.setAction
931  (
932  polyModifyFace
933  (
934  curCutFace, // new face
935  masterPatchAddr[curMaster], // master face index
936  masterFc[curMaster], // owner
937  -1, // neighbour
938  false, // flux flip
939  masterPatchID_.index(), // patch ID
940  false, // remove from zone
941  masterFaceZoneID_.index(), // zone ID
942  masterPatchFlip[curMaster] // zone flip
943  )
944  );
945  }
946 
947  insertedFace = true;
948  }
949  }
950  else if (curSlave >= 0)
951  {
952  // Face has got a slave
953 
954  // Renumber the slave face into merged labels
955  face rsf(slavePatch[curSlave]);
956 
957  forAll(rsf, i)
958  {
959  rsf[i] = pointMergeMap.lookup(rsf[i], rsf[i]);
960  }
961 
962  if (curCutFace == rsf)
963  {
964  // Face is equal to slave. Modify slave face.
965  // Pout<< "Face is equal to slave and is ";
966 
967  if (curMaster >= 0)
968  {
969  // Pout<< "regular internal" << endl;
970  if (masterFc[curMaster] < slaveFc[curSlave])
971  {
972  ref.setAction
973  (
974  polyModifyFace
975  (
976  curCutFace, // new face
977  slavePatchAddr[curSlave], // master face id
978  masterFc[curMaster], // owner
979  slaveFc[curSlave], // neighbour
980  true, // flux flip
981  -1, // patch ID
982  false, // remove from zone
983  slaveFaceZoneID_.index(), // zone ID
984  !slavePatchFlip[curMaster] // zone flip
985  )
986  );
987  }
988  else
989  {
990  // Cut face should point into master.
991  // Be careful about flips in zone!
992  // Pout<< "flipped internal" << endl;
993  ref.setAction
994  (
995  polyModifyFace
996  (
997  curCutFace.reverseFace(), // new face
998  slavePatchAddr[curSlave], // master face id
999  slaveFc[curSlave], // owner
1000  masterFc[curMaster], // neighbour
1001  false, // flux flip
1002  -1, // patch ID
1003  false, // remove from zone
1004  slaveFaceZoneID_.index(), // zone ID
1005  slavePatchFlip[curSlave] // zone flip
1006  )
1007  );
1008  }
1009 
1010  // Orphan the master
1011  orphanedMaster[curMaster] = true;
1012  }
1013  else
1014  {
1015  // Pout<< "slave boundary" << endl;
1016  ref.setAction
1017  (
1018  polyModifyFace
1019  (
1020  curCutFace, // new face
1021  slavePatchAddr[curSlave], // master face index
1022  slaveFc[curSlave], // owner
1023  -1, // neighbour
1024  false, // flux flip
1025  slavePatchID_.index(), // patch ID
1026  false, // remove from zone
1027  slaveFaceZoneID_.index(), // zone ID
1028  slavePatchFlip[curSlave] // zone flip
1029  )
1030  );
1031  }
1032 
1033  insertedFace = true;
1034  }
1035  }
1036  else
1037  {
1039  << "Face " << facei << " in cut faces has neither a master "
1040  << "nor a slave. Error in the cutting algorithm on modify."
1041  << abort(FatalError);
1042  }
1043 
1044  if (!insertedFace)
1045  {
1046  // Face is different from both master and slave
1047  // Pout<< "Face different from both master and slave" << endl;
1048 
1049  if (curMaster >= 0)
1050  {
1051  if (curSlave >= 0)
1052  {
1053  // Add internal face
1054  if (masterFc[curMaster] < slaveFc[curSlave])
1055  {
1056  // Pout<< "Adding internal face " << curCutFace
1057  // << " owner: " << masterFc[curMaster]
1058  // << " slave: " << slaveFc[curSlave]
1059  // << " master face: " << masterPatchAddr[curMaster]
1060  // << endl;
1061 
1062  // Cut face should point into slave.
1063  ref.setAction
1064  (
1065  polyAddFace
1066  (
1067  curCutFace, // new face
1068  masterFc[curMaster], // owner
1069  slaveFc[curSlave], // neighbour
1070  -1, // master point
1071  -1, // master edge
1072  masterPatchAddr[curMaster], // master face id
1073  false, // flux flip
1074  -1, // patch ID
1075  cutFaceZoneID_.index(), // zone ID
1076  false // zone flip
1077  )
1078  );
1079  }
1080  else
1081  {
1082  // Cut face should point into master. Flip required.
1083  ref.setAction
1084  (
1085  polyAddFace
1086  (
1087  curCutFace.reverseFace(), // new face
1088  slaveFc[curSlave], // owner
1089  masterFc[curMaster], // neighbour
1090  -1, // master point
1091  -1, // master edge
1092  masterPatchAddr[curMaster], // master face id
1093  true, // flux flip
1094  -1, // patch ID
1095  cutFaceZoneID_.index(), // zone ID
1096  true // zone flip
1097  )
1098  );
1099  }
1100 
1101  // Orphan slave
1102  orphanedSlave[curSlave] = true;
1103  }
1104  else
1105  {
1106  // Pout<< "Adding solo master face " << curCutFace
1107  // << " owner: " << masterFc[curMaster]
1108  // << " master face: " << masterPatchAddr[curMaster]
1109  // << endl;
1110 
1111  // Add master patch face
1112  ref.setAction
1113  (
1114  polyAddFace
1115  (
1116  curCutFace, // new face
1117  masterFc[curMaster], // owner
1118  -1, // neighbour
1119  -1, // master point
1120  -1, // master edge
1121  masterPatchAddr[curMaster], // master face index
1122  false, // flux flip
1123  masterPatchID_.index(), // patch ID
1124  cutFaceZoneID_.index(), // zone ID
1125  false // zone flip
1126  )
1127  );
1128  }
1129 
1130  // Orphan master
1131  orphanedMaster[curMaster] = true;
1132  }
1133  else if (curSlave >= 0)
1134  {
1135  // Pout<< "Adding solo slave face " << curCutFace
1136  // << " owner: " << slaveFc[curSlave]
1137  // << " master face: " << slavePatchAddr[curSlave]
1138  // << endl;
1139 
1140  // Add slave patch face
1141  ref.setAction
1142  (
1143  polyAddFace
1144  (
1145  curCutFace, // new face
1146  slaveFc[curSlave], // owner
1147  -1, // neighbour
1148  -1, // master point
1149  -1, // master edge
1150  slavePatchAddr[curSlave], // master face index
1151  false, // flux flip
1152  slavePatchID_.index(), // patch ID
1153  cutFaceZoneID_.index(), // zone ID
1154  false // zone flip
1155  )
1156  );
1157 
1158  // Orphan slave
1159  orphanedSlave[curSlave] = true;
1160  }
1161  else
1162  {
1164  << "Face " << facei << " in cut faces has neither a master "
1165  << "nor a slave. Error in the cutting algorithm on add."
1166  << abort(FatalError);
1167  }
1168  }
1169  }
1170 
1171  // Move the orphaned faces into the face zone
1172  // Pout<< "Orphaned master faces: " << orphanedMaster << endl;
1173  // Pout<< "Orphaned slave faces: " << orphanedSlave << endl;
1174 
1175  label nOrphanedMasters = 0;
1176 
1177  forAll(orphanedMaster, facei)
1178  {
1179  if (orphanedMaster[facei])
1180  {
1181  nOrphanedMasters++;
1182 
1184  //ref.setAction
1185  //(
1186  // polyModifyFace
1187  // (
1188  // masterPatch[facei], // new face
1189  // masterPatchAddr[facei], // master face index
1190  // -1, // owner
1191  // -1, // neighbour
1192  // false, // flux flip
1193  // -1, // patch ID
1194  // false, // remove from zone
1195  // masterFaceZoneID_.index(), // zone ID
1196  // false // zone flip
1197  // )
1198  //);
1199 
1200  //Pout<< "**MJ:deleting master face " << masterPatchAddr[facei]
1201  // << " old verts:" << masterPatch[facei] << endl;
1202  ref.setAction(polyRemoveFace(masterPatchAddr[facei]));
1203  }
1204  }
1205 
1206  label nOrphanedSlaves = 0;
1207 
1208  forAll(orphanedSlave, facei)
1209  {
1210  if (orphanedSlave[facei])
1211  {
1212  nOrphanedSlaves++;
1213 
1215  //ref.setAction
1216  //(
1217  // polyModifyFace
1218  // (
1219  // slavePatch[facei], // new face
1220  // slavePatchAddr[facei], // slave face index
1221  // -1, // owner
1222  // -1, // neighbour
1223  // false, // flux flip
1224  // -1, // patch ID
1225  // false, // remove from zone
1226  // slaveFaceZoneID_.index(), // zone ID
1227  // false // zone flip
1228  // )
1229  //);
1230 
1231  //Pout<< "**MJ:deleting slave face " << slavePatchAddr[facei]
1232  // << " old verts:" << slavePatch[facei] << endl;
1233  ref.setAction(polyRemoveFace(slavePatchAddr[facei]));
1234  }
1235  }
1236 
1237  if (debug)
1238  {
1239  Pout<< "Orphaned faces: "
1240  << "master = " << nOrphanedMasters << "/"
1241  << orphanedMaster.size()
1242  << " slave = " << nOrphanedSlaves << "/"
1243  << orphanedSlave.size() << endl;
1244  }
1245 
1246  // Finished coupling the plane of sliding interface.
1247 
1248  // Modify faces influenced by the sliding interface
1249  // These are the faces belonging to the master and slave cell
1250  // layer which have not already been modified.
1251  // Modification comes in three types:
1252  // 1) eliminate the points that have been removed when the old sliding
1253  // interface has been removed
1254  // 2) Merge the slave points that have hit points on the master patch
1255  // 3) Introduce new points resulting from the new sliding interface cut
1256 
1257  // Collect all affected faces
1258 
1259  // Master side
1260 
1261  // Grab the list of faces in the layer
1262  const labelList& masterStickOuts = masterStickOutFaces();
1263 
1264  // Pout<< "masterStickOuts: " << masterStickOuts << endl;
1265 
1266  // Re-create the master stick-out faces
1267  for (const label curFaceID : masterStickOuts)
1268  {
1269  // Renumber the face and remove additional points
1270  const face& oldRichFace = faces[curFaceID];
1271 
1272  bool changed = false;
1273 
1274  // Remove removed points from the face
1275  face oldFace(oldRichFace.size());
1276  label nOldFace = 0;
1277 
1278  for (const label pointi : oldRichFace)
1279  {
1280  if (ref.pointRemoved(pointi))
1281  {
1282  changed = true;
1283  }
1284  else
1285  {
1286  // Point off patch
1287  oldFace[nOldFace] = pointi;
1288  nOldFace++;
1289  }
1290  }
1291 
1292  oldFace.setSize(nOldFace);
1293 
1294  // Pout<< "old rich face[" << curFaceID << "]: " << oldRichFace
1295  // << " old face: " << oldFace << endl;
1296 
1297  DynamicList<label> newFaceLabels(2*oldFace.size());
1298 
1299  forAll(oldFace, pointi)
1300  {
1301  const label localFirstLabel =
1302  masterMeshPointMap.lookup(oldFace[pointi], -1);
1303 
1304  if (localFirstLabel != -1)
1305  {
1306  // Point is in master patch. Add it
1307 
1308  // If the point is a direct hit, grab its label;
1309  // otherwise keep the original
1310  newFaceLabels.append
1311  (
1312  pointMergeMap.lookup(oldFace[pointi], oldFace[pointi])
1313  );
1314 
1315  if (newFaceLabels.last() != oldFace[pointi])
1316  {
1317  changed = true;
1318  }
1319 
1320  // Find if there are additional points inserted onto the edge
1321  // between current point and the next point
1322  // Algorithm:
1323  // 1) Find all the edges in the master patch coming
1324  // out of the current point.
1325  // 2) If the next point in the face to pick the right edge
1326 
1327  const labelList& curEdges = masterPointEdges[localFirstLabel];
1328 
1329  const label nextLabel = oldFace.nextLabel(pointi);
1330 
1331  const label localNextLabel =
1332  masterMeshPointMap.lookup(nextLabel, -1);
1333 
1334  if (localNextLabel != -1)
1335  {
1336  // Pout<< "found label pair " << oldFace[pointi]
1337  // << " and " << nextLabel;
1338  // Find the points on the edge between them
1339 
1340  for (const label curEdgei : curEdges)
1341  {
1342  if
1343  (
1344  masterEdges[curEdgei].otherVertex
1345  (
1346  localFirstLabel
1347  )
1348  == localNextLabel
1349  )
1350  {
1351  // Pout<< " found edge: " << curEdgei << endl;
1352 
1353  // Get points on current edge
1354  const labelList& curPime = pime[curEdgei];
1355 
1356  if (curPime.size())
1357  {
1358  changed = true;
1359  // Pout<< "curPime: " << curPime << endl;
1360  // Insert the edge points into the face
1361  // in the correct order
1362  const point& startPoint =
1363  masterLocalPoints[localFirstLabel];
1364 
1365  const point& endPoint =
1366  masterLocalPoints[localNextLabel];
1367 
1368  vector e = (endPoint - startPoint);
1369 
1370  e /= magSqr(e);
1371 
1372  scalarField edgePointWeights(curPime.size());
1373 
1374  forAll(curPime, curPimeI)
1375  {
1376  edgePointWeights[curPimeI] =
1377  (
1378  e
1379  & (
1380  pointMap[curPime[curPimeI]]
1381  - startPoint
1382  )
1383  );
1384  }
1385 
1386  if (debug)
1387  {
1388  if
1389  (
1390  min(edgePointWeights) < 0
1391  || max(edgePointWeights) > 1
1392  )
1393  {
1395  << "Error in master stick-out edge "
1396  << "point collection."
1397  << abort(FatalError);
1398  }
1399  }
1400 
1401  // Go through the points and collect
1402  // them based on weights from lower to
1403  // higher. This gives the correct
1404  // order of points along the edge.
1405  for
1406  (
1407  label passI = 0;
1408  passI < edgePointWeights.size();
1409  passI++
1410  )
1411  {
1412  // Max weight can only be one, so
1413  // the sorting is done by
1414  // elimination.
1415  label nextPoint = -1;
1416  scalar dist = 2;
1417 
1418  forAll(edgePointWeights, wI)
1419  {
1420  if (edgePointWeights[wI] < dist)
1421  {
1422  dist = edgePointWeights[wI];
1423  nextPoint = wI;
1424  }
1425  }
1426 
1427  // Insert the next point and reset
1428  // its weight to exclude it from
1429  // future picks
1430  newFaceLabels.append(curPime[nextPoint]);
1431  edgePointWeights[nextPoint] = GREAT;
1432  }
1433  }
1434 
1435  break;
1436  } // End of found edge
1437  } // End of looking through current edges
1438  }
1439  }
1440  else
1441  {
1442  newFaceLabels.append(oldFace[pointi]);
1443  }
1444  }
1445 
1446  if (changed)
1447  {
1448  if (newFaceLabels.size() < 3)
1449  {
1451  << "Face " << curFaceID << " reduced to less than "
1452  << "3 points. Topological/cutting error A." << nl
1453  << "Old face: " << oldFace << " new face: " << newFaceLabels
1454  << abort(FatalError);
1455  }
1456 
1457  // Get face zone and its flip
1458  const label modifiedFaceZone = faceZones.whichZone(curFaceID);
1459 
1460  const bool modifiedFaceZoneFlip =
1461  (
1462  modifiedFaceZone >= 0
1463  ?
1464  faceZones[modifiedFaceZone].flipMap()
1465  [
1466  faceZones[modifiedFaceZone].whichFace(curFaceID)
1467  ]
1468  : false
1469  );
1470 
1471  face newFace;
1472  newFace.transfer(newFaceLabels);
1473 
1474  // Pout<< "Modifying master stick-out face[" << curFaceID
1475  // << "]: old: " << oldFace << " new: " << newFace << endl;
1476 
1477  // Modify the face
1478  if (mesh.isInternalFace(curFaceID))
1479  {
1480  ref.setAction
1481  (
1482  polyModifyFace
1483  (
1484  newFace, // modified face
1485  curFaceID, // label of face being modified
1486  own[curFaceID], // owner
1487  nei[curFaceID], // neighbour
1488  false, // face flip
1489  -1, // patch for face
1490  false, // remove from zone
1491  modifiedFaceZone, // zone for face
1492  modifiedFaceZoneFlip // face flip in zone
1493  )
1494  );
1495  }
1496  else
1497  {
1498  ref.setAction
1499  (
1500  polyModifyFace
1501  (
1502  newFace, // modified face
1503  curFaceID, // label of face being modified
1504  own[curFaceID], // owner
1505  -1, // neighbour
1506  false, // face flip
1507  mesh.boundaryMesh().whichPatch(curFaceID),
1508  // patch for face
1509  false, // remove from zone
1510  modifiedFaceZone, // zone for face
1511  modifiedFaceZoneFlip // face flip in zone
1512  )
1513  );
1514  }
1515  }
1516  }
1517 
1518  // Pout<< "Finished master side" << endl;
1519 
1520  // Slave side
1521 
1522  // Grab the list of faces in the layer
1523  const labelList& slaveStickOuts = slaveStickOutFaces();
1524 
1525  // Pout<< "slaveStickOuts: " << slaveStickOuts << endl;
1526 
1527  const Map<label>& rpm = retiredPointMap();
1528 
1529  // Re-create the slave stick-out faces
1530 
1531  for (const label curFaceID : slaveStickOuts)
1532  {
1533  // Renumber the face and remove additional points
1534  const face& oldRichFace = faces[curFaceID];
1535 
1536  bool changed = false;
1537 
1538  // Remove removed points from the face
1539  face oldFace(oldRichFace.size());
1540  label nOldFace = 0;
1541 
1542  for (const label pointi : oldRichFace)
1543  {
1544  if
1545  (
1546  rpm.found(pointi)
1547  || slaveMeshPointMap.found(pointi)
1548  )
1549  {
1550  // Point definitely live. Add it
1551  oldFace[nOldFace] = pointi;
1552  nOldFace++;
1553  }
1554  else if (ref.pointRemoved(pointi))
1555  {
1556  // Point removed, not on slave patch and not retired
1557  // (first if takes care of that!)
1558  changed = true;
1559  }
1560  else
1561  {
1562  // Point on master or slave patch
1563  oldFace[nOldFace] = pointi;
1564  nOldFace++;
1565  }
1566  }
1567 
1568  oldFace.setSize(nOldFace);
1569 
1570  DynamicList<label> newFaceLabels(2*oldFace.size());
1571 
1572  // Pout<< "old rich slave face: " << oldRichFace
1573  // << " old face: " << oldFace
1574  // << endl;
1575 
1576  forAll(oldFace, pointi)
1577  {
1578  // Try to find the point in retired points
1579  const label curP = rpm.lookup(oldFace[pointi], oldFace[pointi]);
1580 
1581  if (curP != oldFace[pointi])
1582  {
1583  changed = true;
1584  }
1585 
1586  const label localFirstLabel = slaveMeshPointMap.lookup(curP, -1);
1587 
1588  if (localFirstLabel != -1)
1589  {
1590  // Point is in slave patch. Add it
1591 
1592  // If the point is a direct hit, grab its label;
1593  // otherwise keep the original
1594  newFaceLabels.append
1595  (
1596  pointMergeMap.lookup(curP, curP)
1597  );
1598 
1599  if (newFaceLabels.last() != curP)
1600  {
1601  changed = true;
1602  }
1603 
1604  // Find if there are additional points inserted onto the edge
1605  // between current point and the next point
1606  // Algorithm:
1607  // 1) Find all the edges in the slave patch coming
1608  // out of the current point.
1609  // 2) Use the next point in the face to pick the right edge
1610 
1611  const labelList& curEdges = slavePointEdges[localFirstLabel];
1612 
1613  label nextLabel = oldFace.nextLabel(pointi);
1614 
1615  nextLabel = rpm.lookup(nextLabel, nextLabel);
1616 
1617  const label localNextLabel =
1618  slaveMeshPointMap.lookup(nextLabel, -1);
1619 
1620  if (localNextLabel != -1)
1621  {
1622  // Both points on the slave patch.
1623  // Find the points on the edge between them
1624 
1625  for (const label curEdgei : curEdges)
1626  {
1627  if
1628  (
1629  slaveEdges[curEdgei].otherVertex
1630  (
1631  localFirstLabel
1632  )
1633  == localNextLabel
1634  )
1635  {
1636  // Pout<< " found edge: " << curEdgei
1637  // << endl;
1638 
1639  // Get points on current edge
1640  const labelList& curPise = pise[curEdgei];
1641 
1642  if (curPise.size())
1643  {
1644  changed = true;
1645 
1646  // Pout<< "curPise: " << curPise << endl;
1647  // Insert the edge points into the face
1648  // in the correct order
1649  const point& startPoint =
1650  projectedSlavePoints[localFirstLabel];
1651 
1652  const point& endPoint =
1653  projectedSlavePoints[localNextLabel];
1654 
1655  vector e = endPoint - startPoint;
1656 
1657  e /= magSqr(e);
1658 
1659  scalarField edgePointWeights(curPise.size());
1660 
1661  forAll(curPise, curPiseI)
1662  {
1663  edgePointWeights[curPiseI] =
1664  (
1665  e
1666  & (
1667  pointMap[curPise[curPiseI]]
1668  - startPoint
1669  )
1670  );
1671  }
1672 
1673  if (debug)
1674  {
1675  if
1676  (
1677  min(edgePointWeights) < 0
1678  || max(edgePointWeights) > 1
1679  )
1680  {
1682  << "Error in slave stick-out edge "
1683  << "point collection."
1684  << abort(FatalError);
1685  }
1686  }
1687 
1688  // Go through the points and collect
1689  // them based on weights from lower to
1690  // higher. This gives the correct
1691  // order of points along the edge.
1692  for
1693  (
1694  label passI = 0;
1695  passI < edgePointWeights.size();
1696  passI++
1697  )
1698  {
1699  // Max weight can only be one, so
1700  // the sorting is done by
1701  // elimination.
1702  label nextPoint = -1;
1703  scalar dist = 2;
1704 
1705  forAll(edgePointWeights, wI)
1706  {
1707  if (edgePointWeights[wI] < dist)
1708  {
1709  dist = edgePointWeights[wI];
1710  nextPoint = wI;
1711  }
1712  }
1713 
1714  // Insert the next point and reset
1715  // its weight to exclude it from
1716  // future picks
1717  newFaceLabels.append(curPise[nextPoint]);
1718  edgePointWeights[nextPoint] = GREAT;
1719  }
1720  }
1721 
1722  break;
1723  }
1724  } // End of found edge
1725  } // End of looking through current edges
1726  }
1727  else
1728  {
1729  newFaceLabels.append(oldFace[pointi]);
1730  }
1731  }
1732 
1733  if (changed)
1734  {
1735  if (newFaceLabels.size() < 3)
1736  {
1738  << "Face " << curFaceID << " reduced to less than "
1739  << "3 points. Topological/cutting error B." << nl
1740  << "Old face: " << oldFace << " new face: " << newFaceLabels
1741  << abort(FatalError);
1742  }
1743 
1744  // Get face zone and its flip
1745  const label modifiedFaceZone =
1746  faceZones.whichZone(curFaceID);
1747 
1748  const bool modifiedFaceZoneFlip
1749  (
1750  modifiedFaceZone >= 0
1751  ?
1752  faceZones[modifiedFaceZone].flipMap()
1753  [
1754  faceZones[modifiedFaceZone].whichFace(curFaceID)
1755  ]
1756  : false
1757  );
1758 
1759  face newFace;
1760  newFace.transfer(newFaceLabels);
1761 
1762  // Pout<< "Modifying slave stick-out face[" << curFaceID
1763  // << "]: old: " << oldFace << " new: " << newFace
1764  // << endl;
1765 
1766  // Modify the face
1767  if (mesh.isInternalFace(curFaceID))
1768  {
1769  ref.setAction
1770  (
1771  polyModifyFace
1772  (
1773  newFace, // modified face
1774  curFaceID, // label of face being modified
1775  own[curFaceID], // owner
1776  nei[curFaceID], // neighbour
1777  false, // face flip
1778  -1, // patch for face
1779  false, // remove from zone
1780  modifiedFaceZone, // zone for face
1781  modifiedFaceZoneFlip // face flip in zone
1782  )
1783  );
1784  }
1785  else
1786  {
1787  ref.setAction
1788  (
1789  polyModifyFace
1790  (
1791  newFace, // modified face
1792  curFaceID, // label of face being modified
1793  own[curFaceID], // owner
1794  -1, // neighbour
1795  false, // face flip
1796  mesh.boundaryMesh().whichPatch(curFaceID),
1797  // patch for face
1798  false, // remove from zone
1799  modifiedFaceZone, // zone for face
1800  modifiedFaceZoneFlip // face flip in zone
1801  )
1802  );
1803  }
1804  }
1805  }
1806 
1807  // Activate and retire slave patch points
1808  // This needs to be done last, so that the map of removed points
1809  // does not get damaged by point modifications
1810 
1811  if (!retiredPointMapPtr_)
1812  {
1814  << "Retired point map pointer not set."
1815  << abort(FatalError);
1816  }
1817 
1818  Map<label>& addToRpm = *retiredPointMapPtr_;
1819 
1820  // Clear the old map
1821  addToRpm.clear();
1822 
1823  label nRetiredPoints = 0;
1824 
1825  for (const label slavePointi : slaveMeshPoints)
1826  {
1827  const label masterPointi = pointMergeMap.lookup(slavePointi, -1);
1828 
1829  if (slavePointi == masterPointi)
1830  {
1831  // Identity mapping (ie, slave point already exists on master patch)
1832  continue;
1833  }
1834  else if (masterPointi != -1)
1835  {
1836  // Retire the point - only used for supporting the detached
1837  // slave patch
1838  nRetiredPoints++;
1839 
1840  // ref.setAction
1841  // (
1842  // polyModifyPoint
1843  // (
1844  // slavePointi, // point ID
1845  // points[slavePointi], // point
1846  // false, // remove from zone
1847  // mesh.pointZones().whichZone(slavePointi), // zone
1848  // false // in a cell
1849  // )
1850  // );
1851  //
1852  //Pout<< "MJ retire slave point " << slavePointi
1853  // << " coord " << points[slavePointi]
1854  // << endl;
1855  ref.setAction
1856  (
1857  polyRemovePoint
1858  (
1859  slavePointi
1860  )
1861  );
1862 
1863  addToRpm.insert(masterPointi, slavePointi);
1864  }
1865  else
1866  {
1867  ref.setAction
1868  (
1869  polyModifyPoint
1870  (
1871  slavePointi, // point ID
1872  points[slavePointi], // point
1873  false, // remove from zone
1874  mesh.pointZones().whichZone(slavePointi),// zone
1875  true // in a cell
1876  )
1877  );
1878  }
1879  }
1880 
1881  if (debug)
1882  {
1883  Pout<< "Retired " << nRetiredPoints << "/"
1884  << slaveMeshPoints.size() << " points." << endl;
1885  }
1886 
1887  // Grab cut face master and slave addressing
1888  cutFaceMasterPtr_.reset(new labelList(cutPatch.cutFaceMaster()));
1889  cutFaceSlavePtr_.reset(new labelList(cutPatch.cutFaceSlave()));
1890 
1891  // Finished coupling
1892  attached_ = true;
1893 
1894  if (debug)
1895  {
1896  Pout<< FUNCTION_NAME << nl
1897  << ": Finished coupling sliding interface " << name() << endl;
1898  }
1899 }
1900 
1901 
1902 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
Foam::edgeList
List< edge > edgeList
A List of edges.
Definition: edgeList.H:63
polyRemovePoint.H
Foam::primitiveFacePatch
PrimitivePatch< List< face >, const pointField & > primitiveFacePatch
A PrimitivePatch with List storage for the faces, const reference for the point field.
Definition: primitiveFacePatch.H:51
Foam::polyMeshModifier::topoChanger
const polyTopoChanger & topoChanger() const
Return reference to morph engine.
Definition: polyMeshModifier.C:63
polyAddFace.H
polyRemoveFace.H
polyTopoChanger.H
polyTopoChange.H
Foam::boolList
List< bool > boolList
A List of bools.
Definition: List.H:65
primitiveMesh.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::primitiveMesh::edgesPerFace_
static const unsigned edgesPerFace_
Estimated number of edges per cell.
Definition: primitiveMesh.H:416
ref
rDeltaT ref()
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
triPointRef.H
polyMesh.H
pointHit.H
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:54
Foam::magSqr
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
Foam::faceZoneMesh
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with the type faceZone.
Definition: faceZoneMeshFwd.H:44
Foam::constant::physicoChemical::b
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
polyModifyPoint.H
plane.H
polyAddPoint.H
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
newPointi
label newPointi
Definition: readKivaGrid.H:496
Foam::FatalError
error FatalError
Foam::pointHit
PointHit< point > pointHit
A PointIndexHit for 3D points.
Definition: pointHit.H:44
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
polyModifyFace.H
Foam::polyMeshModifier::name
const word & name() const
Return name of this modifier.
Definition: polyMeshModifier.H:150
Foam::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
Foam::linePointRef
line< point, const point & > linePointRef
A line using referred points.
Definition: linePointRef.H:47
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::sqr
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Definition: dimensionedSymmTensor.C:51
slidingInterface.H
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::polyTopoChanger::mesh
const polyMesh & mesh() const
Return the mesh reference.
Definition: polyTopoChanger.H:111
Foam::faceList
List< face > faceList
A List of faces.
Definition: faceListFwd.H:47
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::List::clear
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:116
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:191
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:295
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
DynamicList.H
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::labelHashSet
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85
enrichedPatch.H
Foam::DynamicID::index
label index() const
The index of the first matching items, -1 if no matches.
Definition: DynamicID.H:123