51 bool Foam::combineFaces::convexFace
53 const scalar minConcaveCos,
63 scalar magEPrev =
mag(ePrev);
64 ePrev /= magEPrev + vSmall;
69 label fp1 =
f.fcIndex(fp0);
73 scalar magE10 =
mag(e10);
74 e10 /= magE10 + vSmall;
76 if (magEPrev > small && magE10 > small)
78 vector edgeNormal = ePrev ^ e10;
80 if ((edgeNormal &
n) < 0)
83 if ((ePrev & e10) < minConcaveCos)
100 bool Foam::combineFaces::validFace
102 const scalar minConcaveCos,
109 if (edgeLoops.size() > 1)
114 bool isNonManifold = bigFace.checkPointManifold(
false,
nullptr);
121 face
f(getOutsideFace(bigFace));
123 return convexFace(minConcaveCos, bigFace.points(),
f);
127 void Foam::combineFaces::regioniseFaces
133 Map<label>& faceRegion
136 const polyBoundaryMesh&
patches = mesh_.boundaryMesh();
140 label edgeI = cEdges[i];
156 && patchIDs.found(p0)
159 vector f0Normal = mesh_.faceAreas()[f0];
160 f0Normal /=
mag(f0Normal);
161 vector f1Normal = mesh_.faceAreas()[f1];
162 f1Normal /=
mag(f1Normal);
164 if ((f0Normal&f1Normal) > minCos)
169 if (f0Fnd != faceRegion.end())
177 if (f1Fnd != faceRegion.end())
186 label useRegion = faceRegion.size();
187 faceRegion.insert(f0, useRegion);
188 faceRegion.insert(f1, useRegion);
192 faceRegion.insert(f0, region1);
199 faceRegion.insert(f1, region0);
201 else if (region0 != region1)
204 label useRegion =
min(region0, region1);
205 label freeRegion =
max(region0, region1);
209 if (iter() == freeRegion)
222 bool Foam::combineFaces::faceNeighboursValid
225 const Map<label>& faceRegion
228 if (faceRegion.size() <= 1)
233 const cell& cFaces = mesh_.cells()[celli];
235 DynamicList<label> storage;
240 label facei = cFaces[cFacei];
242 if (!faceRegion.found(facei))
244 const labelList& fEdges = mesh_.faceEdges(facei, storage);
250 DynamicList<label> neighbourFaces(cFaces.size());
256 label edgeI = fEdges[i];
261 if (iter == faceRegion.end())
263 if (
findIndex(neighbourFaces, nbrI) == -1)
265 neighbourFaces.append(nbrI);
270 neighbourRegions.insert(iter());
274 if ((neighbourFaces.size()+neighbourRegions.size()) < 3)
296 faceSetsVertices_(0),
297 savedPointLabels_(0),
306 const scalar featureCos,
307 const scalar minConcaveCos,
320 label celli = iter.key();
322 const cell& cFaces = mesh_.cells()[celli];
324 const labelList& cEdges = mesh_.cellEdges(celli, storage);
328 regioniseFaces(featureCos, patchIDs, celli, cEdges, faceRegion);
336 if (faceNeighboursValid(celli, faceRegion))
343 label facei = iter.key();
344 label region = iter();
348 if (regionFnd != regionToFaces.
end())
353 setFaces[sz] = facei;
377 if (validFace(minConcaveCos, bigFace))
379 allFaceSets.
append(iter());
385 return allFaceSets.
shrink();
391 const scalar featureCos,
392 const scalar minConcaveCos,
399 labelHashSet boundaryCells(mesh_.nFaces()-mesh_.nInternalFaces());
409 boundaryCells.
insert(mesh_.faceOwner()[patch.
start()+i]);
414 return getMergeSets(featureCos, minConcaveCos, patchIDs, boundaryCells);
421 const scalar featureCos,
422 const scalar minConcaveCos
427 return getMergeSets(featureCos, minConcaveCos, patchIDs);
442 <<
"Multiple outside loops:" << fp.
edgeLoops()
454 if (eFaces.
size() != 1)
457 <<
"boundary edge:" << bEdgeI
460 <<
" on indirectPrimitivePatch has " << eFaces.
size()
474 bool edgeLoopConsistent =
false;
480 if (index0 == -1 || index1 == -1)
483 <<
"Cannot find boundary edge:" <<
e
488 else if (index1 == outsideLoop.
fcIndex(index0))
490 edgeLoopConsistent =
true;
492 else if (index0 == outsideLoop.
fcIndex(index1))
494 edgeLoopConsistent =
false;
499 <<
"Cannot find boundary edge:" <<
e
502 <<
" on consecutive points in edgeLoop:"
516 bool faceEdgeConsistent =
false;
525 <<
"Cannot find boundary edge:" <<
e
528 <<
" in face:" << eFaces[0]
529 <<
" edges:" << fp.
faceEdges()[eFaces[0]]
532 else if (localF[index] ==
e[0] && localF.
nextLabel(index) ==
e[1])
534 faceEdgeConsistent =
true;
536 else if (localF[index] ==
e[1] && localF.
nextLabel(index) ==
e[0])
538 faceEdgeConsistent =
false;
543 <<
"Cannot find boundary edge:" <<
e
546 <<
" in face:" << eFaces[0] <<
" verts:" << localF
554 if (faceEdgeConsistent != edgeLoopConsistent)
570 masterFace_.setSize(
faceSets.size());
571 faceSetsVertices_.setSize(
faceSets.size());
576 masterFace_[setI] = setFaces[0];
586 labelList nPointFaces(mesh_.nPoints(), 0);
590 forAll(pointFaces, pointi)
592 nPointFaces[pointi] = pointFaces[pointi].
size();
611 <<
"Can only merge non-coupled boundary faces"
612 <<
" but found internal or coupled face:"
613 << setFaces[i] <<
" in set " << setI
633 if (edgeLoops.
size() != 1)
636 <<
"Faces to-be-merged " << setFaces
637 <<
" do not form a single big face." <<
nl
647 label masterFacei = setFaces[0];
650 face outsideFace(getOutsideFace(bigFace));
652 label zoneID = mesh_.faceZones().whichZone(masterFacei);
654 bool zoneFlip =
false;
658 const faceZone& fZone = mesh_.faceZones()[zoneID];
663 label patchi = mesh_.boundaryMesh().whichPatch(masterFacei);
671 mesh_.faceOwner()[masterFacei],
685 for (
label i = 1; i < setFaces.
size(); i++)
697 const face&
f = mesh_.faces()[setFaces[i]];
701 nPointFaces[
f[fp]]--;
707 nPointFaces[outsideFace[fp]]++;
724 forAll(nPointFaces, pointi)
726 if (nPointFaces[pointi] == 0)
736 forAll(nPointFaces, pointi)
738 if (nPointFaces[pointi] == 0)
744 savedPointLabels_.setSize(
n);
745 savedPoints_.setSize(
n);
750 forAll(nPointFaces, pointi)
752 if (nPointFaces[pointi] == 0)
756 savedPointLabels_[
n] = pointi;
757 savedPoints_[
n] = mesh_.points()[pointi];
765 forAll(faceSetsVertices_, setI)
767 faceList& setFaces = faceSetsVertices_[setI];
771 face&
f = setFaces[i];
777 if (nPointFaces[pointi] == 0)
779 f[fp] = -meshToSaved[pointi]-1;
797 forAll(faceSetsVertices_, setI)
799 faceList& faces = faceSetsVertices_[setI];
817 <<
"In set " << setI <<
" at position " << i
818 <<
" with master face "
819 << masterFace_[setI] <<
nl
820 <<
"the points of the slave face " << faces[i]
821 <<
" don't exist anymore."
848 <<
"Can only call setUnrefinement if constructed with"
854 labelList addedPoints(savedPoints_.size(), -1);
861 if (masterFace_[setI] >= 0)
863 masterToSet.
insert(masterFace_[setI], setI);
869 label masterFacei = masterFaces[i];
873 if (iter == masterToSet.
end())
876 <<
"Master face " << masterFacei
877 <<
" is not the master of one of the merge sets"
878 <<
" or has already been merged"
888 faceList& faces = faceSetsVertices_[setI];
893 <<
"Set " << setI <<
" with master face " << masterFacei
907 label localI = -pointi-1;
909 if (addedPoints[localI] == -1)
916 savedPoints_[localI],
925 savedPointLabels_[localI]
929 f[fp] = addedPoints[localI];
938 label own = mesh_.faceOwner()[masterFacei];
939 label zoneID = mesh_.faceZones().whichZone(masterFacei);
940 bool zoneFlip =
false;
943 const faceZone& fZone = mesh_.faceZones()[zoneID];
946 label patchi = mesh_.boundaryMesh().whichPatch(masterFacei);
948 if (mesh_.boundaryMesh()[
patchi].coupled())
951 <<
"Master face " << masterFacei <<
" is on coupled patch "
952 << mesh_.boundaryMesh()[
patchi].name()
975 restoredFaces.
insert(masterFacei, masterFacei);
999 restoredFaces.
insert(facei, masterFacei);
1003 faceSetsVertices_[setI].clear();
1004 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.
An STL-conforming iterator.
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.
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.
HashTable< label, label, Hash< label > >::const_iterator const_iterator
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 subset of mesh faces organised as a primitive patch.
const boolList & flipMap() const
Return face flip map.
label whichFace(const label globalCellID) const
Helper function to re-direct to zone::localID(...)
A face is a list of labels corresponding to mesh vertices.
label nextLabel(const label i) const
Next vertex on face.
A face addition data class. A face can be inflated either from a point or from another face and can e...
Class containing data for point addition.
Mesh consisting of general polyhedral cells.
Class describing modification of a face.
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 data for face removal.
Class containing data for point removal.
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.
label setAction(const topoAction &action)
For compatibility with polyTopoChange: set topological action.
#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