51 bool Foam::combineFaces::convexFace
53 const scalar minConcaveCos,
59 vector n = f.normal(points);
63 vector ePrev(points[f.first()] - points[f.last()]);
64 scalar magEPrev =
mag(ePrev);
65 ePrev /= magEPrev + VSMALL;
70 label fp1 = f.fcIndex(fp0);
73 vector e10(points[f[fp1]] - points[f[fp0]]);
74 scalar magE10 =
mag(e10);
75 e10 /= magE10 + VSMALL;
77 if (magEPrev > SMALL && magE10 > SMALL)
79 vector edgeNormal = ePrev ^ e10;
81 if ((edgeNormal & n) < 0)
84 if ((ePrev & e10) < minConcaveCos)
101 bool Foam::combineFaces::validFace
103 const scalar minConcaveCos,
110 if (edgeLoops.size() > 1)
115 bool isNonManifold = bigFace.checkPointManifold(
false, NULL);
122 face
f(getOutsideFace(bigFace));
124 return convexFace(minConcaveCos, bigFace.points(),
f);
128 void Foam::combineFaces::regioniseFaces
133 Map<label>& faceRegion
136 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
140 label edgeI = cEdges[i];
145 label p0 = patches.whichPatch(f0);
146 label p1 = patches.whichPatch(f1);
151 if (p0 != -1 && p0 == p1 && !patches[p0].coupled())
153 vector f0Normal = mesh_.faceAreas()[f0];
154 f0Normal /=
mag(f0Normal);
155 vector f1Normal = mesh_.faceAreas()[
f1];
156 f1Normal /=
mag(f1Normal);
158 if ((f0Normal&f1Normal) > minCos)
163 if (f0Fnd != faceRegion.end())
171 if (f1Fnd != faceRegion.end())
180 label useRegion = faceRegion.size();
181 faceRegion.insert(f0, useRegion);
182 faceRegion.insert(f1, useRegion);
186 faceRegion.insert(f0, region1);
193 faceRegion.insert(f1, region0);
195 else if (region0 != region1)
198 label useRegion =
min(region0, region1);
199 label freeRegion =
max(region0, region1);
203 if (iter() == freeRegion)
216 bool Foam::combineFaces::faceNeighboursValid
219 const Map<label>& faceRegion
222 if (faceRegion.size() <= 1)
227 const cell& cFaces = mesh_.cells()[cellI];
229 DynamicList<label> storage;
234 label faceI = cFaces[cFaceI];
236 if (!faceRegion.found(faceI))
238 const labelList& fEdges = mesh_.faceEdges(faceI, storage);
244 DynamicList<label> neighbourFaces(cFaces.size());
250 label edgeI = fEdges[i];
255 if (iter == faceRegion.end())
257 if (
findIndex(neighbourFaces, nbrI) == -1)
259 neighbourFaces.append(nbrI);
264 neighbourRegions.insert(iter());
268 if ((neighbourFaces.size()+neighbourRegions.size()) < 3)
281 Foam::combineFaces::combineFaces
290 faceSetsVertices_(0),
291 savedPointLabels_(0),
300 const scalar featureCos,
301 const scalar minConcaveCos,
313 label cellI = iter.key();
315 const cell& cFaces = mesh_.cells()[cellI];
317 const labelList& cEdges = mesh_.cellEdges(cellI, storage);
321 regioniseFaces(featureCos, cellI, cEdges, faceRegion);
329 if (faceNeighboursValid(cellI, faceRegion))
336 label faceI = iter.key();
337 label region = iter();
341 if (regionFnd != regionToFaces.end())
346 setFaces[sz] = faceI;
350 regionToFaces.insert(region,
labelList(1, faceI));
370 if (validFace(minConcaveCos, bigFace))
372 allFaceSets.append(iter());
378 return allFaceSets.shrink();
384 const scalar featureCos,
385 const scalar minConcaveCos
391 labelHashSet boundaryCells(mesh_.nFaces()-mesh_.nInternalFaces());
395 const polyPatch& patch = patches[patchI];
401 boundaryCells.
insert(mesh_.faceOwner()[patch.
start()+i]);
406 return getMergeSets(featureCos, minConcaveCos, boundaryCells);
422 "combineFaces::getOutsideFace(const indirectPrimitivePatch&)" 423 ) <<
"Multiple outside loops:" << fp.
edgeLoops()
435 if (eFaces.
size() != 1)
439 "combineFaces::getOutsideFace(const indirectPrimitivePatch&)" 440 ) <<
"boundary edge:" << bEdgeI
443 <<
" on indirectPrimitivePatch has " << eFaces.
size()
457 bool edgeLoopConsistent =
false;
463 if (index0 == -1 || index1 == -1)
467 "combineFaces::getOutsideFace" 468 "(const indirectPrimitivePatch&)" 469 ) <<
"Cannot find boundary edge:" << e
474 else if (index1 == outsideLoop.
fcIndex(index0))
476 edgeLoopConsistent =
true;
478 else if (index0 == outsideLoop.
fcIndex(index1))
480 edgeLoopConsistent =
false;
486 "combineFaces::getOutsideFace" 487 "(const indirectPrimitivePatch&)" 488 ) <<
"Cannot find boundary edge:" << e
491 <<
" on consecutive points in edgeLoop:" 505 bool faceEdgeConsistent =
false;
515 "combineFaces::getOutsideFace" 516 "(const indirectPrimitivePatch&)" 517 ) <<
"Cannot find boundary edge:" << e
520 <<
" in face:" << eFaces[0]
521 <<
" edges:" << fp.
faceEdges()[eFaces[0]]
524 else if (localF[index] == e[0] && localF.
nextLabel(index) == e[1])
526 faceEdgeConsistent =
true;
528 else if (localF[index] == e[1] && localF.
nextLabel(index) == e[0])
530 faceEdgeConsistent =
false;
536 "combineFaces::getOutsideFace" 537 "(const indirectPrimitivePatch&)" 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());
569 const labelList& setFaces = faceSets[setI];
571 masterFace_[setI] = setFaces[0];
581 labelList nPointFaces(mesh_.nPoints(), 0);
585 forAll(pointFaces, pointI)
587 nPointFaces[pointI] = pointFaces[pointI].
size();
594 const labelList& setFaces = faceSets[setI];
603 if (patchI == -1 || patches[patchI].coupled())
607 "combineFaces::setRefinement" 608 "(const bool, const labelListList&" 610 ) <<
"Can only merge non-coupled boundary faces" 611 <<
" but found internal or coupled face:" 612 << setFaces[i] <<
" in set " << setI
632 if (edgeLoops.size() != 1)
636 "combineFaces::setRefinement" 637 "(const bool, const labelListList&, polyTopoChange&)" 638 ) <<
"Faces to-be-merged " << setFaces
639 <<
" do not form a single big face." <<
nl 649 label masterFaceI = setFaces[0];
652 face outsideFace(getOutsideFace(bigFace));
654 label zoneID = mesh_.faceZones().whichZone(masterFaceI);
656 bool zoneFlip =
false;
660 const faceZone& fZone = mesh_.faceZones()[zoneID];
665 label patchI = mesh_.boundaryMesh().whichPatch(masterFaceI);
673 mesh_.faceOwner()[masterFaceI],
687 for (
label i = 1; i < setFaces.
size(); i++)
699 const face& f = mesh_.faces()[setFaces[i]];
703 nPointFaces[f[fp]]--;
709 nPointFaces[outsideFace[fp]]++;
726 forAll(nPointFaces, pointI)
728 if (nPointFaces[pointI] == 0)
738 forAll(nPointFaces, pointI)
740 if (nPointFaces[pointI] == 0)
746 savedPointLabels_.setSize(n);
747 savedPoints_.setSize(n);
752 forAll(nPointFaces, pointI)
754 if (nPointFaces[pointI] == 0)
758 savedPointLabels_[
n] = pointI;
759 savedPoints_[
n] = mesh_.points()[pointI];
761 meshToSaved.
insert(pointI, n);
767 forAll(faceSetsVertices_, setI)
769 faceList& setFaces = faceSetsVertices_[setI];
773 face& f = setFaces[i];
777 label pointI = f[fp];
779 if (nPointFaces[pointI] == 0)
781 f[fp] = -meshToSaved[pointI]-1;
799 forAll(faceSetsVertices_, setI)
801 faceList& faces = faceSetsVertices_[setI];
810 label pointI = f[fp];
820 "combineFaces::updateMesh" 821 "(const mapPolyMesh&)" 822 ) <<
"In set " << setI <<
" at position " << i
823 <<
" with master face " 824 << masterFace_[setI] <<
nl 825 <<
"the points of the slave face " << faces[i]
826 <<
" don't exist anymore." 854 "combineFaces::setUnrefinement" 855 "(const labelList&, polyTopoChange&" 856 ", Map<label>&, Map<label>&, Map<label>&)" 857 ) <<
"Can only call setUnrefinement if constructed with" 863 labelList addedPoints(savedPoints_.size(), -1);
870 if (masterFace_[setI] >= 0)
872 masterToSet.insert(masterFace_[setI], setI);
878 label masterFaceI = masterFaces[i];
882 if (iter == masterToSet.
end())
886 "combineFaces::setUnrefinement" 887 "(const labelList&, polyTopoChange&" 888 ", Map<label>&, Map<label>&, Map<label>&)" 889 ) <<
"Master face " << masterFaceI
890 <<
" is not the master of one of the merge sets" 891 <<
" or has already been merged" 901 faceList& faces = faceSetsVertices_[setI];
907 "combineFaces::setUnrefinement" 908 "(const labelList&, polyTopoChange&" 909 ", Map<label>&, Map<label>&, Map<label>&)" 910 ) <<
"Set " << setI <<
" with master face " << masterFaceI
920 label pointI = f[fp];
924 label localI = -pointI-1;
926 if (addedPoints[localI] == -1)
933 savedPoints_[localI],
942 savedPointLabels_[localI]
946 f[fp] = addedPoints[localI];
955 label own = mesh_.faceOwner()[masterFaceI];
956 label zoneID = mesh_.faceZones().whichZone(masterFaceI);
957 bool zoneFlip =
false;
960 const faceZone& fZone = mesh_.faceZones()[zoneID];
963 label patchI = mesh_.boundaryMesh().whichPatch(masterFaceI);
965 if (mesh_.boundaryMesh()[patchI].coupled())
969 "combineFaces::setUnrefinement" 970 "(const labelList&, polyTopoChange&" 971 ", Map<label>&, Map<label>&, Map<label>&)" 972 ) <<
"Master face " << masterFaceI <<
" is on coupled patch " 973 << mesh_.boundaryMesh()[patchI].name()
996 restoredFaces.
insert(masterFaceI, masterFaceI);
1020 restoredFaces.
insert(faceI, masterFaceI);
1024 faceSetsVertices_[setI].clear();
1025 masterFace_[setI] = -1;
A List with indirect addressing.
const boolList & flipMap() const
Return face flip map.
label setAction(const topoAction &action)
For compatibility with polyTopoChange: set topological action.
A face addition data class. A face can be inflated either from a point or from another face and can e...
const labelList & reverseFaceMap() const
Reverse face map.
void setUnrefinement(const labelList &masterFaces, polyTopoChange &meshMod, Map< label > &restoredPoints, Map< label > &restoredFaces, Map< label > &restoredCells)
Play commands into polyTopoChange to reinsert original faces.
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
dimensioned< scalar > mag(const dimensioned< Type > &)
A cell is defined as a list of faces with extra functionality.
const labelListList & edgeFaces() const
Return edge-face addressing.
Class containing data for point removal.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
bool empty() const
Return true if the UList is empty (ie, size() is zero).
const labelList & reversePointMap() const
Reverse point map.
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
An STL-conforming iterator.
void getEdgeFaces(const primitiveMesh &, const label cellI, const label edgeI, label &face0, label &face1)
Get faces on cell using edgeI. Throws error if no two found.
A subset of mesh faces organised as a primitive patch.
#define forAllIter(Container, container, iter)
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 size(const label)
Override size to be inconsistent with allocated storage.
errorManipArg< error, int > exit(error &err, const int errNo=1)
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
PrimitivePatch< face, IndirectList, const pointField & > indirectPrimitivePatch
Foam::indirectPrimitivePatch.
label nextLabel(const label i) const
Next vertex on face.
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
vectorField pointField
pointField is a vectorField.
Class containing data for face removal.
A patch is a list of labels that address the faces in the global face list.
label whichFace(const label globalCellID) const
Helper function to re-direct to zone::localID(...)
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
A face is a list of labels corresponding to mesh vertices.
const double e
Elementary charge.
void setSize(const label)
Reset size of List.
void setRefinement(const labelListList &, polyTopoChange &)
Play commands into polyTopoChange to combine faces. Gets.
A List with indirect addressing.
label size() const
Return the number of elements in the list.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
const labelList & meshPoints() const
Return labelList of mesh points in patch. They are constructed.
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
ListType renumber(const labelUList &oldToNew, const ListType &)
Renumber the values (not the indices) of a list.
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
Class describing modification of a face.
label size() const
Return number of elements in table.
errorManip< error > abort(error &err)
label otherFace(const primitiveMesh &, const label cellI, const label faceI, const label edgeI)
Return face on cell using edgeI but not faceI. Throws error.
static void syncPointList(const polyMesh &, List< T > &, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronize values on all mesh points.
const labelListList & edgeLoops() const
Return list of closed loops of boundary vertices.
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
A list of faces which address into the list of points.
label start() const
Return start label of this patch in the polyMesh face list.
Mesh consisting of general polyhedral cells.
label nInternalEdges() const
Number of internal edges.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
List< label > labelList
A List of labels.
const labelListList & faceEdges() const
Return face-edge addressing.
Vector< scalar > vector
A scalar version of the templated Vector.
void reverse(UList< T > &, const label n)
void updateMesh(const mapPolyMesh &)
Force recalculation of locally stored data on topological change.
Direct mesh changes based on v1.3 polyTopoChange syntax.
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
const List< Face > & localFaces() const
Return patch faces addressing into local point list.
Class containing data for point addition.
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
List< labelList > labelListList
A List of labelList.
HashTable< label, label, Hash< label > >::const_iterator const_iterator
static face getOutsideFace(const indirectPrimitivePatch &)
Gets outside of patch as a face (in mesh point labels)
void inplaceRenumber(const labelUList &oldToNew, ListType &)
Inplace renumber the values of a list.
defineTypeNameAndDebug(combustionModel, 0)
labelListList getMergeSets(const scalar featureCos, const scalar minConcaveCos, const labelHashSet &boundaryCells) const
Extract lists of all (non-coupled) boundary faces on selected.
bool insert(const Key &key)
Insert a new entry.