54 bool Foam::combineFaces::convexFace
56 const scalar minConcaveCos,
66 scalar magEPrev =
mag(ePrev);
67 ePrev /= magEPrev + VSMALL;
72 label fp1 =
f.fcIndex(fp0);
76 scalar magE10 =
mag(e10);
77 e10 /= magE10 + VSMALL;
79 if (magEPrev > SMALL && magE10 > SMALL)
81 vector edgeNormal = ePrev ^ e10;
83 if ((edgeNormal & areaNorm) < 0)
86 if ((ePrev & e10) < minConcaveCos)
103 bool Foam::combineFaces::validFace
105 const scalar minConcaveCos,
112 if (edgeLoops.size() > 1)
117 bool isNonManifold = bigFace.checkPointManifold(
false,
nullptr);
124 face
f(getOutsideFace(bigFace));
126 return convexFace(minConcaveCos, bigFace.points(),
f);
130 void Foam::combineFaces::regioniseFaces
133 const bool mergeAcrossPatches,
136 Map<label>& faceRegion
139 const polyBoundaryMesh&
patches = mesh_.boundaryMesh();
143 const label edgeI = cEdges[i];
148 const vector&
a0 = mesh_.faceAreas()[f0];
149 const vector& a1 = mesh_.faceAreas()[f1];
172 if (!mergeAcrossPatches && (
p0 != p1))
180 if ((f0Normal & f1Normal) > minCos)
182 const label region0 = faceRegion.lookup(f0, -1);
183 const label region1 = faceRegion.lookup(f1, -1);
189 const label useRegion = faceRegion.size();
190 faceRegion.insert(f0, useRegion);
191 faceRegion.insert(f1, useRegion);
195 faceRegion.insert(f0, region1);
202 faceRegion.insert(f1, region0);
204 else if (region0 != region1)
207 const label useRegion =
min(region0, region1);
208 const label freeRegion =
max(region0, region1);
212 if (iter.val() == freeRegion)
214 iter.val() = useRegion;
225 bool Foam::combineFaces::faceNeighboursValid
228 const Map<label>& faceRegion
231 if (faceRegion.size() <= 1)
236 const cell& cFaces = mesh_.cells()[celli];
238 DynamicList<label> storage;
243 label facei = cFaces[cFacei];
245 if (!faceRegion.found(facei))
247 const labelList& fEdges = mesh_.faceEdges(facei, storage);
253 DynamicList<label> neighbourFaces(cFaces.size());
259 const label edgeI = fEdges[i];
262 const auto iter = faceRegion.cfind(nbrI);
266 neighbourRegions.insert(iter.val());
270 neighbourFaces.appendUniq(nbrI);
274 if ((neighbourFaces.size()+neighbourRegions.size()) < 3)
287 Foam::combineFaces::combineFaces
296 faceSetsVertices_(0),
297 savedPointLabels_(0),
306 const scalar featureCos,
307 const scalar minConcaveCos,
309 const bool mergeAcrossPatches
319 for (
const label celli : boundaryCells)
321 const cell& cFaces = mesh_.cells()[celli];
323 const labelList& cEdges = mesh_.cellEdges(celli,
set, storage);
342 if (faceNeighboursValid(celli, faceRegion))
349 const label facei = iter.key();
350 const label region = iter.val();
352 auto regionFnd = regionToFaces.find(region);
354 if (regionFnd.found())
357 label sz = setFaces.size();
359 setFaces[sz] = facei;
363 regionToFaces.insert(region,
labelList(1, facei));
383 if (validFace(minConcaveCos, bigFace))
390 if (mergeAcrossPatches)
396 for (label i = 1; i < faceIDs.size(); ++i)
398 const scalar a2 =
magSqr(areas[faceIDs[i]]);
407 std::swap(faceIDs[0], faceIDs[maxIndex]);
411 allFaceSets.append(faceIDs);
417 return allFaceSets.shrink();
423 const scalar featureCos,
424 const scalar minConcaveCos,
425 const bool mergeAcrossPatches
437 if (!
patch.coupled())
441 boundaryCells.
insert(mesh_.faceOwner()[
patch.start()+i]);
467 <<
"Multiple outside loops:" << fp.
edgeLoops()
479 if (eFaces.size() != 1)
482 <<
"boundary edge:" << bEdgeI
485 <<
" on indirectPrimitivePatch has " << eFaces.size()
499 bool edgeLoopConsistent =
false;
502 label index0 = outsideLoop.find(
e[0]);
503 label index1 = outsideLoop.find(
e[1]);
505 if (index0 == -1 || index1 == -1)
508 <<
"Cannot find boundary edge:" <<
e
513 else if (index1 == outsideLoop.fcIndex(index0))
515 edgeLoopConsistent =
true;
517 else if (index0 == outsideLoop.fcIndex(index1))
519 edgeLoopConsistent =
false;
524 <<
"Cannot find boundary edge:" <<
e
527 <<
" on consecutive points in edgeLoop:"
541 bool faceEdgeConsistent =
false;
545 label index = fp.
faceEdges()[eFaces[0]].find(bEdgeI);
550 <<
"Cannot find boundary edge:" <<
e
553 <<
" in face:" << eFaces[0]
554 <<
" edges:" << fp.
faceEdges()[eFaces[0]]
557 else if (localF[index] ==
e[0] && localF.
nextLabel(index) ==
e[1])
559 faceEdgeConsistent =
true;
561 else if (localF[index] ==
e[1] && localF.
nextLabel(index) ==
e[0])
563 faceEdgeConsistent =
false;
568 <<
"Cannot find boundary edge:" <<
e
571 <<
" in face:" << eFaces[0] <<
" verts:" << localF
579 if (faceEdgeConsistent != edgeLoopConsistent)
595 masterFace_.setSize(faceSets.size());
596 faceSetsVertices_.setSize(faceSets.size());
599 const labelList& setFaces = faceSets[setI];
601 masterFace_[setI] = setFaces[0];
615 forAll(pointFaces, pointi)
617 nPointFaces[pointi] = pointFaces[pointi].size();
624 const labelList& setFaces = faceSets[setI];
636 <<
"Can only merge non-coupled boundary faces"
637 <<
" but found internal or coupled face:"
638 << setFaces[i] <<
" in set " << setI
658 if (edgeLoops.size() != 1)
661 <<
"Faces to-be-merged " << setFaces
662 <<
" do not form a single big face." <<
nl
672 label masterFacei = setFaces[0];
675 face outsideFace(getOutsideFace(bigFace));
677 label
zoneID = mesh_.faceZones().whichZone(masterFacei);
679 bool zoneFlip =
false;
688 label patchi = mesh_.boundaryMesh().whichPatch(masterFacei);
696 mesh_.faceOwner()[masterFacei],
710 for (label i = 1; i < setFaces.size(); i++)
722 const face&
f = mesh_.faces()[setFaces[i]];
726 nPointFaces[
f[fp]]--;
732 nPointFaces[outsideFace[fp]]++;
749 forAll(nPointFaces, pointi)
751 if (nPointFaces[pointi] == 0)
761 forAll(nPointFaces, pointi)
763 if (nPointFaces[pointi] == 0)
769 savedPointLabels_.setSize(
n);
770 savedPoints_.setSize(
n);
775 forAll(nPointFaces, pointi)
777 if (nPointFaces[pointi] == 0)
781 savedPointLabels_[
n] = pointi;
782 savedPoints_[
n] = mesh_.points()[pointi];
784 meshToSaved.insert(pointi,
n);
790 forAll(faceSetsVertices_, setI)
792 faceList& setFaces = faceSetsVertices_[setI];
796 face&
f = setFaces[i];
800 label pointi =
f[fp];
802 if (nPointFaces[pointi] == 0)
804 f[fp] = -meshToSaved[pointi]-1;
822 forAll(faceSetsVertices_, setI)
824 faceList& faces = faceSetsVertices_[setI];
833 label pointi =
f[fp];
842 <<
"In set " << setI <<
" at position " << i
843 <<
" with master face "
844 << masterFace_[setI] <<
nl
845 <<
"the points of the slave face " << faces[i]
846 <<
" don't exist anymore."
873 <<
"Can only call setUnrefinement if constructed with"
879 labelList addedPoints(savedPoints_.size(), -1);
886 if (masterFace_[setI] >= 0)
888 masterToSet.insert(masterFace_[setI], setI);
894 const label masterFacei = masterFaces[i];
896 const auto iter = masterToSet.cfind(masterFacei);
901 <<
"Master face " << masterFacei
902 <<
" is not the master of one of the merge sets"
903 <<
" or has already been merged"
907 const label setI = iter.val();
913 faceList& faces = faceSetsVertices_[setI];
918 <<
"Set " << setI <<
" with master face " << masterFacei
928 label pointi =
f[fp];
932 label localI = -pointi-1;
934 if (addedPoints[localI] == -1)
941 savedPoints_[localI],
947 restoredPoints.insert
950 savedPointLabels_[localI]
954 f[fp] = addedPoints[localI];
963 label own = mesh_.faceOwner()[masterFacei];
964 label
zoneID = mesh_.faceZones().whichZone(masterFacei);
965 bool zoneFlip =
false;
971 label patchi = mesh_.boundaryMesh().whichPatch(masterFacei);
973 if (mesh_.boundaryMesh()[patchi].coupled())
976 <<
"Master face " << masterFacei <<
" is on coupled patch "
977 << mesh_.boundaryMesh()[patchi].name()
1000 restoredFaces.insert(masterFacei, masterFacei);
1003 for (label i = 1; i < faces.size(); i++)
1024 restoredFaces.insert(facei, masterFacei);
1028 faceSetsVertices_[setI].clear();
1029 masterFace_[setI] = -1;