51 bool Foam::combineFaces::convexFace
53 const scalar minConcaveCos,
59 const vector n = f.normal(points);
62 vector ePrev(points[f.first()] - points[f.last()]);
63 scalar magEPrev =
mag(ePrev);
64 ePrev /= magEPrev + vSmall;
69 label fp1 = f.fcIndex(fp0);
72 vector e10(points[f[fp1]] - points[f[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
132 Map<label>& faceRegion
135 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
139 label edgeI = cEdges[i];
144 label p0 = patches.whichPatch(f0);
145 label p1 = patches.whichPatch(f1);
150 if (p0 != -1 && p0 == p1 && !patches[p0].coupled())
152 vector f0Normal = mesh_.faceAreas()[f0];
153 f0Normal /=
mag(f0Normal);
154 vector f1Normal = mesh_.faceAreas()[
f1];
155 f1Normal /=
mag(f1Normal);
157 if ((f0Normal&f1Normal) > minCos)
162 if (f0Fnd != faceRegion.end())
170 if (f1Fnd != faceRegion.end())
179 label useRegion = faceRegion.size();
180 faceRegion.insert(f0, useRegion);
181 faceRegion.insert(f1, useRegion);
185 faceRegion.insert(f0, region1);
192 faceRegion.insert(f1, region0);
194 else if (region0 != region1)
197 label useRegion =
min(region0, region1);
198 label freeRegion =
max(region0, region1);
202 if (iter() == freeRegion)
215 bool Foam::combineFaces::faceNeighboursValid
218 const Map<label>& faceRegion
221 if (faceRegion.size() <= 1)
226 const cell& cFaces = mesh_.cells()[celli];
228 DynamicList<label> storage;
233 label facei = cFaces[cFacei];
235 if (!faceRegion.found(facei))
237 const labelList& fEdges = mesh_.faceEdges(facei, storage);
243 DynamicList<label> neighbourFaces(cFaces.size());
249 label edgeI = fEdges[i];
254 if (iter == faceRegion.end())
256 if (
findIndex(neighbourFaces, nbrI) == -1)
258 neighbourFaces.append(nbrI);
263 neighbourRegions.insert(iter());
267 if ((neighbourFaces.size()+neighbourRegions.size()) < 3)
280 Foam::combineFaces::combineFaces
289 faceSetsVertices_(0),
290 savedPointLabels_(0),
299 const scalar featureCos,
300 const scalar minConcaveCos,
312 label celli = iter.key();
314 const cell& cFaces = mesh_.cells()[celli];
316 const labelList& cEdges = mesh_.cellEdges(celli, storage);
320 regioniseFaces(featureCos, celli, cEdges, faceRegion);
328 if (faceNeighboursValid(celli, faceRegion))
335 label facei = iter.key();
336 label region = iter();
340 if (regionFnd != regionToFaces.end())
345 setFaces[sz] = facei;
349 regionToFaces.insert(region,
labelList(1, facei));
369 if (validFace(minConcaveCos, bigFace))
371 allFaceSets.append(iter());
377 return allFaceSets.shrink();
383 const scalar featureCos,
384 const scalar minConcaveCos
390 labelHashSet boundaryCells(mesh_.nFaces()-mesh_.nInternalFaces());
400 boundaryCells.
insert(mesh_.faceOwner()[patch.
start()+i]);
405 return getMergeSets(featureCos, minConcaveCos, boundaryCells);
420 <<
"Multiple outside loops:" << fp.
edgeLoops()
432 if (eFaces.
size() != 1)
435 <<
"boundary edge:" << bEdgeI
438 <<
" on indirectPrimitivePatch has " << eFaces.
size()
452 bool edgeLoopConsistent =
false;
458 if (index0 == -1 || index1 == -1)
461 <<
"Cannot find boundary edge:" << e
466 else if (index1 == outsideLoop.
fcIndex(index0))
468 edgeLoopConsistent =
true;
470 else if (index0 == outsideLoop.
fcIndex(index1))
472 edgeLoopConsistent =
false;
477 <<
"Cannot find boundary edge:" << e
480 <<
" on consecutive points in edgeLoop:" 494 bool faceEdgeConsistent =
false;
503 <<
"Cannot find boundary edge:" << e
506 <<
" in face:" << eFaces[0]
507 <<
" edges:" << fp.
faceEdges()[eFaces[0]]
510 else if (localF[index] == e[0] && localF.
nextLabel(index) == e[1])
512 faceEdgeConsistent =
true;
514 else if (localF[index] == e[1] && localF.
nextLabel(index) == e[0])
516 faceEdgeConsistent =
false;
521 <<
"Cannot find boundary edge:" << e
524 <<
" in face:" << eFaces[0] <<
" verts:" << localF
532 if (faceEdgeConsistent != edgeLoopConsistent)
548 masterFace_.setSize(faceSets.
size());
549 faceSetsVertices_.setSize(faceSets.
size());
552 const labelList& setFaces = faceSets[setI];
554 masterFace_[setI] = setFaces[0];
564 labelList nPointFaces(mesh_.nPoints(), 0);
568 forAll(pointFaces, pointi)
570 nPointFaces[pointi] = pointFaces[pointi].
size();
577 const labelList& setFaces = faceSets[setI];
586 if (patchi == -1 || patches[patchi].coupled())
589 <<
"Can only merge non-coupled boundary faces" 590 <<
" but found internal or coupled face:" 591 << setFaces[i] <<
" in set " << setI
611 if (edgeLoops.size() != 1)
614 <<
"Faces to-be-merged " << setFaces
615 <<
" do not form a single big face." <<
nl 625 label masterFacei = setFaces[0];
628 face outsideFace(getOutsideFace(bigFace));
630 label zoneID = mesh_.faceZones().whichZone(masterFacei);
632 bool zoneFlip =
false;
636 const faceZone& fZone = mesh_.faceZones()[zoneID];
641 label patchi = mesh_.boundaryMesh().whichPatch(masterFacei);
649 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];
737 meshToSaved.
insert(pointi, n);
743 forAll(faceSetsVertices_, setI)
745 faceList& setFaces = faceSetsVertices_[setI];
749 face& f = setFaces[i];
753 label pointi = f[fp];
755 if (nPointFaces[pointi] == 0)
757 f[fp] = -meshToSaved[pointi]-1;
775 forAll(faceSetsVertices_, setI)
777 faceList& faces = faceSetsVertices_[setI];
786 label pointi = f[fp];
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
881 label pointi = f[fp];
885 label localI = -pointi-1;
887 if (addedPoints[localI] == -1)
894 savedPoints_[localI],
903 savedPointLabels_[localI]
907 f[fp] = addedPoints[localI];
916 label own = mesh_.faceOwner()[masterFacei];
917 label zoneID = mesh_.faceZones().whichZone(masterFacei);
918 bool zoneFlip =
false;
921 const faceZone& fZone = mesh_.faceZones()[zoneID];
924 label patchi = mesh_.boundaryMesh().whichPatch(masterFacei);
926 if (mesh_.boundaryMesh()[
patchi].coupled())
929 <<
"Master face " << masterFacei <<
" is on coupled patch " 930 << mesh_.boundaryMesh()[
patchi].name()
953 restoredFaces.
insert(masterFacei, masterFacei);
977 restoredFaces.
insert(facei, masterFacei);
981 faceSetsVertices_[setI].clear();
982 masterFace_[setI] = -1;
ListType renumber(const labelUList &oldToNew, const ListType &)
Renumber the values (not the indices) of a list.
Class containing data for face removal.
List< labelList > labelListList
A List of labelList.
#define forAll(list, i)
Loop across all elements in list.
bool empty() const
Return true if the UList is empty (ie, size() is zero)
const labelList & reversePointMap() const
Reverse point map.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
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 inplaceRenumber(const labelUList &oldToNew, ListType &)
Inplace renumber the values of a list.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Class describing modification of a face.
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
A face is a list of labels corresponding to mesh vertices.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
void size(const label)
Override size to be inconsistent with allocated storage.
const boolList & flipMap() const
Return face flip map.
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
label nextLabel(const label i) const
Next vertex on face.
label nInternalEdges() const
Number of internal edges.
HashTable< label, label, Hash< label > >::const_iterator const_iterator
Class containing data for point addition.
label whichFace(const label globalCellID) const
Helper function to re-direct to zone::localID(...)
Vector< scalar > vector
A scalar version of the templated Vector.
PrimitivePatch< face, IndirectList, const pointField & > indirectPrimitivePatch
Foam::indirectPrimitivePatch.
bool insert(const Key &key)
Insert a new entry.
const labelListList & edgeLoops() const
Return list of closed loops of boundary vertices.
label size() const
Return number of elements in table.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
A face addition data class. A face can be inflated either from a point or from another face and can e...
const labelList & meshPoints() const
Return labelList of mesh points in patch. They are constructed.
const List< Face > & localFaces() const
Return patch faces addressing into local point list.
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
An STL-conforming iterator.
static face getOutsideFace(const indirectPrimitivePatch &)
Gets outside of patch as a face (in mesh point labels)
A list of faces which address into the list of points.
vectorField pointField
pointField is a vectorField.
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
label size() const
Return the number of elements in the list.
const labelListList & edgeFaces() const
Return edge-face addressing.
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
List< label > labelList
A List of labels.
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
errorManip< error > abort(error &err)
labelListList getMergeSets(const scalar featureCos, const scalar minConcaveCos, const labelHashSet &boundaryCells) const
Extract lists of all (non-coupled) boundary faces on selected.
void setRefinement(const labelListList &, polyTopoChange &)
Play commands into polyTopoChange to combine faces. Gets.
void reverse(UList< T > &, const label n)
defineTypeNameAndDebug(combustionModel, 0)
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
void setSize(const label)
Reset size of List.
A cell is defined as a list of faces with extra functionality.
A List with indirect addressing.
Direct mesh changes based on v1.3 polyTopoChange syntax.
label start() const
Return start label of this patch in the polyMesh face list.
const labelListList & faceEdges() const
Return face-edge addressing.
dimensioned< scalar > mag(const dimensioned< Type > &)
const doubleScalar e
Elementary charge.
Mesh consisting of general polyhedral cells.
A subset of mesh faces organised as a primitive patch.
A patch is a list of labels that address the faces in the global face list.
void updateMesh(const mapPolyMesh &)
Force recalculation of locally stored data on topological change.
A List with indirect addressing.
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
Class containing data for point removal.
const labelList & reverseFaceMap() const
Reverse face map.
label setAction(const topoAction &action)
For compatibility with polyTopoChange: set topological action.