54 const labelList& faceOwner,
55 const labelList& faceNeighbour,
56 const cellList&
cells,
69 SortableList<label> nbr(cFaces.size());
73 label facei = cFaces[i];
80 if (nbrCelli == celli)
109 oldToNew[cFaces[nbr.indices()[i]]] = newFacei++;
121 for (label facei = newFacei; facei <
faceOwner.size(); facei++)
123 oldToNew[facei] = facei;
130 if (oldToNew[facei] == -1)
133 <<
"Did not determine new position"
134 <<
" for face " << facei
148void Foam::polyDualMesh::getPointEdges
165 label edgeI = fEdges[i];
172 label index =
f.
find(pointi);
174 if (
f.nextLabel(index) ==
e[1])
183 if (e0 != -1 && e1 != -1)
188 else if (
e[1] == pointi)
191 label index =
f.
find(pointi);
193 if (
f.nextLabel(index) ==
e[0])
202 if (e0 != -1 && e1 != -1)
210 <<
" vertices:" <<
patch.localFaces()[facei]
211 <<
" that uses point:" << pointi
220 const label patchToDualOffset,
231 label meshPointi =
patch.meshPoints()[pointi];
236 if (pointToDualPoint[meshPointi] >= 0)
239 dualFace.setCapacity(
pFaces.size()+2+1);
241 dualFace.append(pointToDualPoint[meshPointi]);
245 dualFace.setCapacity(
pFaces.size()+2);
249 if (edgeToDualPoint[
patch.meshEdges()[edgeI]] < 0)
255 dualFace.
append(edgeToDualPoint[
patch.meshEdges()[edgeI]]);
257 label facei =
patch.edgeFaces()[edgeI][0];
263 getPointEdges(patch, facei, pointi, e0, e1);
277 dualFace.append(facei + patchToDualOffset);
281 getPointEdges(patch, facei, pointi, e0, e1);
292 if (edgeToDualPoint[
patch.meshEdges()[edgeI]] >= 0)
295 dualFace.append(edgeToDualPoint[
patch.meshEdges()[edgeI]]);
300 if (eFaces.size() == 1)
307 if (eFaces[0] == facei)
331void Foam::polyDualMesh::collectPatchInternalFace
334 const label patchToDualOffset,
338 const label startEdgeI,
354 label edgeI = startEdgeI;
355 label facei =
patch.edgeFaces()[edgeI][0];
361 getPointEdges(patch, facei, pointi, e0, e1);
375 dualFace.append(facei + patchToDualOffset);
379 getPointEdges(patch, facei, pointi, e0, e1);
390 if (edgeToDualPoint[meshEdges[edgeI]] >= 0)
393 dualFace.append(edgeToDualPoint[meshEdges[edgeI]]);
394 featEdgeIndices.append(dualFace.size()-1);
397 if (edgeI == startEdgeI)
405 if (eFaces[0] == facei)
415 dualFace2.transfer(dualFace);
417 featEdgeIndices2.transfer(featEdgeIndices);
424 forAll(featEdgeIndices2, i)
426 featEdgeIndices2[i] = dualFace2.size() -1 - featEdgeIndices2[i];
434void Foam::polyDualMesh::splitFace
452 label meshPointi =
patch.meshPoints()[pointi];
454 if (pointToDualPoint[meshPointi] >= 0)
458 if (featEdgeIndices.size() < 2)
461 dualFaces.append(
face(dualFace));
462 dualOwner.append(meshPointi);
463 dualNeighbour.append(-1);
464 dualRegion.append(
patch.index());
471 forAll(featEdgeIndices, i)
473 label startFp = featEdgeIndices[i];
475 label endFp = featEdgeIndices[(i+1) % featEdgeIndices.size()];
482 sz = endFp - startFp + 2;
486 sz = endFp + dualFace.size() - startFp + 2;
491 subFace[0] = pointToDualPoint[
patch.meshPoints()[pointi]];
494 for (label subFp = 1; subFp < subFace.size(); subFp++)
496 subFace[subFp] = dualFace[startFp];
498 startFp = (startFp+1) % dualFace.size();
501 dualFaces.append(
face(subFace));
502 dualOwner.append(meshPointi);
503 dualNeighbour.append(-1);
504 dualRegion.append(
patch.index());
511 if (featEdgeIndices.size() < 2)
514 dualFaces.append(
face(dualFace));
515 dualOwner.append(meshPointi);
516 dualNeighbour.append(-1);
517 dualRegion.append(
patch.index());
528 forAll(featEdgeIndices, featI)
530 label startFp = featEdgeIndices[featI];
531 label endFp = featEdgeIndices[featEdgeIndices.fcIndex(featI)];
537 label vertI = dualFace[fp];
539 subFace.append(vertI);
546 fp = dualFace.fcIndex(fp);
549 if (subFace.size() > 2)
552 dualFaces.append(
face(subFace));
553 dualOwner.append(meshPointi);
554 dualNeighbour.append(-1);
555 dualRegion.append(
patch.index());
561 if (subFace.size() > 2)
564 dualFaces.append(
face(subFace));
565 dualOwner.append(meshPointi);
566 dualNeighbour.append(-1);
567 dualRegion.append(
patch.index());
577void Foam::polyDualMesh::dualPatch
580 const label patchToDualOffset,
607 forAll(doneEdgeSide, patchEdgeI)
611 if (eFaces.size() == 1)
617 label bitMask = 1<<eI;
619 if ((doneEdgeSide[patchEdgeI] & bitMask) == 0)
624 label pointi =
e[eI];
626 label edgeI = patchEdgeI;
642 if (
patch.edges()[edgeI][0] == pointi)
644 doneEdgeSide[edgeI] |= 1;
648 doneEdgeSide[edgeI] |= 2;
651 dualFaces.append(
face(dualFace));
652 dualOwner.append(
patch.meshPoints()[pointi]);
653 dualNeighbour.append(-1);
654 dualRegion.append(
patch.index());
656 doneEdgeSide[patchEdgeI] |= bitMask;
657 donePoint.set(pointi);
670 if (!donePoint.test(pointi))
674 collectPatchInternalFace
680 patch.pointEdges()[pointi][0],
708 donePoint[pointi] =
true;
714void Foam::polyDualMesh::calcDual
731 allBoundary.meshEdges
743 meshEdges.
size() / 100
746 allBoundary.checkPointManifold(
true, &nonManifoldPoints);
748 if (nonManifoldPoints.size())
750 nonManifoldPoints.write();
753 <<
"There are " << nonManifoldPoints.size() <<
" points where"
754 <<
" the outside of the mesh is non-manifold." <<
nl
755 <<
"Such a mesh cannot be converted to a dual." <<
nl
756 <<
"Writing points at non-manifold sites to pointSet "
757 << nonManifoldPoints.name()
777 + featureEdges.size()
778 + featurePoints.size()
781 label dualPointi = 0;
787 cellPoint_.
setSize(cellCentres.size());
789 forAll(cellCentres, celli)
791 cellPoint_[celli] = dualPointi;
792 dualPoints[dualPointi++] = cellCentres[celli];
800 for (label facei = nIntFaces; facei <
mesh.
nFaces(); facei++)
802 boundaryFacePoint_[facei - nIntFaces] = dualPointi;
803 dualPoints[dualPointi++] = faceCentres[facei];
812 forAll(meshEdges, patchEdgeI)
814 label edgeI = meshEdges[patchEdgeI];
816 edgeToDualPoint[edgeI] = -1;
821 label edgeI = featureEdges[i];
825 edgeToDualPoint[edgeI] = dualPointi;
826 dualPoints[dualPointi++] =
e.centre(
mesh.
points());
844 pointToDualPoint[meshPoints[i]] = -2;
855 pointToDualPoint[meshPoints[loop[j]]] = -1;
862 label pointi = featurePoints[i];
864 pointToDualPoint[pointi] = dualPointi;
865 dualPoints[dualPointi++] =
mesh.
points()[pointi];
881 forAll(meshEdges, patchEdgeI)
883 label edgeI = meshEdges[patchEdgeI];
888 label neighbour = -1;
902 const labelList& patchFaces = allBoundary.edgeFaces()[patchEdgeI];
904 if (patchFaces.size() != 2)
907 <<
"Cannot handle edges with " << patchFaces.size()
908 <<
" connected boundary faces."
912 label face0 = patchFaces[0] + nIntFaces;
915 label face1 = patchFaces[1] + nIntFaces;
920 label startFacei = -1;
923 label index = f0.
find(neighbour);
925 if (f0.nextLabel(index) == owner)
940 if (edgeToDualPoint[edgeI] >= 0)
945 dualFace.append(edgeToDualPoint[edgeI]);
956 label facei = startFacei;
961 dualFace.append(celli);
977 if (facei == endFacei)
995 dynDualFaces.append(
face(dualFace.shrink()));
996 dynDualOwner.append(owner);
997 dynDualNeighbour.append(neighbour);
998 dynDualRegion.append(-1);
1003 const vector areaNorm =
f.areaNormal(dualPoints);
1005 if (((
mesh.
points()[owner] - dualPoints[
f[0]]) & areaNorm) > 0)
1008 <<
" on boundary edge:" << edgeI
1020 forAll(edgeToDualPoint, edgeI)
1022 if (edgeToDualPoint[edgeI] == -2)
1031 label neighbour = -1;
1047 label celli = eCells[0];
1057 label index = f0.
find(neighbour);
1059 bool f0OrderOk = (f0.nextLabel(index) == owner);
1061 label startFacei = -1;
1075 label facei = startFacei;
1080 dualFace.append(celli);
1096 if (facei == startFacei)
1111 dynDualFaces.append(
face(dualFace.shrink()));
1112 dynDualOwner.append(owner);
1113 dynDualNeighbour.append(neighbour);
1114 dynDualRegion.append(-1);
1119 const vector areaNorm =
f.areaNormal(dualPoints);
1121 if (((
mesh.
points()[owner] - dualPoints[
f[0]]) & areaNorm) > 0)
1124 <<
" on internal edge:" << edgeI
1136 dynDualFaces.shrink();
1137 dynDualOwner.shrink();
1138 dynDualNeighbour.shrink();
1139 dynDualRegion.shrink();
1141 OFstream str(
"dualInternalFaces.obj");
1142 Pout<<
"polyDualMesh::calcDual : dumping internal faces to "
1143 << str.name() <<
endl;
1145 forAll(dualPoints, dualPointi)
1149 forAll(dynDualFaces, dualFacei)
1151 const face&
f = dynDualFaces[dualFacei];
1156 str<<
' ' <<
f[fp]+1;
1162 const label nInternalFaces = dynDualFaces.size();
1190 faceList dualFaces(std::move(dynDualFaces));
1191 labelList dualOwner(std::move(dynDualOwner));
1192 labelList dualNeighbour(std::move(dynDualNeighbour));
1193 labelList dualRegion(std::move(dynDualRegion));
1200 Pout<<
"polyDualMesh::calcDual : dumping all faces to "
1201 << str.name() <<
endl;
1203 forAll(dualPoints, dualPointi)
1207 forAll(dualFaces, dualFacei)
1209 const face&
f = dualFaces[dualFacei];
1214 str<<
' ' <<
f[fp]+1;
1231 label celli = dualOwner[facei];
1235 dualCells[celli].push_back(facei);
1238 forAll(dualNeighbour, facei)
1240 label celli = dualNeighbour[facei];
1244 dualCells[celli].push_back(facei);
1278 forAll(dualRegion, facei)
1280 if (dualRegion[facei] >= 0)
1282 patchSizes[dualRegion[facei]]++;
1288 label facei = nInternalFaces;
1292 patchStarts[patchi] = facei;
1294 facei += patchSizes[patchi];
1298 Pout<<
"nFaces:" << dualFaces.size()
1299 <<
" patchSizes:" << patchSizes
1300 <<
" patchStarts:" << patchStarts
1323 addPatches(dualPatches);
1341Foam::polyDualMesh::polyDualMesh(
const IOobject&
io)
1360 "boundaryFacePoint",
1361 time().findInstance(
meshDir(),
"boundaryFacePoint"),
1372Foam::polyDualMesh::polyDualMesh
1385 time().findInstance(meshDir(),
"faces"),
1397 "boundaryFacePoint",
1398 time().findInstance(meshDir(),
"faces"),
1407 calcDual(
mesh, featureEdges, featurePoints);
1412Foam::polyDualMesh::polyDualMesh
1415 const scalar featureCos
1424 time().findInstance(meshDir(),
"faces"),
1436 "boundaryFacePoint",
1437 time().findInstance(meshDir(),
"faces"),
1449 calcDual(
mesh, featureEdges, featurePoints);
1456 const scalar featureCos,
1467 labelList allRegion(allBoundary.size());
1473 allRegion.slice(
pp.offset(),
pp.size()) = patchi;
1481 const vectorField& faceNormals = allBoundary.faceNormals();
1482 const labelList& meshPoints = allBoundary.meshPoints();
1484 bitSet isFeatureEdge(edgeFaces.size(),
false);
1488 const labelList& eFaces = edgeFaces[edgeI];
1490 if (eFaces.size() != 2)
1493 const edge&
e = allBoundary.edges()[edgeI];
1496 << meshPoints[
e[0]] <<
' ' << meshPoints[
e[1]]
1497 <<
" coords:" <<
mesh.points()[meshPoints[
e[0]]]
1498 <<
mesh.points()[meshPoints[
e[1]]]
1499 <<
" has more than 2 faces connected to it:"
1500 << eFaces.size() <<
endl;
1502 isFeatureEdge.set(edgeI);
1504 else if (allRegion[eFaces[0]] != allRegion[eFaces[1]])
1506 isFeatureEdge.set(edgeI);
1510 (faceNormals[eFaces[0]] & faceNormals[eFaces[1]])
1514 isFeatureEdge.set(edgeI);
1526 forAll(pointEdges, pointi)
1528 const labelList& pEdges = pointEdges[pointi];
1530 label nFeatEdges = 0;
1534 if (isFeatureEdge.test(pEdges[i]))
1542 allFeaturePoints.append(allBoundary.meshPoints()[pointi]);
1545 featurePoints.
transfer(allFeaturePoints);
1551 Pout<<
"polyDualMesh::calcFeatures : dumping feature points to "
1552 << str.name() <<
endl;
1556 label pointi = featurePoints[i];
1565 allBoundary.meshEdges
1579 forAll(isFeatureEdge, edgeI)
1581 if (isFeatureEdge.test(edgeI))
1584 allFeatureEdges.append(meshEdges[edgeI]);
1587 featureEdges.
transfer(allFeatureEdges);
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.
void append(const T &val)
Copy append an element to the end of this list.
label size() const noexcept
The number of elements in table.
@ NO_READ
Nothing to be read.
@ MUST_READ
Reading required.
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
@ AUTO_WRITE
Automatically write from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
void append(const T &val)
Append an element at the end of the list.
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
Read/write access to the name of the stream.
label size() const noexcept
Number of entries.
const labelListList & pointEdges() const
Return point-edge addressing.
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
labelList meshEdges(const edgeList &allEdges, const labelListList &cellEdges, const labelList &faceCells) const
Return labels of patch edges in the global edge list using cell addressing.
const labelList & meshPoints() const
Return labelList of mesh points in patch.
const Field< point_type > & faceNormals() const
Return face unit normals for patch.
const labelListList & edgeFaces() const
Return edge-face addressing.
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie,...
A non-owning sub-view of a List (allocated or unallocated storage).
SubList< T > slice(const label pos, label len=-1)
Return SubList slice (non-const access) - no range checking.
void size(const label n)
Older name for setAddressableSize.
T & last()
Access last element of the list, position [size()-1].
label find(const T &val) const
Find index of the first occurrence of the value.
label size() const noexcept
The number of entries in the list.
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
void set(const bitSet &bitset)
Set specified bits from another bitset.
bool test(const label pos) const
Test for True value at specified position, never auto-vivify entries.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
A face is a list of labels corresponding to mesh vertices.
const Time & time() const noexcept
Return time registry.
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh,...
const faceList::subList faces() const
Return mesh faces for the entire boundary.
Creates dual of polyMesh.
~polyDualMesh()
Destructor.
static void calcFeatures(const polyMesh &, const scalar featureCos, labelList &featureEdges, labelList &featurePoints)
Helper function to create feature edges and points based on.
Mesh consisting of general polyhedral cells.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
fileName meshDir() const
Return the local mesh directory (dbDir()/meshSubDir).
virtual const faceList & faces() const
Return raw faces.
virtual const labelList & faceOwner() const
Return face owner.
virtual const labelList & faceNeighbour() const
Return face neighbour.
virtual const pointField & points() const
Return raw points.
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh").
A patch is a list of labels that address the faces in the global face list.
label nBoundaryFaces() const noexcept
Number of boundary faces (== nFaces - nInternalFaces).
const labelListList & pointEdges() const
const edgeList & edges() const
Return mesh edges. Uses calcEdges.
const labelListList & cellEdges() const
const vectorField & faceCentres() const
label nInternalFaces() const noexcept
Number of internal faces.
const vectorField & cellCentres() const
label nPoints() const noexcept
Number of mesh points.
label nCells() const noexcept
Number of mesh cells.
label nFaces() const noexcept
Number of mesh faces.
const labelListList & edgeFaces() const
const labelListList & edgeCells() const
const cellList & cells() const
label nEdges() const
Number of mesh edges.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
const polyBoundaryMesh & patches
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for handling debugging switches.
const std::string patch
OpenFOAM patch number as a std::string.
PtrList< polyPatch > polyPatchList
Store lists of polyPatch as a PtrList.
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values within a list.
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.
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field.
List< face > faceList
List of faces.
Ostream & endl(Ostream &os)
Add newline and flush stream.
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
List< cell > cellList
List of cell.
errorManip< error > abort(error &err)
Field< vector > vectorField
Specialisation of Field<T> for vector.
static constexpr const zero Zero
Global zero (0).
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.
errorManipArg< error, int > exit(error &err, const int errNo=1)
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.