49void Foam::meshDualiser::checkPolyTopoChange(
const polyTopoChange& meshMod)
53 forAll(meshMod.points(), i)
55 points[i] = meshMod.points()[i];
67 if (nUnique <
points.size())
69 CompactListList<label> newToOld
76 if (newToOld[newi].size() != 1)
79 <<
"duplicate verts:" << newToOld[newi]
81 << UIndirectList<point>(
points, newToOld[newi])
90void Foam::meshDualiser::dumpPolyTopoChange
99 Info<<
"Dumping current polyTopoChange. Faces to " << str1.name()
100 <<
" , points and edges to " << str2.name() <<
endl;
102 for (
const auto&
p : meshMod.points())
108 for (
const face&
f : meshMod.faces())
113 str1<<
' ' <<
f[fp]+1;
120 str2<<
' ' <<
f[fp]+1;
122 str2<<
' ' <<
f[0]+1 <<
nl;
127Foam::label Foam::meshDualiser::findDualCell
133 const labelList& dualCells = pointToDualCells_[pointi];
135 if (dualCells.size() == 1)
141 label index = mesh_.pointCells()[pointi].find(celli);
143 return dualCells[index];
148void Foam::meshDualiser::generateDualBoundaryEdges
150 const bitSet& isBoundaryEdge,
155 const labelList& pEdges = mesh_.pointEdges()[pointi];
159 label edgeI = pEdges[pEdgeI];
161 if (edgeToDualPoint_[edgeI] == -1 && isBoundaryEdge.test(edgeI))
163 const edge&
e = mesh_.edges()[edgeI];
165 edgeToDualPoint_[edgeI] = meshMod.addPoint
167 e.centre(mesh_.points()),
179bool Foam::meshDualiser::sameDualCell
185 if (!mesh_.isInternalFace(facei))
188 <<
"face:" << facei <<
" is not internal face."
192 label own = mesh_.faceOwner()[facei];
193 label nei = mesh_.faceNeighbour()[facei];
195 return findDualCell(own, pointi) == findDualCell(nei, pointi);
199Foam::label Foam::meshDualiser::addInternalFace
201 const label masterPointi,
202 const label masterEdgeI,
203 const label masterFacei,
205 const bool edgeOrder,
206 const label dualCell0,
207 const label dualCell1,
214 if (edgeOrder != (dualCell0 < dualCell1))
221 pointField facePoints(meshMod.points(), newFace);
232 if (nUnique < facePoints.size())
235 <<
"verts:" << verts <<
" newFace:" << newFace
236 <<
" face points:" << facePoints
243 bool zoneFlip =
false;
244 if (masterFacei != -1)
246 zoneID = mesh_.faceZones().whichZone(masterFacei);
250 const faceZone& fZone = mesh_.faceZones()[zoneID];
252 zoneFlip = fZone.flipMap()[fZone.whichFace(masterFacei)];
258 if (dualCell0 < dualCell1)
260 dualFacei = meshMod.addFace
287 dualFacei = meshMod.addFace
316Foam::label Foam::meshDualiser::addBoundaryFace
318 const label masterPointi,
319 const label masterEdgeI,
320 const label masterFacei,
322 const label dualCelli,
331 bool zoneFlip =
false;
332 if (masterFacei != -1)
334 zoneID = mesh_.faceZones().whichZone(masterFacei);
338 const faceZone& fZone = mesh_.faceZones()[zoneID];
340 zoneFlip = fZone.flipMap()[fZone.whichFace(masterFacei)];
344 label dualFacei = meshMod.addFace
375void Foam::meshDualiser::createFacesAroundEdge
377 const bool splitFace,
378 const bitSet& isBoundaryEdge,
380 const label startFacei,
385 const edge&
e = mesh_.edges()[edgeI];
386 const labelList& eFaces = mesh_.edgeFaces()[edgeI];
390 mesh_.faces()[startFacei],
401 isBoundaryEdge.test(edgeI)
405 bool edgeOrder = ie.sameOrder(
e[0],
e[1]);
406 label startFaceLabel = ie.faceLabel();
419 if (edgeToDualPoint_[edgeI] != -1)
421 verts.append(edgeToDualPoint_[edgeI]);
423 if (faceToDualPoint_[ie.faceLabel()] != -1)
425 doneEFaces[eFaces.find(ie.faceLabel())] =
true;
426 verts.append(faceToDualPoint_[ie.faceLabel()]);
428 if (cellToDualPoint_[ie.cellLabel()] != -1)
430 verts.append(cellToDualPoint_[ie.cellLabel()]);
433 label currentDualCell0 = findDualCell(ie.cellLabel(),
e[0]);
434 label currentDualCell1 = findDualCell(ie.cellLabel(),
e[1]);
440 label facei = ie.faceLabel();
443 doneEFaces[eFaces.find(facei)] =
true;
445 if (faceToDualPoint_[facei] != -1)
447 verts.append(faceToDualPoint_[facei]);
450 label celli = ie.cellLabel();
460 label dualCell0 = findDualCell(celli,
e[0]);
461 label dualCell1 = findDualCell(celli,
e[1]);
469 dualCell0 != currentDualCell0
470 || dualCell1 != currentDualCell1
488 currentDualCell0 = dualCell0;
489 currentDualCell1 = dualCell1;
492 if (edgeToDualPoint_[edgeI] != -1)
494 verts.append(edgeToDualPoint_[edgeI]);
496 if (faceToDualPoint_[facei] != -1)
498 verts.append(faceToDualPoint_[facei]);
502 if (cellToDualPoint_[celli] != -1)
504 verts.append(cellToDualPoint_[celli]);
513 if (!isBoundaryEdge.test(edgeI))
515 label startDual = faceToDualPoint_[startFaceLabel];
519 verts.push_uniq(startDual);
544void Foam::meshDualiser::createFaceFromInternalFace
551 const face&
f = mesh_.faces()[facei];
552 const labelList& fEdges = mesh_.faceEdges()[facei];
553 label own = mesh_.faceOwner()[facei];
554 label nei = mesh_.faceNeighbour()[facei];
567 verts.append(faceToDualPoint_[facei]);
568 verts.append(edgeToDualPoint_[fEdges[fp]]);
574 label currentDualCell0 = findDualCell(own,
f[fp]);
575 label currentDualCell1 = findDualCell(nei,
f[fp]);
580 if (pointToDualPoint_[
f[fp]] != -1)
582 verts.append(pointToDualPoint_[
f[fp]]);
586 label edgeI = fEdges[fp];
588 if (edgeToDualPoint_[edgeI] != -1)
590 verts.append(edgeToDualPoint_[edgeI]);
597 label dualCell0 = findDualCell(own,
f[nextFp]);
598 label dualCell1 = findDualCell(nei,
f[nextFp]);
600 if (dualCell0 != currentDualCell0 || dualCell1 != currentDualCell1)
603 if (edgeToDualPoint_[edgeI] == -1)
606 <<
"face:" << facei <<
" verts:" <<
f
608 <<
" no feature edge between " <<
f[fp]
609 <<
" and " <<
f[nextFp] <<
" although have different"
610 <<
" dual cells." <<
endl
611 <<
"point " <<
f[fp] <<
" has dual cells "
612 << currentDualCell0 <<
" and " << currentDualCell1
613 <<
" ; point "<<
f[nextFp] <<
" has dual cells "
614 << dualCell0 <<
" and " << dualCell1
642void Foam::meshDualiser::createFacesAroundBoundaryPoint
645 const label patchPointi,
646 const label startFacei,
654 const labelList& own = mesh_.faceOwner();
658 if (pointToDualPoint_[pointi] == -1)
664 label facei = startFacei;
670 label index =
pFaces.find(facei-
pp.start());
673 if (donePFaces[index])
677 donePFaces[index] =
true;
680 verts.append(faceToDualPoint_[facei]);
682 label dualCelli = findDualCell(own[facei], pointi);
685 const face&
f = mesh_.faces()[facei];
686 label fp =
f.
find(pointi);
688 label edgeI = mesh_.faceEdges()[facei][prevFp];
690 if (edgeToDualPoint_[edgeI] != -1)
692 verts.append(edgeToDualPoint_[edgeI]);
709 while (mesh_.isInternalFace(circ.faceLabel()));
712 facei = circ.faceLabel();
714 if (facei <
pp.start() || facei >=
pp.start()+
pp.
size())
717 <<
"Walked from face on patch:" << patchi
718 <<
" to face:" << facei
719 <<
" fc:" << mesh_.faceCentres()[facei]
725 if (dualCelli != findDualCell(own[facei], pointi))
728 <<
"Different dual cells but no feature edge"
729 <<
" inbetween point:" << pointi
730 <<
" coord:" << mesh_.points()[pointi]
737 label dualCelli = findDualCell(own[facei], pointi);
757 label facei = startFacei;
763 verts.append(pointToDualPoint_[pointi]);
766 const labelList& fEdges = mesh_.faceEdges()[facei];
767 label nextEdgeI = fEdges[mesh_.faces()[facei].find(pointi)];
768 if (edgeToDualPoint_[nextEdgeI] != -1)
770 verts.append(edgeToDualPoint_[nextEdgeI]);
775 label index =
pFaces.find(facei-
pp.start());
778 if (donePFaces[index])
782 donePFaces[index] =
true;
785 verts.append(faceToDualPoint_[facei]);
788 const labelList& fEdges = mesh_.faceEdges()[facei];
789 const face&
f = mesh_.faces()[facei];
791 label edgeI = fEdges[prevFp];
793 if (edgeToDualPoint_[edgeI] != -1)
797 verts.append(edgeToDualPoint_[edgeI]);
803 findDualCell(own[facei], pointi),
810 verts.append(pointToDualPoint_[pointi]);
811 verts.append(edgeToDualPoint_[edgeI]);
828 while (mesh_.isInternalFace(circ.faceLabel()));
831 facei = circ.faceLabel();
836 && facei >=
pp.start()
840 if (verts.size() > 2)
848 findDualCell(own[facei], pointi),
863 pointToDualCells_(mesh_.
nPoints()),
864 pointToDualPoint_(mesh_.
nPoints(), -1),
865 cellToDualPoint_(mesh_.nCells()),
866 faceToDualPoint_(mesh_.nFaces(), -1),
867 edgeToDualPoint_(mesh_.nEdges(), -1)
875 const bool splitFace,
876 const labelList& featureFaces,
877 const labelList& featureEdges,
878 const labelList& singleCellFeaturePoints,
879 const labelList& multiCellFeaturePoints,
880 polyTopoChange& meshMod
883 const labelList& own = mesh_.faceOwner();
884 const labelList& nei = mesh_.faceNeighbour();
885 const vectorField& cellCentres = mesh_.cellCentres();
890 bitSet isBoundaryEdge(mesh_.nEdges());
891 for (label facei = mesh_.nInternalFaces(); facei < mesh_.nFaces(); facei++)
893 const labelList& fEdges = mesh_.faceEdges()[facei];
895 isBoundaryEdge.
set(fEdges);
908 boolList featureFaceSet(mesh_.nFaces(),
false);
911 featureFaceSet[featureFaces[i]] =
true;
913 label facei = featureFaceSet.find(
false);
918 <<
"In split-face-mode (splitFace=true) but not all faces"
919 <<
" marked as feature faces." <<
endl
920 <<
"First conflicting face:" << facei
921 <<
" centre:" << mesh_.faceCentres()[facei]
925 boolList featureEdgeSet(mesh_.nEdges(),
false);
928 featureEdgeSet[featureEdges[i]] =
true;
930 label edgeI = featureEdgeSet.find(
false);
934 const edge&
e = mesh_.edges()[edgeI];
936 <<
"In split-face-mode (splitFace=true) but not all edges"
937 <<
" marked as feature edges." <<
endl
938 <<
"First conflicting edge:" << edgeI
940 <<
" coords:" << mesh_.points()[
e[0]] << mesh_.points()[
e[1]]
948 boolList featureFaceSet(mesh_.nFaces(),
false);
951 featureFaceSet[featureFaces[i]] =
true;
955 label facei = mesh_.nInternalFaces();
956 facei < mesh_.nFaces();
960 if (!featureFaceSet[facei])
963 <<
"Not all boundary faces marked as feature faces."
965 <<
"First conflicting face:" << facei
966 <<
" centre:" << mesh_.faceCentres()[facei]
996 autoPtr<OFstream> dualCcStr;
999 dualCcStr.reset(
new OFstream(
"dualCc.obj"));
1000 Pout<<
"Dumping centres of dual cells to " << dualCcStr().
name()
1015 forAll(singleCellFeaturePoints, i)
1017 label pointi = singleCellFeaturePoints[i];
1019 pointToDualPoint_[pointi] = meshMod.addPoint
1021 mesh_.points()[pointi],
1023 mesh_.pointZones().whichZone(pointi),
1028 pointToDualCells_[pointi].setSize(1);
1029 pointToDualCells_[pointi][0] = meshMod.addCell
1044 forAll(multiCellFeaturePoints, i)
1046 label pointi = multiCellFeaturePoints[i];
1048 if (pointToDualCells_[pointi].size() > 0)
1051 <<
"Point " << pointi <<
" at:" << mesh_.points()[pointi]
1052 <<
" is both in singleCellFeaturePoints"
1053 <<
" and multiCellFeaturePoints."
1057 pointToDualPoint_[pointi] = meshMod.addPoint
1059 mesh_.points()[pointi],
1061 mesh_.pointZones().whichZone(pointi),
1067 const labelList& pCells = mesh_.pointCells()[pointi];
1069 pointToDualCells_[pointi].
setSize(pCells.size());
1073 pointToDualCells_[pointi][pCelli] = meshMod.addCell
1079 mesh_.cellZones().whichZone(pCells[pCelli])
1086 0.5*(mesh_.points()[pointi]+cellCentres[pCells[pCelli]])
1092 forAll(mesh_.points(), pointi)
1094 if (pointToDualCells_[pointi].empty())
1096 pointToDualCells_[pointi].setSize(1);
1097 pointToDualCells_[pointi][0] = meshMod.addCell
1117 forAll(cellToDualPoint_, celli)
1119 cellToDualPoint_[celli] = meshMod.addPoint
1122 mesh_.faces()[mesh_.cells()[celli][0]][0],
1132 label facei = featureFaces[i];
1134 faceToDualPoint_[facei] = meshMod.addPoint
1136 mesh_.faceCentres()[facei],
1137 mesh_.faces()[facei][0],
1145 for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
1147 if (faceToDualPoint_[facei] == -1)
1149 const face&
f = mesh_.faces()[facei];
1153 label ownDualCell = findDualCell(own[facei],
f[fp]);
1154 label neiDualCell = findDualCell(nei[facei],
f[fp]);
1156 if (ownDualCell != neiDualCell)
1158 faceToDualPoint_[facei] = meshMod.addPoint
1160 mesh_.faceCentres()[facei],
1176 label edgeI = featureEdges[i];
1178 const edge&
e = mesh_.edges()[edgeI];
1180 edgeToDualPoint_[edgeI] = meshMod.addPoint
1182 e.centre(mesh_.points()),
1197 if (edgeToDualPoint_[edgeI] == -1)
1199 const edge&
e = mesh_.edges()[edgeI];
1204 const labelList& eCells = mesh_.edgeCells()[edgeI];
1206 label dualE0 = findDualCell(eCells[0],
e[0]);
1207 label dualE1 = findDualCell(eCells[0],
e[1]);
1209 for (label i = 1; i < eCells.size(); i++)
1211 label newDualE0 = findDualCell(eCells[i],
e[0]);
1213 if (dualE0 != newDualE0)
1215 edgeToDualPoint_[edgeI] = meshMod.addPoint
1217 e.centre(mesh_.points()),
1219 mesh_.pointZones().whichZone(
e[0]),
1226 label newDualE1 = findDualCell(eCells[i],
e[1]);
1228 if (dualE1 != newDualE1)
1230 edgeToDualPoint_[edgeI] = meshMod.addPoint
1232 e.centre(mesh_.points()),
1234 mesh_.pointZones().whichZone(
e[1]),
1246 forAll(singleCellFeaturePoints, i)
1248 generateDualBoundaryEdges
1251 singleCellFeaturePoints[i],
1255 forAll(multiCellFeaturePoints, i)
1257 generateDualBoundaryEdges
1260 multiCellFeaturePoints[i],
1269 dumpPolyTopoChange(meshMod,
"generatedPoints_");
1270 checkPolyTopoChange(meshMod);
1284 const edgeList& edges = mesh_.edges();
1288 const labelList& eFaces = mesh_.edgeFaces()[edgeI];
1290 boolList doneEFaces(eFaces.size(),
false);
1300 label startFacei = eFaces[i];
1309 createFacesAroundEdge
1324 dumpPolyTopoChange(meshMod,
"generatedFacesFromEdges_");
1333 forAll(faceToDualPoint_, facei)
1335 if (faceToDualPoint_[facei] != -1 && mesh_.isInternalFace(facei))
1337 const face&
f = mesh_.faces()[facei];
1338 const labelList& fEdges = mesh_.faceEdges()[facei];
1347 bool foundStart =
false;
1353 edgeToDualPoint_[fEdges[fp]] != -1
1354 && !sameDualCell(facei,
f.nextLabel(fp))
1370 createFaceFromInternalFace
1383 dumpPolyTopoChange(meshMod,
"generatedFacesFromFeatFaces_");
1389 const polyBoundaryMesh&
patches = mesh_.boundaryMesh();
1397 forAll(pointFaces, patchPointi)
1408 label startFacei =
pp.start()+
pFaces[i];
1417 createFacesAroundBoundaryPoint
1432 dumpPolyTopoChange(meshMod,
"generatedFacesFromBndFaces_");
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
label size() const noexcept
The number of elements in the list.
bool set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
void setSize(label n)
Alias for resize().
Output to file stream as an OSstream, normally using std::ofstream for the actual output.
virtual const fileName & name() const override
Get the name of the output serial stream. (eg, the name of the Fstream file name).
const labelList & meshPoints() const
Return labelList of mesh points in patch.
const labelListList & pointFaces() const
Return point-face addressing.
A List with indirect addressing. Like IndirectList but does not store addressing.
label rcIndex(const label i) const noexcept
The reverse circular index. The previous index in the list which returns to the last at the beginning...
label find(const T &val) const
Find index of the first occurrence of the value.
label fcIndex(const label i) const noexcept
The forward circular index. The next index in the list which returns to the first at the end of the l...
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Walks from starting face around edge.
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.
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
A subset of mesh faces organised as a primitive patch.
A face is a list of labels corresponding to mesh vertices.
A class for handling file names.
Creates dual of polyMesh. Every point becomes a cell (or multiple cells for feature points),...
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.
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh,...
label whichPatch(const label meshFacei) const
Return patch index for a given mesh face index. Uses binary search.
Mesh consisting of general polyhedral cells.
A patch is a list of labels that address the faces in the global face list.
Direct mesh changes based on v1.3 polyTopoChange syntax.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
const polyBoundaryMesh & patches
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Geometric merging of points. See below.
Namespace for handling debugging switches.
CompactListList< label > invertOneToManyCompact(const label len, const labelUList &map)
Invert one-to-many compact map. Unmapped elements will be size 0.
List< edge > edgeList
List of edge.
List< labelList > labelListList
List of labelList.
List< label > labelList
A List of labels.
void reverse(UList< T > &list, const label n)
Reverse the first n elements of the list.
messageStream Info
Information stream (stdout output on master, null elsewhere).
label mergePoints(const PointList &points, labelList &pointToUnique, labelList &uniquePoints, const scalar mergeTol=SMALL, const bool verbose=false)
Calculate merge mapping, preserving the original point order. All points closer/equal mergeTol are to...
Ostream & endl(Ostream &os)
Add newline and flush stream.
errorManip< error > abort(error &err)
Field< vector > vectorField
Specialisation of Field<T> for vector.
List< bool > boolList
A List of bools.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
vectorField pointField
pointField is a vectorField.
UList< label > labelUList
A UList of labels.
constexpr char nl
The newline '\n' character (0x0a).
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=cellModel::ref(cellModel::HEX);labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){ pointMap[i]=i;}for(label i=0;i< nPoints;i++){ if(f[i] > 0.0) { hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells].reset(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei) { if(edges[ei].mag(points)< SMALL) { label start=pointMap[edges[ei].start()];while(start !=pointMap[start]) { start=pointMap[start];} label end=pointMap[edges[ei].end()];while(end !=pointMap[end]) { end=pointMap[end];} pointMap[start]=pointMap[end]=Foam::min(start, end);} } cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){ cellShape &cs=cellShapes[celli];forAll(cs, i) { cs[i]=pointMap[cs[i]];} cs.collapse();}label bcIDs[11]={-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};constexpr label nBCs=12;const word *kivaPatchTypes[nBCs]={ &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &symmetryPolyPatch::typeName, &wedgePolyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &symmetryPolyPatch::typeName, &oldCyclicPolyPatch::typeName};enum patchTypeNames{ PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={ "piston", "valve", "liner", "cylinderHead", "axis", "wedge", "inflow", "outflow", "presin", "presout", "symmetryPlane", "cyclic"};List< DynamicList< face > > pFaces[nBCs]
#define forAll(list, i)
Loop across all elements in list.