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());
401 boundaryCells.
insert(mesh_.faceOwner()[patch.
start()+i]);
406 return getMergeSets(featureCos, minConcaveCos, boundaryCells);
421 <<
"Multiple outside loops:" << fp.
edgeLoops()
433 if (eFaces.
size() != 1)
436 <<
"boundary edge:" << bEdgeI
439 <<
" on indirectPrimitivePatch has " << eFaces.
size()
453 bool edgeLoopConsistent =
false;
459 if (index0 == -1 || index1 == -1)
462 <<
"Cannot find boundary edge:" << e
467 else if (index1 == outsideLoop.
fcIndex(index0))
469 edgeLoopConsistent =
true;
471 else if (index0 == outsideLoop.
fcIndex(index1))
473 edgeLoopConsistent =
false;
478 <<
"Cannot find boundary edge:" << e
481 <<
" on consecutive points in edgeLoop:" 495 bool faceEdgeConsistent =
false;
504 <<
"Cannot find boundary edge:" << e
507 <<
" in face:" << eFaces[0]
508 <<
" edges:" << fp.
faceEdges()[eFaces[0]]
511 else if (localF[index] == e[0] && localF.
nextLabel(index) == e[1])
513 faceEdgeConsistent =
true;
515 else if (localF[index] == e[1] && localF.
nextLabel(index) == e[0])
517 faceEdgeConsistent =
false;
522 <<
"Cannot find boundary edge:" << e
525 <<
" in face:" << eFaces[0] <<
" verts:" << localF
533 if (faceEdgeConsistent != edgeLoopConsistent)
549 masterFace_.setSize(faceSets.
size());
550 faceSetsVertices_.setSize(faceSets.
size());
553 const labelList& setFaces = faceSets[setI];
555 masterFace_[setI] = setFaces[0];
565 labelList nPointFaces(mesh_.nPoints(), 0);
569 forAll(pointFaces, pointi)
571 nPointFaces[pointi] = pointFaces[pointi].
size();
578 const labelList& setFaces = faceSets[setI];
587 if (patchi == -1 || patches[patchi].coupled())
590 <<
"Can only merge non-coupled boundary faces" 591 <<
" but found internal or coupled face:" 592 << setFaces[i] <<
" in set " << setI
612 if (edgeLoops.size() != 1)
615 <<
"Faces to-be-merged " << setFaces
616 <<
" do not form a single big face." <<
nl 626 label masterFacei = setFaces[0];
629 face outsideFace(getOutsideFace(bigFace));
631 label zoneID = mesh_.faceZones().whichZone(masterFacei);
633 bool zoneFlip =
false;
637 const faceZone& fZone = mesh_.faceZones()[zoneID];
642 label patchi = mesh_.boundaryMesh().whichPatch(masterFacei);
650 mesh_.faceOwner()[masterFacei],
664 for (
label i = 1; i < setFaces.
size(); i++)
676 const face& f = mesh_.faces()[setFaces[i]];
680 nPointFaces[f[fp]]--;
686 nPointFaces[outsideFace[fp]]++;
703 forAll(nPointFaces, pointi)
705 if (nPointFaces[pointi] == 0)
715 forAll(nPointFaces, pointi)
717 if (nPointFaces[pointi] == 0)
723 savedPointLabels_.setSize(n);
724 savedPoints_.setSize(n);
729 forAll(nPointFaces, pointi)
731 if (nPointFaces[pointi] == 0)
735 savedPointLabels_[
n] = pointi;
736 savedPoints_[
n] = mesh_.points()[pointi];
738 meshToSaved.
insert(pointi, n);
744 forAll(faceSetsVertices_, setI)
746 faceList& setFaces = faceSetsVertices_[setI];
750 face& f = setFaces[i];
754 label pointi = f[fp];
756 if (nPointFaces[pointi] == 0)
758 f[fp] = -meshToSaved[pointi]-1;
776 forAll(faceSetsVertices_, setI)
778 faceList& faces = faceSetsVertices_[setI];
787 label pointi = f[fp];
796 <<
"In set " << setI <<
" at position " << i
797 <<
" with master face " 798 << masterFace_[setI] <<
nl 799 <<
"the points of the slave face " << faces[i]
800 <<
" don't exist anymore." 827 <<
"Can only call setUnrefinement if constructed with" 833 labelList addedPoints(savedPoints_.size(), -1);
840 if (masterFace_[setI] >= 0)
842 masterToSet.insert(masterFace_[setI], setI);
848 label masterFacei = masterFaces[i];
852 if (iter == masterToSet.
end())
855 <<
"Master face " << masterFacei
856 <<
" is not the master of one of the merge sets" 857 <<
" or has already been merged" 867 faceList& faces = faceSetsVertices_[setI];
872 <<
"Set " << setI <<
" with master face " << masterFacei
882 label pointi = f[fp];
886 label localI = -pointi-1;
888 if (addedPoints[localI] == -1)
895 savedPoints_[localI],
904 savedPointLabels_[localI]
908 f[fp] = addedPoints[localI];
917 label own = mesh_.faceOwner()[masterFacei];
918 label zoneID = mesh_.faceZones().whichZone(masterFacei);
919 bool zoneFlip =
false;
922 const faceZone& fZone = mesh_.faceZones()[zoneID];
925 label patchi = mesh_.boundaryMesh().whichPatch(masterFacei);
927 if (mesh_.boundaryMesh()[
patchi].coupled())
930 <<
"Master face " << masterFacei <<
" is on coupled patch " 931 << mesh_.boundaryMesh()[
patchi].name()
954 restoredFaces.
insert(masterFacei, masterFacei);
978 restoredFaces.
insert(facei, masterFacei);
982 faceSetsVertices_[setI].clear();
983 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.
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)
const boolList & flipMap() const
Return face flip map.
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.
const double e
Elementary charge.
const labelList & meshPoints() const
Return labelList of mesh points in patch. They are constructed.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
bool empty() const
Return true if the UList is empty (ie, size() is zero)
const List< Face > & localFaces() const
Return patch faces addressing into local point list.
#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.
HashTable< label, label, Hash< label > >::const_iterator const_iterator
Class containing data for point addition.
label size() const
Return number of elements in table.
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.
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...
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
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.
label whichFace(const label globalCellID) const
Helper function to re-direct to zone::localID(...)
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.
label start() const
Return start label of this patch in the polyMesh face list.
const labelList & reverseFaceMap() const
Reverse face map.
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...
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
const labelListList & faceEdges() const
Return face-edge addressing.
label size() const
Return the number of elements in the list.
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)
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 occurence 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.
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
label nInternalEdges() const
Number of internal edges.
A List with indirect addressing.
Direct mesh changes based on v1.3 polyTopoChange syntax.
labelListList getMergeSets(const scalar featureCos, const scalar minConcaveCos, const labelHashSet &boundaryCells) const
Extract lists of all (non-coupled) boundary faces on selected.
dimensioned< scalar > mag(const dimensioned< Type > &)
const labelListList & edgeFaces() const
Return edge-face addressing.
label nextLabel(const label i) const
Next vertex on face.
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.
Class containing data for point removal.
const labelListList & edgeLoops() const
Return list of closed loops of boundary vertices.
const labelList & reversePointMap() const
Reverse point map.
label setAction(const topoAction &action)
For compatibility with polyTopoChange: set topological action.