45 void Foam::meshDualiser::checkPolyTopoChange(
const polyTopoChange& meshMod)
49 forAll(meshMod.points(), i)
51 points[i] = meshMod.points()[i];
63 if (nUnique < points.size())
69 if (newToOld[newI].size() != 1)
72 <<
"duplicate verts:" << newToOld[newI]
74 << UIndirectList<point>(
points, newToOld[newI])()
83 void Foam::meshDualiser::dumpPolyTopoChange
85 const polyTopoChange& meshMod,
86 const fileName& prefix
89 OFstream str1(prefix +
"Faces.obj");
90 OFstream str2(prefix +
"Edges.obj");
92 Info<<
"Dumping current polyTopoChange. Faces to " << str1.name()
93 <<
" , points and edges to " << str2.name() <<
endl;
95 const DynamicList<point>& points = meshMod.points();
103 const DynamicList<face>& faces = meshMod.faces();
107 const face& f = faces[facei];
112 str1<<
' ' << f[fp]+1;
119 str2<<
' ' << f[fp]+1;
121 str2<<
' ' << f[0]+1 <<
nl;
132 const labelList& dualCells = pointToDualCells_[pointi];
134 if (dualCells.size() == 1)
142 return dualCells[index];
147 void Foam::meshDualiser::generateDualBoundaryEdges
149 const PackedBoolList& isBoundaryEdge,
151 polyTopoChange& meshMod
154 const labelList& pEdges = mesh_.pointEdges()[pointi];
158 label edgeI = pEdges[pEdgeI];
160 if (edgeToDualPoint_[edgeI] == -1 && isBoundaryEdge.get(edgeI) == 1)
162 const edge& e = mesh_.edges()[edgeI];
164 edgeToDualPoint_[edgeI] = meshMod.addPoint
166 e.centre(mesh_.points()),
178 bool Foam::meshDualiser::sameDualCell
184 if (!mesh_.isInternalFace(facei))
187 <<
"face:" << facei <<
" is not internal face." 191 label own = mesh_.faceOwner()[facei];
192 label nei = mesh_.faceNeighbour()[facei];
194 return findDualCell(own, pointi) == findDualCell(nei, pointi);
200 const label masterPointi,
201 const label masterEdgeI,
202 const label masterFacei,
204 const bool edgeOrder,
205 const label dualCell0,
206 const label dualCell1,
207 const DynamicList<label>& verts,
208 polyTopoChange& meshMod
213 if (edgeOrder != (dualCell0 < dualCell1))
220 pointField facePoints(meshMod.points(), newFace);
231 if (nUnique < facePoints.size())
234 <<
"verts:" << verts <<
" newFace:" << newFace
235 <<
" face points:" << facePoints
242 bool zoneFlip =
false;
243 if (masterFacei != -1)
245 zoneID = mesh_.faceZones().whichZone(masterFacei);
249 const faceZone& fZone = mesh_.faceZones()[zoneID];
251 zoneFlip = fZone.flipMap()[fZone.whichFace(masterFacei)];
257 if (dualCell0 < dualCell1)
259 dualFacei = meshMod.addFace
286 dualFacei = meshMod.addFace
317 const label masterPointi,
318 const label masterEdgeI,
319 const label masterFacei,
321 const label dualCelli,
323 const DynamicList<label>& verts,
324 polyTopoChange& meshMod
330 bool zoneFlip =
false;
331 if (masterFacei != -1)
333 zoneID = mesh_.faceZones().whichZone(masterFacei);
337 const faceZone& fZone = mesh_.faceZones()[zoneID];
339 zoneFlip = fZone.flipMap()[fZone.whichFace(masterFacei)];
343 label dualFacei = meshMod.addFace
374 void Foam::meshDualiser::createFacesAroundEdge
376 const bool splitFace,
377 const PackedBoolList& isBoundaryEdge,
379 const label startFacei,
380 polyTopoChange& meshMod,
384 const edge& e = mesh_.edges()[edgeI];
385 const labelList& eFaces = mesh_.edgeFaces()[edgeI];
389 mesh_.faces()[startFacei],
394 edgeFaceCirculator ie
400 isBoundaryEdge.get(edgeI) == 1
404 bool edgeOrder = ie.sameOrder(e[0], e[1]);
405 label startFaceLabel = ie.faceLabel();
416 DynamicList<label> verts(100);
418 if (edgeToDualPoint_[edgeI] != -1)
420 verts.append(edgeToDualPoint_[edgeI]);
422 if (faceToDualPoint_[ie.faceLabel()] != -1)
424 doneEFaces[
findIndex(eFaces, ie.faceLabel())] =
true;
425 verts.append(faceToDualPoint_[ie.faceLabel()]);
427 if (cellToDualPoint_[ie.cellLabel()] != -1)
429 verts.append(cellToDualPoint_[ie.cellLabel()]);
432 label currentDualCell0 = findDualCell(ie.cellLabel(), e[0]);
433 label currentDualCell1 = findDualCell(ie.cellLabel(), e[1]);
439 label facei = ie.faceLabel();
442 doneEFaces[
findIndex(eFaces, facei)] =
true;
444 if (faceToDualPoint_[facei] != -1)
446 verts.append(faceToDualPoint_[facei]);
449 label celli = ie.cellLabel();
459 label dualCell0 = findDualCell(celli, e[0]);
460 label dualCell1 = findDualCell(celli, e[1]);
468 dualCell0 != currentDualCell0
469 || dualCell1 != currentDualCell1
487 currentDualCell0 = dualCell0;
488 currentDualCell1 = dualCell1;
491 if (edgeToDualPoint_[edgeI] != -1)
493 verts.append(edgeToDualPoint_[edgeI]);
495 if (faceToDualPoint_[facei] != -1)
497 verts.append(faceToDualPoint_[facei]);
501 if (cellToDualPoint_[celli] != -1)
503 verts.append(cellToDualPoint_[celli]);
512 if (isBoundaryEdge.get(edgeI) == 0)
514 label startDual = faceToDualPoint_[startFaceLabel];
516 if (startDual != -1 &&
findIndex(verts, startDual) == -1)
518 verts.append(startDual);
543 void Foam::meshDualiser::createFaceFromInternalFace
547 polyTopoChange& meshMod
550 const face& f = mesh_.faces()[facei];
551 const labelList& fEdges = mesh_.faceEdges()[facei];
552 label own = mesh_.faceOwner()[facei];
553 label nei = mesh_.faceNeighbour()[facei];
564 DynamicList<label> verts(100);
566 verts.append(faceToDualPoint_[facei]);
567 verts.append(edgeToDualPoint_[fEdges[fp]]);
573 label currentDualCell0 = findDualCell(own, f[fp]);
574 label currentDualCell1 = findDualCell(nei, f[fp]);
579 if (pointToDualPoint_[f[fp]] != -1)
581 verts.append(pointToDualPoint_[f[fp]]);
585 label edgeI = fEdges[fp];
587 if (edgeToDualPoint_[edgeI] != -1)
589 verts.append(edgeToDualPoint_[edgeI]);
593 label nextFp = f.fcIndex(fp);
596 label dualCell0 = findDualCell(own, f[nextFp]);
597 label dualCell1 = findDualCell(nei, f[nextFp]);
599 if (dualCell0 != currentDualCell0 || dualCell1 != currentDualCell1)
602 if (edgeToDualPoint_[edgeI] == -1)
605 <<
"face:" << facei <<
" verts:" << f
606 <<
" points:" << UIndirectList<point>(mesh_.points(),
f)()
607 <<
" no feature edge between " << f[fp]
608 <<
" and " << f[nextFp] <<
" although have different" 609 <<
" dual cells." <<
endl 610 <<
"point " << f[fp] <<
" has dual cells " 611 << currentDualCell0 <<
" and " << currentDualCell1
612 <<
" ; point "<< f[nextFp] <<
" has dual cells " 613 << dualCell0 <<
" and " << dualCell1
641 void Foam::meshDualiser::createFacesAroundBoundaryPoint
644 const label patchPointi,
645 const label startFacei,
646 polyTopoChange& meshMod,
650 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
651 const polyPatch& pp = patches[
patchi];
652 const labelList& pFaces = pp.pointFaces()[patchPointi];
653 const labelList& own = mesh_.faceOwner();
655 label pointi = pp.meshPoints()[patchPointi];
657 if (pointToDualPoint_[pointi] == -1)
663 label facei = startFacei;
665 DynamicList<label> verts(4);
672 if (donePFaces[index])
676 donePFaces[index] =
true;
679 verts.append(faceToDualPoint_[facei]);
681 label dualCelli = findDualCell(own[facei], pointi);
684 const face& f = mesh_.faces()[facei];
686 label prevFp = f.rcIndex(fp);
687 label edgeI = mesh_.faceEdges()[facei][prevFp];
689 if (edgeToDualPoint_[edgeI] != -1)
691 verts.append(edgeToDualPoint_[edgeI]);
695 edgeFaceCirculator circ
708 while (mesh_.isInternalFace(circ.faceLabel()));
711 facei = circ.faceLabel();
713 if (facei < pp.start() || facei >= pp.start()+pp.size())
716 <<
"Walked from face on patch:" << patchi
717 <<
" to face:" << facei
718 <<
" fc:" << mesh_.faceCentres()[facei]
719 <<
" on patch:" << patches.whichPatch(facei)
724 if (dualCelli != findDualCell(own[facei], pointi))
727 <<
"Different dual cells but no feature edge" 728 <<
" in between point:" << pointi
729 <<
" coord:" << mesh_.points()[pointi]
736 label dualCelli = findDualCell(own[facei], pointi);
756 label facei = startFacei;
759 DynamicList<label> verts(mesh_.faces()[facei].size());
762 verts.append(pointToDualPoint_[pointi]);
765 const labelList& fEdges = mesh_.faceEdges()[facei];
766 label nextEdgeI = fEdges[
findIndex(mesh_.faces()[facei], pointi)];
767 if (edgeToDualPoint_[nextEdgeI] != -1)
769 verts.append(edgeToDualPoint_[nextEdgeI]);
777 if (donePFaces[index])
781 donePFaces[index] =
true;
784 verts.append(faceToDualPoint_[facei]);
787 const labelList& fEdges = mesh_.faceEdges()[facei];
788 const face& f = mesh_.faces()[facei];
790 label edgeI = fEdges[prevFp];
792 if (edgeToDualPoint_[edgeI] != -1)
796 verts.append(edgeToDualPoint_[edgeI]);
802 findDualCell(own[facei], pointi),
809 verts.append(pointToDualPoint_[pointi]);
810 verts.append(edgeToDualPoint_[edgeI]);
814 edgeFaceCirculator circ
827 while (mesh_.isInternalFace(circ.faceLabel()));
830 facei = circ.faceLabel();
835 && facei >= pp.start()
836 && facei < pp.start()+pp.size()
839 if (verts.size() > 2)
847 findDualCell(own[facei], pointi),
862 pointToDualCells_(mesh_.
nPoints()),
863 pointToDualPoint_(mesh_.
nPoints(), -1),
864 cellToDualPoint_(mesh_.nCells()),
865 faceToDualPoint_(mesh_.nFaces(), -1),
866 edgeToDualPoint_(mesh_.nEdges(), -1)
874 const bool splitFace,
877 const labelList& singleCellFeaturePoints,
879 polyTopoChange& meshMod
882 const labelList& own = mesh_.faceOwner();
883 const labelList& nei = mesh_.faceNeighbour();
884 const vectorField& cellCentres = mesh_.cellCentres();
889 PackedBoolList isBoundaryEdge(mesh_.nEdges());
890 for (
label facei = mesh_.nInternalFaces(); facei < mesh_.nFaces(); facei++)
892 const labelList& fEdges = mesh_.faceEdges()[facei];
896 isBoundaryEdge.set(fEdges[i], 1);
910 boolList featureFaceSet(mesh_.nFaces(),
false);
913 featureFaceSet[featureFaces[i]] =
true;
920 <<
"In split-face-mode (splitFace=true) but not all faces" 921 <<
" marked as feature faces." <<
endl 922 <<
"First conflicting face:" << facei
923 <<
" centre:" << mesh_.faceCentres()[facei]
927 boolList featureEdgeSet(mesh_.nEdges(),
false);
930 featureEdgeSet[featureEdges[i]] =
true;
936 const edge& e = mesh_.edges()[edgeI];
938 <<
"In split-face-mode (splitFace=true) but not all edges" 939 <<
" marked as feature edges." <<
endl 940 <<
"First conflicting edge:" << edgeI
942 <<
" coords:" << mesh_.points()[e[0]] << mesh_.points()[e[1]]
950 boolList featureFaceSet(mesh_.nFaces(),
false);
953 featureFaceSet[featureFaces[i]] =
true;
957 label facei = mesh_.nInternalFaces();
958 facei < mesh_.nFaces();
962 if (!featureFaceSet[facei])
965 <<
"Not all boundary faces marked as feature faces." 967 <<
"First conflicting face:" << facei
968 <<
" centre:" << mesh_.faceCentres()[facei]
998 autoPtr<OFstream> dualCcStr;
1001 dualCcStr.reset(
new OFstream(
"dualCc.obj"));
1002 Pout<<
"Dumping centres of dual cells to " << dualCcStr().
name()
1017 forAll(singleCellFeaturePoints, i)
1019 label pointi = singleCellFeaturePoints[i];
1021 pointToDualPoint_[pointi] = meshMod.addPoint
1023 mesh_.points()[pointi],
1025 mesh_.pointZones().whichZone(pointi),
1030 pointToDualCells_[pointi].setSize(1);
1031 pointToDualCells_[pointi][0] = meshMod.addCell
1039 if (dualCcStr.valid())
1046 forAll(multiCellFeaturePoints, i)
1048 label pointi = multiCellFeaturePoints[i];
1050 if (pointToDualCells_[pointi].
size() > 0)
1053 <<
"Point " << pointi <<
" at:" << mesh_.points()[pointi]
1054 <<
" is both in singleCellFeaturePoints" 1055 <<
" and multiCellFeaturePoints." 1059 pointToDualPoint_[pointi] = meshMod.addPoint
1061 mesh_.points()[pointi],
1063 mesh_.pointZones().whichZone(pointi),
1069 const labelList& pCells = mesh_.pointCells()[pointi];
1071 pointToDualCells_[pointi].
setSize(pCells.size());
1075 pointToDualCells_[pointi][pCelli] = meshMod.addCell
1081 mesh_.cellZones().whichZone(pCells[pCelli])
1083 if (dualCcStr.valid())
1088 0.5*(mesh_.points()[pointi]+cellCentres[pCells[pCelli]])
1094 forAll(mesh_.points(), pointi)
1096 if (pointToDualCells_[pointi].
empty())
1098 pointToDualCells_[pointi].setSize(1);
1099 pointToDualCells_[pointi][0] = meshMod.addCell
1108 if (dualCcStr.valid())
1119 forAll(cellToDualPoint_, celli)
1121 cellToDualPoint_[celli] = meshMod.addPoint
1124 mesh_.faces()[mesh_.cells()[celli][0]][0],
1134 label facei = featureFaces[i];
1136 faceToDualPoint_[facei] = meshMod.addPoint
1138 mesh_.faceCentres()[facei],
1139 mesh_.faces()[facei][0],
1147 for (
label facei = 0; facei < mesh_.nInternalFaces(); facei++)
1149 if (faceToDualPoint_[facei] == -1)
1151 const face& f = mesh_.faces()[facei];
1155 label ownDualCell = findDualCell(own[facei], f[fp]);
1156 label neiDualCell = findDualCell(nei[facei], f[fp]);
1158 if (ownDualCell != neiDualCell)
1160 faceToDualPoint_[facei] = meshMod.addPoint
1162 mesh_.faceCentres()[facei],
1178 label edgeI = featureEdges[i];
1180 const edge& e = mesh_.edges()[edgeI];
1182 edgeToDualPoint_[edgeI] = meshMod.addPoint
1184 e.centre(mesh_.points()),
1199 if (edgeToDualPoint_[edgeI] == -1)
1201 const edge& e = mesh_.edges()[edgeI];
1206 const labelList& eCells = mesh_.edgeCells()[edgeI];
1208 label dualE0 = findDualCell(eCells[0], e[0]);
1209 label dualE1 = findDualCell(eCells[0], e[1]);
1211 for (
label i = 1; i < eCells.size(); i++)
1213 label newDualE0 = findDualCell(eCells[i], e[0]);
1215 if (dualE0 != newDualE0)
1217 edgeToDualPoint_[edgeI] = meshMod.addPoint
1219 e.centre(mesh_.points()),
1221 mesh_.pointZones().whichZone(e[0]),
1228 label newDualE1 = findDualCell(eCells[i], e[1]);
1230 if (dualE1 != newDualE1)
1232 edgeToDualPoint_[edgeI] = meshMod.addPoint
1234 e.centre(mesh_.points()),
1236 mesh_.pointZones().whichZone(e[1]),
1248 forAll(singleCellFeaturePoints, i)
1250 generateDualBoundaryEdges
1253 singleCellFeaturePoints[i],
1257 forAll(multiCellFeaturePoints, i)
1259 generateDualBoundaryEdges
1262 multiCellFeaturePoints[i],
1271 dumpPolyTopoChange(meshMod,
"generatedPoints_");
1272 checkPolyTopoChange(meshMod);
1286 const edgeList& edges = mesh_.edges();
1290 const labelList& eFaces = mesh_.edgeFaces()[edgeI];
1292 boolList doneEFaces(eFaces.size(),
false);
1302 label startFacei = eFaces[i];
1311 createFacesAroundEdge
1326 dumpPolyTopoChange(meshMod,
"generatedFacesFromEdges_");
1335 forAll(faceToDualPoint_, facei)
1337 if (faceToDualPoint_[facei] != -1 && mesh_.isInternalFace(facei))
1339 const face& f = mesh_.faces()[facei];
1340 const labelList& fEdges = mesh_.faceEdges()[facei];
1349 bool foundStart =
false;
1355 edgeToDualPoint_[fEdges[fp]] != -1
1356 && !sameDualCell(facei, f.nextLabel(fp))
1372 createFaceFromInternalFace
1385 dumpPolyTopoChange(meshMod,
"generatedFacesFromFeatFaces_");
1391 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
1395 const polyPatch& pp = patches[
patchi];
1399 forAll(pointFaces, patchPointi)
1401 const labelList& pFaces = pointFaces[patchPointi];
1403 boolList donePFaces(pFaces.size(),
false);
1410 label startFacei = pp.start()+pFaces[i];
1419 createFacesAroundBoundaryPoint
1434 dumpPolyTopoChange(meshMod,
"generatedFacesFromBndFaces_");
virtual const fileName & name() const
Return the name of the stream.
List< labelList > labelListList
A List of labelList.
void setRefinement(const bool splitFace, const labelList &featureFaces, const labelList &featureEdges, const labelList &singleCellFeaturePoints, const labelList &multiCellFeaturePoints, polyTopoChange &meshMod)
Insert all changes into meshMod to convert the polyMesh into.
#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.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
labelListList invertOneToMany(const label len, const labelUList &)
Invert one-to-many map. Unmapped elements will be size 0.
bool empty() const
Return true if the hash table is empty.
Ostream & endl(Ostream &os)
Add newline and flush stream.
static label getMinIndex(const face &f, const label v0, const label v1)
Helper: find index in face of edge or -1. Index is such that edge is.
label size() const
Return number of elements in table.
List< bool > boolList
Bool container classes.
vectorField pointField
pointField is a vectorField.
List< label > labelList
A List of labels.
errorManip< error > abort(error &err)
void reverse(UList< T > &, const label n)
meshDualiser(const polyMesh &)
Construct from mesh.
defineTypeNameAndDebug(combustionModel, 0)
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
void setSize(const label)
Reset size of List.
prefixOSstream Pout(cout, "Pout")
label mergePoints(const UList< Type > &points, const scalar mergeTol, const bool verbose, labelList &pointMap, const Type &origin=Type::zero)
Sorts and merges points. All points closer than/equal mergeTol get merged.
Field< vector > vectorField
Specialisation of Field<T> for vector.