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 if (!neighbourFaces.found(nbrI))
272 neighbourFaces.append(nbrI);
277 if ((neighbourFaces.size()+neighbourRegions.size()) < 3)
290 Foam::combineFaces::combineFaces
299 faceSetsVertices_(0),
300 savedPointLabels_(0),
309 const scalar featureCos,
310 const scalar minConcaveCos,
312 const bool mergeAcrossPatches
322 for (
const label celli : boundaryCells)
324 const cell& cFaces = mesh_.cells()[celli];
326 const labelList& cEdges = mesh_.cellEdges(celli,
set, storage);
345 if (faceNeighboursValid(celli, faceRegion))
352 const label facei = iter.key();
353 const label region = iter.val();
355 auto regionFnd = regionToFaces.find(region);
357 if (regionFnd.found())
360 label sz = setFaces.size();
362 setFaces[sz] = facei;
366 regionToFaces.insert(region,
labelList(1, facei));
386 if (validFace(minConcaveCos, bigFace))
393 if (mergeAcrossPatches)
399 for (label i = 1; i < faceIDs.size(); ++i)
401 const scalar a2 =
magSqr(areas[faceIDs[i]]);
410 Swap(faceIDs[0], faceIDs[maxIndex]);
414 allFaceSets.append(faceIDs);
420 return allFaceSets.shrink();
426 const scalar featureCos,
427 const scalar minConcaveCos,
428 const bool mergeAcrossPatches
440 if (!
patch.coupled())
444 boundaryCells.
insert(mesh_.faceOwner()[
patch.start()+i]);
470 <<
"Multiple outside loops:" << fp.
edgeLoops()
482 if (eFaces.size() != 1)
485 <<
"boundary edge:" << bEdgeI
488 <<
" on indirectPrimitivePatch has " << eFaces.size()
502 bool edgeLoopConsistent =
false;
505 label index0 = outsideLoop.find(
e[0]);
506 label index1 = outsideLoop.find(
e[1]);
508 if (index0 == -1 || index1 == -1)
511 <<
"Cannot find boundary edge:" <<
e
516 else if (index1 == outsideLoop.fcIndex(index0))
518 edgeLoopConsistent =
true;
520 else if (index0 == outsideLoop.fcIndex(index1))
522 edgeLoopConsistent =
false;
527 <<
"Cannot find boundary edge:" <<
e
530 <<
" on consecutive points in edgeLoop:"
544 bool faceEdgeConsistent =
false;
548 label index = fp.
faceEdges()[eFaces[0]].find(bEdgeI);
553 <<
"Cannot find boundary edge:" <<
e
556 <<
" in face:" << eFaces[0]
557 <<
" edges:" << fp.
faceEdges()[eFaces[0]]
560 else if (localF[index] ==
e[0] && localF.
nextLabel(index) ==
e[1])
562 faceEdgeConsistent =
true;
564 else if (localF[index] ==
e[1] && localF.
nextLabel(index) ==
e[0])
566 faceEdgeConsistent =
false;
571 <<
"Cannot find boundary edge:" <<
e
574 <<
" in face:" << eFaces[0] <<
" verts:" << localF
582 if (faceEdgeConsistent != edgeLoopConsistent)
598 masterFace_.setSize(faceSets.size());
599 faceSetsVertices_.setSize(faceSets.size());
602 const labelList& setFaces = faceSets[setI];
604 masterFace_[setI] = setFaces[0];
618 forAll(pointFaces, pointi)
620 nPointFaces[pointi] = pointFaces[pointi].size();
627 const labelList& setFaces = faceSets[setI];
636 if (patchi == -1 ||
patches[patchi].coupled())
639 <<
"Can only merge non-coupled boundary faces"
640 <<
" but found internal or coupled face:"
641 << setFaces[i] <<
" in set " << setI
661 if (edgeLoops.size() != 1)
664 <<
"Faces to-be-merged " << setFaces
665 <<
" do not form a single big face." <<
nl
675 label masterFacei = setFaces[0];
678 face outsideFace(getOutsideFace(bigFace));
680 label
zoneID = mesh_.faceZones().whichZone(masterFacei);
682 bool zoneFlip =
false;
691 label patchi = mesh_.boundaryMesh().whichPatch(masterFacei);
699 mesh_.faceOwner()[masterFacei],
713 for (label i = 1; i < setFaces.size(); i++)
725 const face&
f = mesh_.faces()[setFaces[i]];
729 nPointFaces[
f[fp]]--;
735 nPointFaces[outsideFace[fp]]++;
752 forAll(nPointFaces, pointi)
754 if (nPointFaces[pointi] == 0)
764 forAll(nPointFaces, pointi)
766 if (nPointFaces[pointi] == 0)
772 savedPointLabels_.setSize(
n);
773 savedPoints_.setSize(
n);
778 forAll(nPointFaces, pointi)
780 if (nPointFaces[pointi] == 0)
784 savedPointLabels_[
n] = pointi;
785 savedPoints_[
n] = mesh_.points()[pointi];
787 meshToSaved.insert(pointi,
n);
793 forAll(faceSetsVertices_, setI)
795 faceList& setFaces = faceSetsVertices_[setI];
799 face&
f = setFaces[i];
803 label pointi =
f[fp];
805 if (nPointFaces[pointi] == 0)
807 f[fp] = -meshToSaved[pointi]-1;
825 forAll(faceSetsVertices_, setI)
827 faceList& faces = faceSetsVertices_[setI];
836 label pointi =
f[fp];
845 <<
"In set " << setI <<
" at position " << i
846 <<
" with master face "
847 << masterFace_[setI] <<
nl
848 <<
"the points of the slave face " << faces[i]
849 <<
" don't exist anymore."
876 <<
"Can only call setUnrefinement if constructed with"
882 labelList addedPoints(savedPoints_.size(), -1);
889 if (masterFace_[setI] >= 0)
891 masterToSet.insert(masterFace_[setI], setI);
897 const label masterFacei = masterFaces[i];
899 const auto iter = masterToSet.cfind(masterFacei);
904 <<
"Master face " << masterFacei
905 <<
" is not the master of one of the merge sets"
906 <<
" or has already been merged"
910 const label setI = iter.val();
916 faceList& faces = faceSetsVertices_[setI];
921 <<
"Set " << setI <<
" with master face " << masterFacei
931 label pointi =
f[fp];
935 label localI = -pointi-1;
937 if (addedPoints[localI] == -1)
944 savedPoints_[localI],
950 restoredPoints.insert
953 savedPointLabels_[localI]
957 f[fp] = addedPoints[localI];
966 label own = mesh_.faceOwner()[masterFacei];
967 label
zoneID = mesh_.faceZones().whichZone(masterFacei);
968 bool zoneFlip =
false;
974 label patchi = mesh_.boundaryMesh().whichPatch(masterFacei);
976 if (mesh_.boundaryMesh()[patchi].coupled())
979 <<
"Master face " << masterFacei <<
" is on coupled patch "
980 << mesh_.boundaryMesh()[patchi].name()
1003 restoredFaces.insert(masterFacei, masterFacei);
1006 for (label i = 1; i < faces.size(); i++)
1027 restoredFaces.insert(facei, masterFacei);
1031 faceSetsVertices_[setI].clear();
1032 masterFace_[setI] = -1;