46 bool Foam::combineFaces::convexFace
48 const scalar minConcaveCos,
58 scalar magEPrev =
mag(ePrev);
59 ePrev /= magEPrev + vSmall;
64 label fp1 =
f.fcIndex(fp0);
68 scalar magE10 =
mag(e10);
69 e10 /= magE10 + vSmall;
71 if (magEPrev > small && magE10 > small)
73 vector edgeNormal = ePrev ^ e10;
75 if ((edgeNormal &
n) < 0)
78 if ((ePrev & e10) < minConcaveCos)
95 bool Foam::combineFaces::validFace
97 const scalar minConcaveCos,
104 if (edgeLoops.size() > 1)
109 bool isNonManifold = bigFace.checkPointManifold(
false,
nullptr);
116 face
f(getOutsideFace(bigFace));
118 return convexFace(minConcaveCos, bigFace.points(),
f);
122 void Foam::combineFaces::regioniseFaces
128 Map<label>& faceRegion
131 const polyBoundaryMesh&
patches = mesh_.boundaryMesh();
135 label edgeI = cEdges[i];
151 && patchIDs.found(p0)
154 vector f0Normal = mesh_.faceAreas()[f0];
155 f0Normal /=
mag(f0Normal);
156 vector f1Normal = mesh_.faceAreas()[f1];
157 f1Normal /=
mag(f1Normal);
159 if ((f0Normal&f1Normal) > minCos)
164 if (f0Fnd != faceRegion.end())
172 if (f1Fnd != faceRegion.end())
181 label useRegion = faceRegion.size();
182 faceRegion.insert(f0, useRegion);
183 faceRegion.insert(f1, useRegion);
187 faceRegion.insert(f0, region1);
194 faceRegion.insert(f1, region0);
196 else if (region0 != region1)
199 label useRegion =
min(region0, region1);
200 label freeRegion =
max(region0, region1);
204 if (iter() == freeRegion)
217 bool Foam::combineFaces::faceNeighboursValid
220 const Map<label>& faceRegion
223 if (faceRegion.size() <= 1)
228 const cell& cFaces = mesh_.cells()[celli];
230 DynamicList<label> storage;
235 label facei = cFaces[cFacei];
237 if (!faceRegion.found(facei))
239 const labelList& fEdges = mesh_.faceEdges(facei, storage);
245 DynamicList<label> neighbourFaces(cFaces.size());
251 label edgeI = fEdges[i];
256 if (iter == faceRegion.end())
258 if (
findIndex(neighbourFaces, nbrI) == -1)
260 neighbourFaces.append(nbrI);
265 neighbourRegions.insert(iter());
269 if ((neighbourFaces.size()+neighbourRegions.size()) < 3)
291 faceSetsVertices_(0),
292 savedPointLabels_(0),
301 const scalar featureCos,
302 const scalar minConcaveCos,
315 label celli = iter.key();
317 const cell& cFaces = mesh_.cells()[celli];
319 const labelList& cEdges = mesh_.cellEdges(celli, storage);
323 regioniseFaces(featureCos, patchIDs, celli, cEdges, faceRegion);
331 if (faceNeighboursValid(celli, faceRegion))
338 label facei = iter.key();
339 label region = iter();
343 if (regionFnd != regionToFaces.
end())
348 setFaces[sz] = facei;
372 if (validFace(minConcaveCos, bigFace))
374 allFaceSets.
append(iter());
380 return allFaceSets.
shrink();
386 const scalar featureCos,
387 const scalar minConcaveCos,
394 labelHashSet boundaryCells(mesh_.nFaces()-mesh_.nInternalFaces());
404 boundaryCells.
insert(mesh_.faceOwner()[patch.
start()+i]);
409 return getMergeSets(featureCos, minConcaveCos, patchIDs, boundaryCells);
416 const scalar featureCos,
417 const scalar minConcaveCos
422 return getMergeSets(featureCos, minConcaveCos, patchIDs);
437 <<
"Multiple outside loops:" << fp.
edgeLoops()
449 if (eFaces.
size() != 1)
452 <<
"boundary edge:" << bEdgeI
455 <<
" on indirectPrimitivePatch has " << eFaces.
size()
469 bool edgeLoopConsistent =
false;
475 if (index0 == -1 || index1 == -1)
478 <<
"Cannot find boundary edge:" <<
e
483 else if (index1 == outsideLoop.
fcIndex(index0))
485 edgeLoopConsistent =
true;
487 else if (index0 == outsideLoop.
fcIndex(index1))
489 edgeLoopConsistent =
false;
494 <<
"Cannot find boundary edge:" <<
e
497 <<
" on consecutive points in edgeLoop:"
511 bool faceEdgeConsistent =
false;
520 <<
"Cannot find boundary edge:" <<
e
523 <<
" in face:" << eFaces[0]
524 <<
" edges:" << fp.
faceEdges()[eFaces[0]]
527 else if (localF[index] ==
e[0] && localF.
nextLabel(index) ==
e[1])
529 faceEdgeConsistent =
true;
531 else if (localF[index] ==
e[1] && localF.
nextLabel(index) ==
e[0])
533 faceEdgeConsistent =
false;
538 <<
"Cannot find boundary edge:" <<
e
541 <<
" in face:" << eFaces[0] <<
" verts:" << localF
549 if (faceEdgeConsistent != edgeLoopConsistent)
565 masterFace_.setSize(
faceSets.size());
566 faceSetsVertices_.setSize(
faceSets.size());
571 masterFace_[setI] = setFaces[0];
581 labelList nPointFaces(mesh_.nPoints(), 0);
585 forAll(pointFaces, pointi)
587 nPointFaces[pointi] = pointFaces[pointi].
size();
606 <<
"Can only merge non-coupled boundary faces"
607 <<
" but found internal or coupled face:"
608 << setFaces[i] <<
" in set " << setI
628 if (edgeLoops.
size() != 1)
631 <<
"Faces to-be-merged " << setFaces
632 <<
" do not form a single big face." <<
nl
642 const label masterFacei = setFaces[0];
645 const face outsideFace(getOutsideFace(bigFace));
647 const label patchi = mesh_.boundaryMesh().whichPatch(masterFacei);
653 mesh_.faceOwner()[masterFacei],
663 for (
label i = 1; i < setFaces.
size(); i++)
675 const face&
f = mesh_.faces()[setFaces[i]];
679 nPointFaces[
f[fp]]--;
685 nPointFaces[outsideFace[fp]]++;
702 forAll(nPointFaces, pointi)
704 if (nPointFaces[pointi] == 0)
714 forAll(nPointFaces, pointi)
716 if (nPointFaces[pointi] == 0)
722 savedPointLabels_.setSize(
n);
723 savedPoints_.setSize(
n);
728 forAll(nPointFaces, pointi)
730 if (nPointFaces[pointi] == 0)
734 savedPointLabels_[
n] = pointi;
735 savedPoints_[
n] = mesh_.points()[pointi];
743 forAll(faceSetsVertices_, setI)
745 faceList& setFaces = faceSetsVertices_[setI];
749 face&
f = setFaces[i];
755 if (nPointFaces[pointi] == 0)
757 f[fp] = -meshToSaved[pointi]-1;
775 forAll(faceSetsVertices_, setI)
777 faceList& faces = faceSetsVertices_[setI];
795 <<
"In set " << setI <<
" at position " << i
796 <<
" with master face "
797 << masterFace_[setI] <<
nl
798 <<
"the points of the slave face " << faces[i]
799 <<
" don't exist anymore."
826 <<
"Can only call setUnrefinement if constructed with"
832 labelList addedPoints(savedPoints_.size(), -1);
839 if (masterFace_[setI] >= 0)
841 masterToSet.
insert(masterFace_[setI], setI);
847 label masterFacei = masterFaces[i];
851 if (iter == masterToSet.
end())
854 <<
"Master face " << masterFacei
855 <<
" is not the master of one of the merge sets"
856 <<
" or has already been merged"
866 faceList& faces = faceSetsVertices_[setI];
871 <<
"Set " << setI <<
" with master face " << masterFacei
885 label localI = -pointi-1;
887 if (addedPoints[localI] == -1)
890 addedPoints[localI] = meshMod.
addPoint
892 savedPoints_[localI],
899 savedPointLabels_[localI]
903 f[fp] = addedPoints[localI];
912 const label own = mesh_.faceOwner()[masterFacei];
913 const label patchi = mesh_.boundaryMesh().whichPatch(masterFacei);
915 if (mesh_.boundaryMesh()[
patchi].coupled())
918 <<
"Master face " << masterFacei <<
" is on coupled patch "
919 << mesh_.boundaryMesh()[
patchi].name()
936 restoredFaces.
insert(masterFacei, masterFacei);
953 restoredFaces.
insert(facei, masterFacei);
957 faceSetsVertices_[setI].clear();
958 masterFace_[setI] = -1;
#define forAll(list, i)
Loop across all elements in list.
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & shrink()
Shrink the allocated space to the number of elements used.
bool insert(const Key &key)
Insert a new entry.
label size() const
Return number of elements in table.
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
friend class const_iterator
Declare friendship with the const_iterator.
A List with indirect addressing.
void size(const label)
Override size to be inconsistent with allocated storage.
void setSize(const label)
Reset size of List.
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
label nInternalEdges() const
Number of internal edges.
const labelList & meshPoints() const
Return labelList of mesh points in patch. They are constructed.
const labelListList & edgeLoops() const
Return list of closed loops of boundary vertices.
const List< FaceType > & localFaces() const
Return patch faces addressing into local point list.
const labelListList & edgeFaces() const
Return edge-face addressing.
const labelListList & faceEdges() const
Return face-edge addressing.
A List with indirect addressing.
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
bool empty() const
Return true if the UList is empty (ie, size() is zero)
A cell is defined as a list of faces with extra functionality.
Combines boundary faces into single face. The faces get the patch of the first face ('the master')
labelListList getMergeSets(const scalar featureCos, const scalar minConcaveCos, const labelHashSet &patchIDs, const labelHashSet &boundaryCells) const
Extract lists of all (non-coupled) boundary faces on selected.
void topoChange(const polyTopoChangeMap &)
Force recalculation of locally stored data on topological change.
void setUnrefinement(const labelList &masterFaces, polyTopoChange &meshMod, Map< label > &restoredPoints, Map< label > &restoredFaces, Map< label > &restoredCells)
Play commands into polyTopoChange to reinsert original faces.
void setRefinement(const labelListList &, polyTopoChange &)
Play commands into polyTopoChange to combine faces. Gets.
combineFaces(const polyMesh &mesh, const bool undoable=false)
Construct from mesh.
static face getOutsideFace(const indirectPrimitivePatch &)
Gets outside of patch as a face (in mesh point labels)
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
A face is a list of labels corresponding to mesh vertices.
label nextLabel(const label i) const
Next vertex on face.
Mesh consisting of general polyhedral cells.
A patch is a list of labels that address the faces in the global face list.
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
label start() const
Return start label of this patch in the polyMesh face list.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
const labelList & reversePointMap() const
Reverse point map.
const labelList & reverseFaceMap() const
Reverse face map.
Direct mesh changes based on v1.3 polyTopoChange syntax.
void removePoint(const label, const label)
Remove point / merge points.
void removeFace(const label, const label)
Remove face / merge faces.
label addPoint(const point &, const label masterPointID, const bool inCell)
Add point and return new point index.
void modifyFace(const face &f, const label facei, const label own, const label nei, const bool flipFaceFlux, const label patchID)
Modify vertices or cell of face.
label addFace(const face &f, const label own, const label nei, const label masterFaceID, const bool flipFaceFlux, const label patchID)
Add face to cells and return new face index.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const fvPatchList & patches
errorManipArg< error, int > exit(error &err, const int errNo=1)
List< label > labelList
A List of labels.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
errorManip< error > abort(error &err)
ListType renumber(const labelUList &oldToNew, const ListType &)
Renumber the values (not the indices) of a list.
vectorField pointField
pointField is a vectorField.
void reverse(UList< T > &, const label n)
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
Vector< scalar > vector
A scalar version of the templated Vector.
List< labelList > labelListList
A List of labelList.
dimensioned< scalar > mag(const dimensioned< Type > &)
defineTypeNameAndDebug(combustionModel, 0)
void inplaceRenumber(const labelUList &oldToNew, ListType &)
Inplace renumber the values of a list.
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
labelList identityMap(const label len)
Create identity map (map[i] == i) of given length.
PrimitivePatch< IndirectList< face >, const pointField & > indirectPrimitivePatch
Foam::indirectPrimitivePatch.
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable