29 #include "indirectPrimitivePatch.H"
66 const edge&
e = edges[edgeI];
72 if (pointMap[pointI] == -1)
74 pointMap[pointI] = newPointI++;
93 const edge&
e = edges[edgeI];
95 str<<
"l " << pointMap[
e[0]]+1 <<
' ' << pointMap[
e[1]]+1 <<
nl;
108 Pout<<
"Writing connections as edges to " << fName <<
endl;
120 str <<
"l " << vertI-1 <<
' ' << vertI <<
nl;
151 Pout<<
"Writing cutToMasterPoints to cutToMasterPoints.obj" <<
endl;
155 "cutToMasterPoints.obj",
160 Pout<<
"Writing cutToSlavePoints to cutToSlavePoints.obj" <<
endl;
164 "cutToSlavePoints.obj",
172 Pout<<
"Writing cutToMasterFaces to cutToMasterFaces.obj" <<
endl;
180 if (masterFaceI != -1)
182 equivMasterFaces[cutFaceI] = m[masterFaceI].centre(m.
points());
187 <<
"No master face for cut face " << cutFaceI
188 <<
" at position " <<
c[cutFaceI].centre(
c.points())
197 "cutToMasterFaces.obj",
198 calcFaceCentres<List>(
c,
cutPoints(), 0,
c.size()),
204 Pout<<
"Writing cutToSlaveFaces to cutToSlaveFaces.obj" <<
endl;
212 equivSlaveFaces[cutFaceI] =
s[slaveFaceI].centre(
s.points());
217 "cutToSlaveFaces.obj",
218 calcFaceCentres<List>(
c,
cutPoints(), 0,
c.size()),
239 OFstream str(
"cutToMasterEdges.obj");
240 Pout<<
"Writing cutToMasterEdges to " << str.
name() <<
endl;
244 forAll(cutToMasterEdges, cutEdgeI)
246 if (cutToMasterEdges[cutEdgeI] != -1)
248 const edge& masterEdge =
249 m.
edges()[cutToMasterEdges[cutEdgeI]];
250 const edge& cutEdge =
c.edges()[cutEdgeI];
260 str <<
"l " << vertI-3 <<
' ' << vertI-2 <<
nl;
261 str <<
"l " << vertI-3 <<
' ' << vertI-1 <<
nl;
262 str <<
"l " << vertI-3 <<
' ' << vertI <<
nl;
263 str <<
"l " << vertI-2 <<
' ' << vertI-1 <<
nl;
264 str <<
"l " << vertI-2 <<
' ' << vertI <<
nl;
265 str <<
"l " << vertI-1 <<
' ' << vertI <<
nl;
270 OFstream str(
"cutToSlaveEdges.obj");
271 Pout<<
"Writing cutToSlaveEdges to " << str.
name() <<
endl;
279 if (slaveToCut[edgeI] != -1)
281 const edge& slaveEdge =
s.edges()[edgeI];
282 const edge& cutEdge =
c.edges()[slaveToCut[edgeI]];
292 str <<
"l " << vertI-3 <<
' ' << vertI-2 <<
nl;
293 str <<
"l " << vertI-3 <<
' ' << vertI-1 <<
nl;
294 str <<
"l " << vertI-3 <<
' ' << vertI <<
nl;
295 str <<
"l " << vertI-2 <<
' ' << vertI-1 <<
nl;
296 str <<
"l " << vertI-2 <<
' ' << vertI <<
nl;
297 str <<
"l " << vertI-1 <<
' ' << vertI <<
nl;
317 forAll(toPatchEdges, edgeI)
319 const edge&
e = edges[edgeI];
321 label v0 = pointMap[
e[0]];
322 label v1 = pointMap[
e[1]];
324 toPatchEdges[edgeI] =
342 const label slaveEdgeI
345 const labelList& eFaces = slavePatch().edgeFaces()[slaveEdgeI];
347 if (eFaces.
size() == 1)
359 label faceI = eFaces[i];
361 label meshFaceI = slavePatch().addressing()[faceI];
369 else if (patchI != patch0)
387 const bool patchDivision,
391 const label edgeStart,
395 const pointField& localPoints = cutFaces().localPoints();
397 const labelList& pEdges = cutFaces().pointEdges()[pointI];
401 Pout<<
"mostAlignedEdge : finding nearest edge among "
403 <<
" connected to point " << pointI
404 <<
" coord:" << localPoints[pointI]
405 <<
" running between " << edgeStart <<
" coord:"
406 << localPoints[edgeStart]
407 <<
" and " << edgeEnd <<
" coord:"
408 << localPoints[edgeEnd]
415 scalar maxCos = -GREAT;
419 label edgeI = pEdges[i];
425 && cutToMasterEdges[edgeI] == -1
429 && regionEdge(slaveMesh, cutToSlaveEdges[edgeI])
433 const edge&
e = cutFaces().edges()[edgeI];
435 label otherPointI =
e.otherVertex(pointI);
437 if (otherPointI == edgeEnd)
442 Pout<<
" mostAlignedEdge : found end point " << edgeEnd
450 vector eVec(localPoints[otherPointI] - localPoints[pointI]);
452 scalar magEVec =
mag(eVec);
454 if (magEVec < VSMALL)
457 <<
"Crossing zero sized edge " << edgeI
458 <<
" coords:" << localPoints[otherPointI]
459 << localPoints[pointI]
460 <<
" when walking from " << localPoints[edgeStart]
461 <<
" to " << localPoints[edgeEnd]
468 vector eToEndPoint(localPoints[edgeEnd] - localPoints[otherPointI]);
469 eToEndPoint /=
mag(eToEndPoint);
471 scalar cosAngle = eVec & eToEndPoint;
475 Pout<<
" edge:" <<
e <<
" points:" << localPoints[pointI]
476 << localPoints[otherPointI]
478 <<
" vecToEnd:" << eToEndPoint
479 <<
" cosAngle:" << cosAngle
483 if (cosAngle > maxCos)
491 if (maxCos > 1 - angleTol_)
509 masterPatch().nEdges(),
514 const edgeList& cutEdges = cutFaces().edges();
519 masterPatch().nEdges()
520 + slavePatch().nEdges()
524 forAll(masterToCutEdges, masterEdgeI)
526 const edge& masterE = masterPatch().edges()[masterEdgeI];
531 const labelList& stringedEdges = masterToCutEdges[masterEdgeI];
533 if (stringedEdges.empty())
536 <<
"Did not match all of master edges to cutFace edges"
538 <<
"First unmatched edge:" << masterEdgeI <<
" endPoints:"
539 << masterPatch().localPoints()[masterE[0]]
540 << masterPatch().localPoints()[masterE[1]]
542 <<
"This usually means that the slave patch is not a"
543 <<
" subdivision of the master patch"
546 else if (stringedEdges.
size() > 1)
554 const edge unsplitEdge
556 masterToCutPoints_[masterE[0]],
557 masterToCutPoints_[masterE[1]]
560 label startVertI = unsplitEdge[0];
561 label startEdgeI = -1;
563 while (startVertI != unsplitEdge[1])
571 label oldStart = startVertI;
575 label edgeI = stringedEdges[i];
577 if (edgeI != startEdgeI)
579 const edge&
e = cutEdges[edgeI];
585 if (
e[0] == startVertI)
589 if (
e[1] != unsplitEdge[1])
595 else if (
e[1] == startVertI)
599 if (
e[0] != unsplitEdge[1])
609 if (oldStart == startVertI)
612 <<
" unsplitEdge:" << unsplitEdge
613 <<
" does not correspond to split edges "
629 cutEdgeToPoints_.insert(unsplitEdge, splitPoints.
shrink());
644 const bool sameOrientation
647 if (f0.
size() !=
f1.size())
650 <<
"Different sizes for supposedly matching faces." <<
nl
657 const scalar absTolSqr =
sqr(absTol);
665 bool fullMatch =
true;
672 scalar distSqr =
Foam::magSqr(points0[f0[fp0]] - points1[
f1[fp1]]);
674 if (distSqr > absTolSqr)
680 fp0 = f0.fcIndex(fp0);
684 fp1 =
f1.fcIndex(fp1);
688 fp1 =
f1.rcIndex(fp1);
702 <<
"No unique match between two faces" <<
nl
703 <<
"Face " << f0 <<
" coords "
705 <<
"Face " <<
f1 <<
" coords "
707 <<
"when using tolerance " << absTol
708 <<
" and forwardMatching:" << sameOrientation
728 const bool sameOrientation,
737 patchToCutPoints.
setSize(patchPoints.size());
738 patchToCutPoints = -1;
742 labelList cutPointRegion(cutPoints.size(), -1);
750 const face& cutF = cutFaces[patchFaceI];
753 label patchFp = matchFaces
765 label cutPointI = cutF[cutFp];
766 label patchPointI = patchF[patchFp];
778 if (patchToCutPoints[patchPointI] == -1)
780 patchToCutPoints[patchPointI] = cutPointI;
782 else if (patchToCutPoints[patchPointI] != cutPointI)
786 label otherCutPointI = patchToCutPoints[patchPointI];
795 if (cutPointRegion[otherCutPointI] != -1)
798 label region = cutPointRegion[otherCutPointI];
799 cutPointRegion[cutPointI] = region;
802 cutPointRegionMaster[region] =
min
804 cutPointRegionMaster[region],
811 label region = cutPointRegionMaster.size();
812 cutPointRegionMaster.
append
814 min(cutPointI, otherCutPointI)
816 cutPointRegion[cutPointI] = region;
817 cutPointRegion[otherCutPointI] = region;
823 patchFp = patchF.fcIndex(patchFp);
827 patchFp = patchF.rcIndex(patchFp);
836 label compactPointI = 0;
840 if (cutPointRegion[i] == -1)
843 cutToCompact[i] = compactPointI;
844 compactToCut[compactPointI] = i;
851 label masterPointI = cutPointRegionMaster[cutPointRegion[i]];
853 if (cutToCompact[masterPointI] == -1)
855 cutToCompact[masterPointI] = compactPointI;
856 compactToCut[compactPointI] = masterPointI;
859 cutToCompact[i] = cutToCompact[masterPointI];
862 compactToCut.
setSize(compactPointI);
864 return compactToCut.
size() != cutToCompact.
size();
877 scalar maxDist = -GREAT;
881 const point& cutPt = cutPoints[cutF[fp]];
906 calcFaceCentres<List>
917 calcFaceCentres<List>
929 Pout<<
"Face matching tolerance : " << absTol <<
endl;
947 <<
"faceCoupleInfo::faceCoupleInfo : "
948 <<
"Matched ALL " << fc1.size()
949 <<
" boundary faces of mesh0 to boundary faces of mesh1." <<
endl
950 <<
"This is only valid if the mesh to add is fully"
951 <<
" enclosed by the mesh it is added to." <<
endl;
958 mesh0Faces.
setSize(fc0.size());
959 mesh1Faces.
setSize(fc1.size());
963 if (from1To0[i] != -1)
1014 Pout<<
"findSlavesCoveringMaster :"
1015 <<
" constructed octree for mesh0 boundary faces" <<
endl;
1026 mesh1FaceI < mesh1.
nFaces();
1052 mesh0.
faces()[mesh0FaceI],
1058 mesh0Set.
insert(mesh0FaceI);
1059 mesh1Set.
insert(mesh1FaceI);
1066 Pout<<
"findSlavesCoveringMaster :"
1067 <<
" matched " << mesh1Set.
size() <<
" mesh1 faces to "
1068 << mesh0Set.
size() <<
" mesh0 faces" <<
endl;
1071 mesh0Faces = mesh0Set.
toc();
1072 mesh1Faces = mesh1Set.
toc();
1085 Pout<<
"growCutFaces :"
1086 <<
" growing cut faces to masterPatch" <<
endl;
1089 label nTotChanged = 0;
1098 forAll(cutToMasterFaces_, cutFaceI)
1100 const label masterFaceI = cutToMasterFaces_[cutFaceI];
1102 if (masterFaceI != -1)
1108 const labelList& fEdges = cutFaceEdges[cutFaceI];
1112 const label cutEdgeI = fEdges[i];
1114 if (cutToMasterEdges[cutEdgeI] == -1)
1122 const labelList& eFaces = cutEdgeFaces[cutEdgeI];
1126 const label faceI = eFaces[j];
1128 if (cutToMasterFaces_[faceI] == -1)
1130 cutToMasterFaces_[faceI] = masterFaceI;
1131 candidates.erase(faceI);
1134 else if (cutToMasterFaces_[faceI] != masterFaceI)
1137 cutFaces().points();
1139 masterPatch().points();
1141 const edge&
e = cutFaces().edges()[cutEdgeI];
1143 label myMaster = cutToMasterFaces_[faceI];
1144 const face& myF = masterPatch()[myMaster];
1146 const face& nbrF = masterPatch()[masterFaceI];
1150 << cutFaces()[faceI].points(cutPoints)
1153 <<
" but also connects to nbr face "
1154 << cutFaces()[cutFaceI].points(cutPoints)
1155 <<
" with master " << masterFaceI
1158 << myF.
points(masterPoints)
1159 <<
" nbrMasterFace:"
1161 <<
"Across cut edge " << cutEdgeI
1163 << cutFaces().localPoints()[
e[0]]
1164 << cutFaces().localPoints()[
e[1]]
1175 Pout<<
"growCutFaces : Grown an additional " << nChanged
1176 <<
" cut to master face" <<
" correspondence" <<
endl;
1179 nTotChanged += nChanged;
1193 const pointField& cutLocalPoints = cutFaces().localPoints();
1195 const pointField& masterLocalPoints = masterPatch().localPoints();
1196 const faceList& masterLocalFaces = masterPatch().localFaces();
1198 forAll(cutToMasterEdges, cutEdgeI)
1200 const edge&
e = cutFaces().edges()[cutEdgeI];
1202 if (cutToMasterEdges[cutEdgeI] == -1)
1205 const labelList& cutEFaces = cutFaces().edgeFaces()[cutEdgeI];
1207 label masterFaceI = -1;
1211 label cutFaceI = cutEFaces[i];
1213 if (cutToMasterFaces_[cutFaceI] != -1)
1215 if (masterFaceI == -1)
1217 masterFaceI = cutToMasterFaces_[cutFaceI];
1219 else if (masterFaceI != cutToMasterFaces_[cutFaceI])
1221 label myMaster = cutToMasterFaces_[cutFaceI];
1222 const face& myF = masterLocalFaces[myMaster];
1224 const face& nbrF = masterLocalFaces[masterFaceI];
1227 <<
"Internal CutEdge " <<
e
1229 << cutLocalPoints[
e[0]]
1230 << cutLocalPoints[
e[1]]
1231 <<
" connects to master " << myMaster
1232 <<
" and to master " << masterFaceI <<
nl
1234 << myF.
points(masterLocalPoints)
1235 <<
" nbrMasterFace:"
1236 << nbrF.
points(masterLocalPoints)
1257 candidates.resize(cutFaces().size());
1261 forAll(cutToMasterEdges, cutEdgeI)
1263 label masterEdgeI = cutToMasterEdges[cutEdgeI];
1265 if (masterEdgeI != -1)
1270 const labelList& cutEFaces = cutFaces().edgeFaces()[cutEdgeI];
1272 masterPatch().edgeFaces()[masterEdgeI];
1276 label cutFaceI = cutEFaces[i];
1278 if (cutToMasterFaces_[cutFaceI] == -1)
1289 if (fnd == candidates.end())
1293 candidates.insert(cutFaceI, masterEFaces);
1306 if (
findIndex(masterFaces, masterEFaces[j]) != -1)
1308 newCandidates.
append(masterEFaces[j]);
1312 if (newCandidates.size() == 1)
1316 cutToMasterFaces_[cutFaceI] = newCandidates[0];
1317 candidates.erase(cutFaceI);
1330 fnd() = newCandidates.
shrink();
1341 Pout<<
"matchEdgeFaces : Found " << nChanged
1342 <<
" faces where there was"
1343 <<
" only one remaining choice for cut-master correspondence"
1359 const pointField& cutPoints = cutFaces().points();
1369 masterPatch().size(),
1376 label cutFaceI = iter.key();
1378 const face& cutF = cutFaces()[cutFaceI];
1380 if (cutToMasterFaces_[cutFaceI] == -1)
1385 scalar minDist = GREAT;
1386 label minMasterFaceI = -1;
1390 label masterFaceI = masterFaces[i];
1392 if (masterToCutFaces[masterFaces[i]].empty())
1394 scalar dist = maxDistance
1398 masterPatch()[masterFaceI],
1405 minMasterFaceI = masterFaceI;
1410 if (minMasterFaceI != -1)
1412 cutToMasterFaces_[cutFaceI] = minMasterFaceI;
1413 masterToCutFaces[minMasterFaceI] = cutFaceI;
1420 forAll(cutToMasterFaces_, cutFaceI)
1422 if (cutToMasterFaces_[cutFaceI] != -1)
1424 candidates.erase(cutFaceI);
1431 Pout<<
"geometricMatchEdgeFaces : Found " << nChanged
1432 <<
" faces where there was"
1433 <<
" only one remaining choice for cut-master correspondence"
1445 const scalar absTol,
1446 const bool slaveFacesOrdered
1451 Pout<<
"perfectPointMatch :"
1452 <<
" Matching master and slave to cut."
1453 <<
" Master and slave faces are identical" <<
nl;
1455 if (slaveFacesOrdered)
1457 Pout<<
"and master and slave faces are ordered"
1458 <<
" (on coupled patches)" <<
endl;
1462 Pout<<
"and master and slave faces are not ordered"
1463 <<
" (on coupled patches)" <<
endl;
1467 cutToMasterFaces_ =
identity(masterPatch().size());
1468 cutPoints_ = masterPatch().localPoints();
1473 masterPatch().localFaces(),
1477 masterToCutPoints_ =
identity(cutPoints_.size());
1481 bool matchedAllFaces =
false;
1483 if (slaveFacesOrdered)
1485 cutToSlaveFaces_ =
identity(cutFaces().size());
1486 matchedAllFaces = (cutFaces().
size() == slavePatch().size());
1495 calcFaceCentres<List>
1502 calcFaceCentres<IndirectList>
1516 if (!matchedAllFaces)
1519 <<
"Did not match all of the master faces to the slave faces"
1521 <<
"This usually means that the slave patch and master patch"
1522 <<
" do not align to within " << absTol <<
" metre."
1532 matchPointsThroughFaces
1535 cutFaces().localPoints(),
1536 reorder(cutToSlaveFaces_, cutFaces().localFaces()),
1537 slavePatch().localPoints(),
1538 slavePatch().localFaces(),
1550 const faceList& cutLocalFaces = cutFaces().localFaces();
1555 compactFaces[i] =
renumber(cutToCompact, cutLocalFaces[i]);
1576 const bool patchDivision,
1582 Pout<<
"subDivisionMatch :"
1583 <<
" Matching master and slave to cut."
1584 <<
" Slave can be subdivision of master but all master edges"
1585 <<
" have to be covered by slave edges." <<
endl;
1590 cutPoints_ = slavePatch().localPoints();
1592 faceList cutFaces(slavePatch().size());
1596 cutFaces[i] = slavePatch().localFaces()[i].reverseFace();
1602 cutToSlaveFaces_ =
identity(cutFaces().size());
1621 Pout<<
"subDivisionMatch :"
1622 <<
" addressing for slave patch fully done."
1623 <<
" Dumping region edges to " << str.
name() <<
endl;
1627 forAll(slavePatch().edges(), slaveEdgeI)
1629 if (regionEdge(slaveMesh, slaveEdgeI))
1631 const edge&
e = slavePatch().edges()[slaveEdgeI];
1637 str<<
"l " << vertI-1 <<
' ' << vertI <<
nl;
1650 Pout<<
"subDivisionMatch :"
1651 <<
" matching master points to cut points" <<
endl;
1656 masterPatch().localPoints(),
1663 if (!matchedAllPoints)
1666 <<
"Did not match all of the master points to the slave points"
1668 <<
"This usually means that the slave patch is not a"
1669 <<
" subdivision of the master patch"
1681 Pout<<
"subDivisionMatch :"
1682 <<
" matching cut edges to master edges" <<
endl;
1685 const edgeList& masterEdges = masterPatch().edges();
1686 const pointField& masterPoints = masterPatch().localPoints();
1688 const edgeList& cutEdges = cutFaces().edges();
1690 labelList cutToMasterEdges(cutFaces().nEdges(), -1);
1692 forAll(masterEdges, masterEdgeI)
1694 const edge& masterEdge = masterEdges[masterEdgeI];
1696 label cutPoint0 = masterToCutPoints_[masterEdge[0]];
1697 label cutPoint1 = masterToCutPoints_[masterEdge[1]];
1701 label cutPointI = cutPoint0;
1734 Pout<<
"Dumping unmatched pointEdges to errorEdges.obj"
1745 cutFaces().pointEdges()[cutPointI]
1748 cutFaces().localPoints(),
1753 <<
"Problem in finding cut edges corresponding to"
1754 <<
" master edge " << masterEdge
1755 <<
" points:" << masterPoints[masterEdge[0]]
1756 <<
' ' << masterPoints[masterEdge[1]]
1757 <<
" corresponding cut edge: (" << cutPoint0
1758 <<
") " << cutPoint1
1762 cutToMasterEdges[cutEdgeI] = masterEdgeI;
1764 cutPointI = cutEdges[cutEdgeI].otherVertex(cutPointI);
1766 }
while (cutPointI != cutPoint1);
1772 writeEdges(cutToMasterEdges, cutToSlaveEdges);
1777 setCutEdgeToPoints(cutToMasterEdges);
1791 Pout<<
"subDivisionMatch :"
1792 <<
" matching (topological) cut faces to masterPatch" <<
endl;
1798 cutToMasterFaces_.setSize(cutFaces().size());
1799 cutToMasterFaces_ = -1;
1805 label nChanged = matchEdgeFaces(cutToMasterEdges, candidates);
1807 checkMatch(cutToMasterEdges);
1814 nChanged += growCutFaces(cutToMasterEdges, candidates);
1816 checkMatch(cutToMasterEdges);
1826 Pout<<
"subDivisionMatch :"
1827 <<
" matching (geometric) cut faces to masterPatch" <<
endl;
1836 label nChanged = geometricMatchEdgeFaces(candidates);
1838 checkMatch(cutToMasterEdges);
1840 nChanged += growCutFaces(cutToMasterEdges, candidates);
1842 checkMatch(cutToMasterEdges);
1852 forAll(cutToMasterFaces_, cutFaceI)
1854 if (cutToMasterFaces_[cutFaceI] == -1)
1856 const face& cutF = cutFaces()[cutFaceI];
1859 <<
"Did not match all of cutFaces to a master face" <<
nl
1860 <<
"First unmatched cut face:" << cutFaceI <<
" with points:"
1863 <<
"This usually means that the slave patch is not a"
1864 <<
" subdivision of the master patch"
1871 Pout<<
"subDivisionMatch :"
1872 <<
" finished matching master and slave to cut" <<
endl;
1889 const scalar absTol,
1890 const bool perfectMatch
1893 masterPatchPtr_(NULL),
1894 slavePatchPtr_(NULL),
1897 cutToMasterFaces_(0),
1898 masterToCutPoints_(0),
1899 cutToSlaveFaces_(0),
1900 slaveToCutPoints_(0),
1912 findPerfectMatchingFaces
1925 findSlavesCoveringMaster
1936 masterPatchPtr_.reset
1945 slavePatchPtr_.reset
1958 perfectPointMatch(absTol,
false);
1963 subDivisionMatch(slaveMesh,
false, absTol);
1981 const scalar absTol,
1982 const bool perfectMatch,
1983 const bool orderedFaces,
1984 const bool patchDivision
2005 cutToMasterFaces_(0),
2006 masterToCutPoints_(0),
2007 cutToSlaveFaces_(0),
2008 slaveToCutPoints_(0),
2011 if (perfectMatch && (masterAddressing.
size() != slaveAddressing.
size()))
2014 <<
"Perfect match specified but number of master and slave faces"
2015 <<
" differ." <<
endl
2016 <<
"master:" << masterAddressing.
size()
2017 <<
" slave:" << slaveAddressing.
size()
2023 masterAddressing.
size()
2028 <<
"Supplied internal face on master mesh to couple." <<
nl
2029 <<
"Faces to be coupled have to be boundary faces."
2034 slaveAddressing.
size()
2039 <<
"Supplied internal face on slave mesh to couple." <<
nl
2040 <<
"Faces to be coupled have to be boundary faces."
2047 perfectPointMatch(absTol, orderedFaces);
2052 subDivisionMatch(slaveMesh, patchDivision, absTol);
2092 map.insert(i, lst[i]);
2110 map.insert(i, lst[i]);