41 void Foam::conformalVoronoiMesh::calcDualMesh
53 bitSet& boundaryFacesToRemove
58 setVertexSizeAndAlignment();
60 timeCheck(
"After setVertexSizeAndAlignment");
62 indexDualVertices(
points, boundaryPts);
65 Info<<
nl <<
"Merging identical points" <<
endl;
68 mergeIdenticalDualVertices(
points, boundaryPts);
73 timeCheck(
"Before createFacesOwnerNeighbourAndPatches");
75 createFacesOwnerNeighbourAndPatches
83 patchToDelaunayVertex,
84 boundaryFacesToRemove,
92 cellToDelaunayVertex = removeUnusedCells(owner, neighbour);
94 cellCentres =
pointField(cellCentres, cellToDelaunayVertex);
96 removeUnusedPoints(faces,
points, boundaryPts);
102 void Foam::conformalVoronoiMesh::calcTetMesh
113 labelList vertexMap(number_of_vertices());
118 pointToDelaunayVertex.setSize(number_of_vertices());
122 Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
123 vit != finite_vertices_end();
127 if (vit->internalPoint() || vit->boundaryPoint())
129 vertexMap[vit->index()] = vertI;
131 pointToDelaunayVertex[vertI] = vit->index();
137 pointToDelaunayVertex.setSize(vertI);
143 Delaunay::Finite_cells_iterator cit = finite_cells_begin();
144 cit != finite_cells_end();
148 if (cit->internalOrBoundaryDualVertex())
150 cit->cellIndex() = celli++;
158 patchNames = geometryToConformTo_.patchNames();
166 List<DynamicList<face>> patchFaces(
nPatches);
167 List<DynamicList<label>> patchOwners(
nPatches);
169 faces.setSize(number_of_finite_facets());
171 owner.setSize(number_of_finite_facets());
173 neighbour.setSize(number_of_finite_facets());
177 labelList verticesOnTriFace(3, label(-1));
179 face newFace(verticesOnTriFace);
183 Delaunay::Finite_facets_iterator fit = finite_facets_begin();
184 fit != finite_facets_end();
188 const Cell_handle
c1(fit->first);
189 const label oppositeVertex = fit->second;
190 const Cell_handle
c2(
c1->neighbor(oppositeVertex));
192 if (
c1->hasFarPoint() &&
c2->hasFarPoint())
198 label c1I =
c1->cellIndex();
199 label c2I =
c2->cellIndex();
201 label ownerCell = -1;
202 label neighbourCell = -1;
204 for (label i = 0; i < 3; i++)
206 verticesOnTriFace[i] = vertexMap
208 c1->vertex(vertex_triple_index(oppositeVertex, i))->index()
212 newFace = face(verticesOnTriFace);
214 if (
c1->hasFarPoint() ||
c2->hasFarPoint())
217 if (
c1->hasFarPoint())
230 label patchIndex = geometryToConformTo_.findPatch
235 if (patchIndex == -1)
241 <<
"did not find a surface patch. Adding to " 246 patchFaces[patchIndex].append(newFace);
247 patchOwners[patchIndex].append(ownerCell);
267 faces[facei] = newFace;
268 owner[facei] = ownerCell;
269 neighbour[facei] = neighbourCell;
274 label nInternalFaces = facei;
276 faces.setSize(nInternalFaces);
277 owner.setSize(nInternalFaces);
278 neighbour.setSize(nInternalFaces);
280 sortFaces(faces, owner, neighbour);
299 void Foam::conformalVoronoiMesh::mergeIdenticalDualVertices
307 label nPtsMerged = 0;
308 label nPtsMergedSum = 0;
312 Map<label> dualPtIndexMap;
314 nPtsMerged = mergeIdenticalDualVertices
320 reindexDualVertices(dualPtIndexMap, boundaryPts);
322 reduce(nPtsMerged, sumOp<label>());
324 nPtsMergedSum += nPtsMerged;
326 }
while (nPtsMerged > 0);
328 if (nPtsMergedSum > 0)
330 Info<<
" Merged " << nPtsMergedSum <<
" points " <<
endl;
335 Foam::label Foam::conformalVoronoiMesh::mergeIdenticalDualVertices
338 Map<label>& dualPtIndexMap
341 label nPtsMerged = 0;
345 Delaunay::Finite_facets_iterator fit = finite_facets_begin();
346 fit != finite_facets_end();
350 const Cell_handle
c1(fit->first);
351 const label oppositeVertex = fit->second;
352 const Cell_handle
c2(
c1->neighbor(oppositeVertex));
354 if (is_infinite(
c1) || is_infinite(
c2))
359 label& c1I =
c1->cellIndex();
360 label& c2I =
c2->cellIndex();
362 if ((c1I != c2I) && !
c1->hasFarPoint() && !
c2->hasFarPoint())
384 dualPtIndexMap.insert(c1I, c1I);
385 dualPtIndexMap.insert(c2I, c1I);
389 dualPtIndexMap.insert(c1I, c2I);
390 dualPtIndexMap.insert(c2I, c2I);
400 Info<<
"mergeIdenticalDualVertices:" <<
endl 401 <<
" zero-length edges : " 674 void Foam::conformalVoronoiMesh::deferredCollapseFaceSet
685 if (deferredCollapseFaces.found(Pair<label>(owner[nI], neighbour[nI])))
696 Foam::conformalVoronoiMesh::createPolyMeshFromPoints
708 bitSet boundaryFacesToRemove;
710 timeCheck(
"Start of checkPolyMeshQuality");
712 Info<<
nl <<
"Creating polyMesh to assess quality" <<
endl;
714 createFacesOwnerNeighbourAndPatches
722 patchToDelaunayVertex,
723 boundaryFacesToRemove,
729 labelList cellToDelaunayVertex(removeUnusedCells(owner, neighbour));
730 cellCentres =
pointField(cellCentres, cellToDelaunayVertex);
736 "foamyHexMesh_temporary",
752 label nValidPatches = 0;
756 label nPatchFaces =
patchDicts[
p].get<label>(
"nFaces");
761 &&
patchDicts[
p].get<word>(
"type") == processorPolyPatch::typeName
767 patchDicts[
p].set(
"transform",
"coincidentFullMatch");
769 patches[nValidPatches] =
new processorPolyPatch
774 pMesh.boundaryMesh(),
775 processorPolyPatch::typeName
808 void Foam::conformalVoronoiMesh::checkCellSizing()
810 Info<<
"Checking cell sizes..."<<
endl;
812 timeCheck(
"Start of Cell Sizing");
814 labelList boundaryPts(number_of_finite_cells(),
internal);
817 indexDualVertices(ptsField, boundaryPts);
820 mergeIdenticalDualVertices(ptsField, boundaryPts);
822 autoPtr<polyMesh>
meshPtr = createPolyMeshFromPoints(ptsField);
823 const polyMesh& pMesh =
meshPtr();
828 DynamicList<label> checkFaces(
identity(pMesh.nFaces()));
831 Info<<
"Running checkMesh on mesh with " << pMesh.nCells()
834 const dictionary&
dict 835 = foamyHexMeshControls().foamyHexMeshDict();
837 const dictionary& meshQualityDict
840 const scalar maxNonOrtho =
843 label nWrongFaces = 0;
845 if (maxNonOrtho < 180.0 - SMALL)
859 label nNonOrthogonal =
returnReduce(wrongFaces.size(), sumOp<label>());
861 Info<<
" non-orthogonality > " << maxNonOrtho
862 <<
" degrees : " << nNonOrthogonal <<
endl;
864 nWrongFaces += nNonOrthogonal;
867 labelHashSet protrudingCells = findOffsetPatchFaces(pMesh, 0.25);
869 label nProtrudingCells = protrudingCells.size();
871 Info<<
" protruding/intruding cells : " << nProtrudingCells <<
endl;
873 nWrongFaces += nProtrudingCells;
884 Info<<
" Found total of " << nWrongFaces <<
" bad faces" <<
endl;
890 for (
const label facei : wrongFaces)
892 const label faceOwner = pMesh.faceOwner()[facei];
893 const label faceNeighbour = pMesh.faceNeighbour()[facei];
895 cellsToResizeMap.
insert(faceOwner);
896 cellsToResizeMap.insert(faceNeighbour);
899 cellsToResizeMap += protrudingCells;
901 pointField cellsToResize(cellsToResizeMap.size());
904 for (label celli = 0; celli < pMesh.nCells(); ++celli)
906 if (cellsToResizeMap.found(celli))
908 cellsToResize[
count++] = pMesh.cellCentres()[celli];
912 Info<<
" DISABLED: Automatically re-sizing " << cellsToResize.size()
913 <<
" cells that are attached to the bad faces: " <<
endl;
918 timeCheck(
"End of Cell Sizing");
920 Info<<
"Finished checking cell sizes"<<
endl;
926 const polyMesh&
mesh,
927 const scalar allowedOffset
930 timeCheck(
"Start findRemainingProtrusionSet");
934 cellSet offsetBoundaryCells
937 "foamyHexMesh_protrudingCells",
952 const face&
f = localFaces[pLFI];
956 const scalar targetSize = targetCellSize(faceCentre);
961 geometryToConformTo_.findSurfaceNearest
972 && (pHit.point().dist(faceCentre) > allowedOffset*targetSize)
975 offsetBoundaryCells.insert(fCell[pLFI]);
980 if (foamyHexMeshControls().objOutput())
982 offsetBoundaryCells.write();
985 return std::move(offsetBoundaryCells);
994 autoPtr<polyMesh>
meshPtr = createPolyMeshFromPoints(
pts);
997 timeCheck(
"polyMesh created, checking quality");
1001 DynamicList<label> checkFaces(pMesh.nFaces());
1005 scalar faceAreaLimit = SMALL;
1009 if (
mag(fAreas[fI]) > faceAreaLimit)
1011 checkFaces.append(fI);
1015 Info<<
nl <<
"Excluding " 1016 <<
returnReduce(fAreas.size() - checkFaces.size(), sumOp<label>())
1017 <<
" faces from check, < " << faceAreaLimit <<
" area" <<
endl;
1019 const dictionary&
dict 1020 = foamyHexMeshControls().foamyHexMeshDict();
1022 const dictionary& meshQualityDict
1036 label nInvalidPolyhedra = 0;
1042 if (
cells[cI].size() < 4 &&
cells[cI].size() > 0)
1048 nInvalidPolyhedra++;
1050 wrongFaces.insert(
cells[cI]);
1054 Info<<
" cells with more than 1 but fewer than 4 faces : " 1062 for (label fI = 0; fI < pMesh.nInternalFaces(); fI++)
1064 nInternalFaces[pMesh.faceOwner()[fI]]++;
1065 nInternalFaces[pMesh.faceNeighbour()[fI]]++;
1068 const polyBoundaryMesh&
patches = pMesh.boundaryMesh();
1078 nInternalFaces[owners[i]]++;
1083 label oneInternalFaceCells = 0;
1085 forAll(nInternalFaces, cI)
1087 if (nInternalFaces[cI] <= 1)
1089 oneInternalFaceCells++;
1090 wrongFaces.insert(
cells[cI]);
1094 Info<<
" cells with with zero or one non-boundary face : " 1100 bitSet ptToBeLimited(
pts.
size(),
false);
1102 for (
const label facei : wrongFaces)
1104 const face
f = pMesh.faces()[facei];
1106 ptToBeLimited.
set(
f);
1140 label maxFilterCount = 0;
1144 Delaunay::Finite_cells_iterator cit = finite_cells_begin();
1145 cit != finite_cells_end();
1149 label cI = cit->cellIndex();
1153 if (ptToBeLimited.test(cI))
1155 cit->filterCount()++;
1158 if (cit->filterCount() > maxFilterCount)
1160 maxFilterCount = cit->filterCount();
1165 Info<<
nl <<
"Maximum number of filter limits applied: " 1172 Foam::label Foam::conformalVoronoiMesh::classifyBoundaryPoint
1177 if (cit->boundaryDualVertex())
1179 if (cit->featurePointDualVertex())
1181 return featurePoint;
1183 else if (cit->featureEdgeDualVertex())
1192 else if (cit->baffleSurfaceDualVertex())
1196 else if (cit->baffleEdgeDualVertex())
1207 void Foam::conformalVoronoiMesh::indexDualVertices
1215 this->resetCellCount();
1217 label nConstrainedVertices = 0;
1218 if (foamyHexMeshControls().guardFeaturePoints())
1222 Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
1223 vit != finite_vertices_end();
1227 if (vit->constrained())
1229 vit->index() = number_of_finite_cells() + nConstrainedVertices;
1230 nConstrainedVertices++;
1235 pts.
setSize(number_of_finite_cells() + nConstrainedVertices);
1238 number_of_finite_cells() + nConstrainedVertices,
1242 if (foamyHexMeshControls().guardFeaturePoints())
1244 nConstrainedVertices = 0;
1247 Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
1248 vit != finite_vertices_end();
1252 if (vit->constrained())
1254 pts[number_of_finite_cells() + nConstrainedVertices] =
1257 boundaryPts[number_of_finite_cells() + nConstrainedVertices] =
1260 nConstrainedVertices++;
1271 Delaunay::Finite_cells_iterator cit = finite_cells_begin();
1272 cit != finite_cells_end();
1283 if (!cit->hasFarPoint())
1285 cit->cellIndex() = getNewCellIndex();
1293 typedef CGAL::Exact_predicates_exact_constructions_kernel Exact;
1294 typedef CGAL::Point_3<Exact> ExactPoint;
1296 List<labelPair> cellVerticesPair(4);
1297 List<ExactPoint> cellVertices(4);
1299 for (label vI = 0; vI < 4; ++vI)
1303 cit->vertex(vI)->procIndex(),
1304 cit->vertex(vI)->index()
1307 cellVertices[vI] = ExactPoint
1309 cit->vertex(vI)->point().x(),
1310 cit->vertex(vI)->point().y(),
1311 cit->vertex(vI)->point().z()
1318 oldToNew =
invert(oldToNew.size(), oldToNew);
1321 ExactPoint synchronisedDual = CGAL::circumcenter
1331 CGAL::to_double(synchronisedDual.x()),
1332 CGAL::to_double(synchronisedDual.y()),
1333 CGAL::to_double(synchronisedDual.z())
1338 pts[cit->cellIndex()] = cit->dual();
1342 if (foamyHexMeshControls().snapFeaturePoints())
1344 if (cit->featurePointDualVertex())
1352 geometryToConformTo_.findFeaturePointNearest
1355 sqr(targetCellSize(dual)),
1364 Info<<
"Dual = " << dual <<
nl 1365 <<
" Nearest = " << fpHit.point() <<
endl;
1368 pts[cit->cellIndex()] = fpHit.point();
1452 boundaryPts[cit->cellIndex()] = classifyBoundaryPoint(cit);
1466 void Foam::conformalVoronoiMesh::reindexDualVertices
1468 const Map<label>& dualPtIndexMap,
1474 Delaunay::Finite_cells_iterator cit = finite_cells_begin();
1475 cit != finite_cells_end();
1479 if (dualPtIndexMap.found(cit->cellIndex()))
1481 cit->cellIndex() = dualPtIndexMap[cit->cellIndex()];
1482 boundaryPts[cit->cellIndex()] =
1485 boundaryPts[cit->cellIndex()],
1486 boundaryPts[dualPtIndexMap[cit->cellIndex()]]
1493 Foam::label Foam::conformalVoronoiMesh::createPatchInfo
1499 patchNames = geometryToConformTo_.patchNames();
1503 const PtrList<dictionary>& patchInfo = geometryToConformTo_.patchInfo();
1507 if (patchInfo.set(patchi))
1509 patchDicts.set(patchi,
new dictionary(patchInfo[patchi]));
1517 wallPolyPatch::typeName
1524 patchNames[defaultPatchIndex] =
"foamyHexMesh_defaultPatch";
1525 patchDicts.set(defaultPatchIndex,
new dictionary());
1529 wallPolyPatch::typeName
1536 List<boolList> procUsedList
1547 Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
1548 vit != finite_vertices_end();
1555 if (vit->referred())
1557 procUsed[vit->procIndex()] =
true;
1564 forAll(procUsedList, proci)
1570 procUsed[proci] =
true;
1588 for (label pI = nNonProcPatches; pI < nTotalPatches; ++pI)
1605 processorPolyPatch::typeName
1614 patchDicts[nNonProcPatches + procAddI].set(
"neighbProcNo", pUI);
1621 return defaultPatchIndex;
1625 Foam::vector Foam::conformalVoronoiMesh::calcSharedPatchNormal
1634 for (label cI = 0; cI < 4; ++cI)
1636 if (
c1->neighbor(cI) !=
c2 && !
c1->vertex(cI)->constrained())
1638 if (
c1->vertex(cI)->internalBoundaryPoint())
1640 patchEdge[0] =
topoint(
c1->vertex(cI)->point());
1644 patchEdge[1] =
topoint(
c1->vertex(cI)->point());
1651 return vector(patchEdge[1] - patchEdge[0]);
1655 bool Foam::conformalVoronoiMesh::boundaryDualFace
1661 label nInternal = 0;
1662 label nExternal = 0;
1664 for (label cI = 0; cI < 4; ++cI)
1666 if (
c1->neighbor(cI) !=
c2 && !
c1->vertex(cI)->constrained())
1668 if (
c1->vertex(cI)->internalBoundaryPoint())
1672 else if (
c1->vertex(cI)->externalBoundaryPoint())
1679 Info<<
"in = " << nInternal <<
" out = " << nExternal <<
endl;
1681 return (nInternal == 1 && nExternal == 1);
1685 void Foam::conformalVoronoiMesh::createFacesOwnerNeighbourAndPatches
1694 bitSet& boundaryFacesToRemove,
1695 bool includeEmptyPatches
1703 forAll(procNeighbours, patchi)
1705 procNeighbours[patchi] =
1706 patchDicts[patchi].getOrDefault<label>(
"neighbProcNo", -1);
1709 List<DynamicList<face>> patchFaces(
nPatches);
1710 List<DynamicList<label>> patchOwners(
nPatches);
1712 List<DynamicList<label>> patchPPSlaves(
nPatches);
1713 List<DynamicList<bool>> indirectPatchFace(
nPatches);
1716 faces.setSize(number_of_finite_edges());
1717 owner.setSize(number_of_finite_edges());
1718 neighbour.setSize(number_of_finite_edges());
1719 boundaryFacesToRemove.setSize(number_of_finite_edges(),
false);
1721 labelPairPairDynListList procPatchSortingIndex(
nPatches);
1723 label dualFacei = 0;
1725 if (foamyHexMeshControls().guardFeaturePoints())
1727 OBJstream startCellStr(
"startingCell.obj");
1728 OBJstream featurePointFacesStr(
"ftPtFaces.obj");
1729 OBJstream featurePointDualsStr(
"ftPtDuals.obj");
1730 OFstream cellStr(
"vertexCells.obj");
1736 Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
1737 vit != finite_vertices_end();
1741 if (vit->constrained())
1744 std::list<Cell_handle> vertexCells;
1745 finite_incident_cells(vit, std::back_inserter(vertexCells));
1747 Cell_handle startCell;
1751 std::list<Cell_handle>::iterator vcit = vertexCells.begin();
1752 vcit != vertexCells.end();
1756 if ((*vcit)->featurePointExternalCell())
1761 if ((*vcit)->real())
1763 featurePointDualsStr.writeLine
1772 if (startCell ==
nullptr)
1774 Pout<<
"Start cell is null!" <<
endl;
1778 Cell_handle vc1 = startCell;
1781 Info<<
"c1 index = " << vc1->cellIndex() <<
" " 1782 << vc1->dual() <<
endl;
1784 for (label cI = 0; cI < 4; ++cI)
1786 Info<<
"c1 = " << cI <<
" " 1787 << vc1->neighbor(cI)->cellIndex() <<
" v = " 1788 << vc1->neighbor(cI)->dual() <<
endl;
1790 Info<< vc1->vertex(cI)->info();
1793 Cell_handle nextCell;
1795 for (label cI = 0; cI < 4; ++cI)
1797 if (vc1->vertex(cI)->externalBoundaryPoint())
1799 vc2 = vc1->neighbor(cI);
1801 Info<<
" c2 is neighbor " 1803 <<
" of c1" <<
endl;
1805 for (label cI = 0; cI < 4; ++cI)
1807 Info<<
" c2 = " << cI <<
" " 1808 << vc2->neighbor(cI)->cellIndex() <<
" v = " 1809 << vc2->vertex(cI)->index() <<
endl;
1813 f[0] = vit->index();
1814 f[1] = vc1->cellIndex();
1815 f[2] = vc2->cellIndex();
1823 vector correctNormal = calcSharedPatchNormal(vc1, vc2);
1824 correctNormal.normalise();
1826 Info<<
" cN " << correctNormal <<
endl;
1830 if (
mag(fN) < SMALL)
1839 if ((fN & correctNormal) > 0)
1849 label own = vit->index();
1853 Info<<
"Start walk from " << vc1->cellIndex()
1854 <<
" to " << vc2->cellIndex() <<
endl;
1861 Info<<
" Walk from " << vc1->cellIndex()
1862 <<
" " << vc1->dual()
1863 <<
" to " << vc2->cellIndex()
1864 <<
" " << vc2->dual()
1867 startCellStr.writeLine(vc1->dual(), vc2->dual());
1872 geometryToConformTo_.findPatch
1877 f[1] = vc1->cellIndex();
1878 f[2] = vc2->cellIndex();
1880 patchFaces[patchIndex].
append(
f);
1881 patchOwners[patchIndex].append(own);
1882 patchPPSlaves[patchIndex].append(own);
1885 Cell_handle nextCell;
1887 Info<<
" c1 vertices " << vc2->dual() <<
endl;
1888 for (label cI = 0; cI < 4; ++cI)
1890 Info<<
" " << vc2->vertex(cI)->info();
1892 Info<<
" c1 neighbour vertices " <<
endl;
1893 for (label cI = 0; cI < 4; ++cI)
1897 !vc2->vertex(cI)->constrained()
1898 && vc2->neighbor(cI) != vc1
1899 && !is_infinite(vc2->neighbor(cI))
1902 vc2->neighbor(cI)->featurePointExternalCell()
1903 || vc2->neighbor(cI)->featurePointInternalCell()
1905 && vc2->neighbor(cI)->hasConstrainedPoint()
1915 Info<<
" neighbour " << cI <<
" " 1916 << vc2->neighbor(cI)->dual() <<
endl;
1917 for (label
I = 0;
I < 4; ++
I)
1920 << vc2->neighbor(cI)->vertex(
I)->info();
1925 for (label cI = 0; cI < 4; ++cI)
1929 !vc2->vertex(cI)->constrained()
1930 && vc2->neighbor(cI) != vc1
1931 && !is_infinite(vc2->neighbor(cI))
1934 vc2->neighbor(cI)->featurePointExternalCell()
1935 || vc2->neighbor(cI)->featurePointInternalCell()
1937 && vc2->neighbor(cI)->hasConstrainedPoint()
1941 if (boundaryDualFace(vc2, vc2->neighbor(cI)))
1943 nextCell = vc2->neighbor(cI);
1953 }
while (vc1 != startCell && iter < 100);
1960 Delaunay::Finite_edges_iterator eit = finite_edges_begin();
1961 eit != finite_edges_end();
1965 Cell_handle
c = eit->first;
1966 Vertex_handle vA =
c->vertex(eit->second);
1967 Vertex_handle vB =
c->vertex(eit->third);
1969 if (vA->constrained() && vB->constrained())
1976 (vA->constrained() && vB->internalOrBoundaryPoint())
1977 || (vB->constrained() && vA->internalOrBoundaryPoint())
1980 face newDualFace = buildDualFace(eit);
1985 if (ownerAndNeighbour(vA, vB, own, nei))
1991 faces[dualFacei] = newDualFace;
1992 owner[dualFacei] = own;
1993 neighbour[dualFacei] = nei;
1999 (vA->internalOrBoundaryPoint() && !vA->referred())
2000 || (vB->internalOrBoundaryPoint() && !vB->referred())
2005 (vA->internalPoint() && vB->externalBoundaryPoint())
2006 || (vB->internalPoint() && vA->externalBoundaryPoint())
2009 Cell_circulator ccStart = incident_cells(*eit);
2010 Cell_circulator cc1 = ccStart;
2011 Cell_circulator cc2 = cc1;
2015 bool skipEdge =
false;
2021 cc1->hasFarPoint() || cc2->hasFarPoint()
2022 || is_infinite(cc1) || is_infinite(cc2)
2025 Pout<<
"Ignoring edge between internal and external: " 2036 }
while (cc1 != ccStart);
2051 face newDualFace = buildDualFace(eit);
2053 if (newDualFace.size() >= 3)
2058 if (ownerAndNeighbour(vA, vB, own, nei))
2063 label patchIndex = -1;
2072 if (isProcBoundaryEdge(eit))
2077 label procIndex =
max(vA->procIndex(), vB->procIndex());
2081 procNeighbours.find(vA->procIndex()),
2082 procNeighbours.find(vB->procIndex())
2093 DynamicList<labelPairPair>& sortingIndex =
2094 procPatchSortingIndex[patchIndex];
2096 if (vB->internalOrBoundaryPoint() && vB->referred())
2102 labelPair(vA->index(), vA->procIndex()),
2113 labelPair(vB->index(), vB->procIndex()),
2124 DynamicList<labelPairPair>& sortingIndex =
2125 procPatchSortingIndex[patchIndex];
2127 if (vA->internalOrBoundaryPoint() && vA->referred())
2133 labelPair(vA->index(), vA->procIndex()),
2144 labelPair(vB->index(), vB->procIndex()),
2163 patchIndex = geometryToConformTo_.findPatch(ptA, ptB);
2166 if (patchIndex == -1)
2175 patchIndex = geometryToConformTo_.findPatch
2181 patchFaces[patchIndex].append(newDualFace);
2182 patchOwners[patchIndex].append(own);
2188 vA->boundaryPoint() && vB->boundaryPoint()
2189 && !ptPairs_.isPointPair(vA, vB)
2190 && !ftPtConformer_.featurePointPairs().isPointPair(vA, vB)
2193 indirectPatchFace[patchIndex].append(
true);
2197 indirectPatchFace[patchIndex].append(
false);
2201 if (vA->internalOrBoundaryPoint())
2203 patchPPSlaves[patchIndex].append(vB->index());
2207 patchPPSlaves[patchIndex].append(vA->index());
2214 !vA->boundaryPoint()
2215 || !vB->boundaryPoint()
2216 || ptPairs_.isPointPair(vA, vB)
2217 || ftPtConformer_.featurePointPairs().isPointPair(vA, vB)
2220 patchIndex = geometryToConformTo_.findPatch(ptA, ptB);
2226 && geometryToConformTo_.patchInfo().set(patchIndex)
2231 patchFaces[patchIndex].append(newDualFace);
2232 patchOwners[patchIndex].append(own);
2233 indirectPatchFace[patchIndex].append(
false);
2237 patchFaces[patchIndex].append(newDualFace);
2238 patchOwners[patchIndex].append(nei);
2239 indirectPatchFace[patchIndex].append(
false);
2244 <
labelPair(vA->index(), vA->procIndex())
2247 patchPPSlaves[patchIndex].append(vB->index());
2248 patchPPSlaves[patchIndex].append(vB->index());
2252 patchPPSlaves[patchIndex].append(vA->index());
2253 patchPPSlaves[patchIndex].append(vA->index());
2260 faces[dualFacei] = newDualFace;
2261 owner[dualFacei] = own;
2262 neighbour[dualFacei] = nei;
2271 if (!patchFaces[defaultPatchIndex].empty())
2273 Pout<<
nl << patchFaces[defaultPatchIndex].size()
2274 <<
" faces were not able to have their patch determined from " 2276 <<
nl <<
"Adding to patch " <<
patchNames[defaultPatchIndex]
2280 label nInternalFaces = dualFacei;
2282 faces.setSize(nInternalFaces);
2283 owner.setSize(nInternalFaces);
2284 neighbour.setSize(nInternalFaces);
2286 timeCheck(
"polyMesh quality checked");
2288 sortFaces(faces, owner, neighbour);
2295 procPatchSortingIndex
2298 timeCheck(
"faces, owner, neighbour sorted");
2306 boundaryFacesToRemove,
2313 patchPointPairSlaves.setSize(
nPatches);
2314 forAll(patchPPSlaves, patchi)
2316 patchPointPairSlaves[patchi].transfer(patchPPSlaves[patchi]);
2319 if (foamyHexMeshControls().objOutput())
2321 Info<<
"Writing processor interfaces" <<
endl;
2325 if (patchFaces[nbI].size() > 0)
2327 const label neighbour =
2328 patchDicts[nbI].getOrDefault<label>(
"neighbProcNo", -1);
2330 faceList procPatchFaces = patchFaces[nbI];
2336 forAll(procPatchFaces, fI)
2338 procPatchFaces[fI].flip();
2342 if (neighbour != -1)
2353 time().
path()/fName,
2364 void Foam::conformalVoronoiMesh::sortFaces
2385 List<labelPair> ownerNeighbourPair(owner.size());
2387 forAll(ownerNeighbourPair, oNI)
2389 ownerNeighbourPair[oNI] =
labelPair(owner[oNI], neighbour[oNI]);
2393 <<
"Sorting faces, owner and neighbour into upper triangular order" 2397 oldToNew =
invert(oldToNew.size(), oldToNew);
2405 void Foam::conformalVoronoiMesh::sortProcPatches
2407 List<DynamicList<face>>& patchFaces,
2408 List<DynamicList<label>>& patchOwners,
2409 List<DynamicList<label>>& patchPointPairSlaves,
2410 labelPairPairDynListList& patchSortingIndices
2418 forAll(patchSortingIndices, patchi)
2420 faceList& faces = patchFaces[patchi];
2422 DynamicList<label>& slaves = patchPointPairSlaves[patchi];
2423 DynamicList<labelPairPair>& sortingIndices
2424 = patchSortingIndices[patchi];
2426 if (!sortingIndices.empty())
2430 faces.size() != sortingIndices.size()
2431 || owner.size() != sortingIndices.size()
2432 || slaves.size() != sortingIndices.size()
2436 <<
"patch size and size of sorting indices is inconsistent " 2437 <<
" for patch " << patchi <<
nl 2438 <<
" faces.size() " << faces.size() <<
nl 2439 <<
" owner.size() " << owner.size() <<
nl 2440 <<
" slaves.size() " << slaves.size() <<
nl 2441 <<
" sortingIndices.size() " 2442 << sortingIndices.size()
2447 oldToNew =
invert(oldToNew.size(), oldToNew);
2458 void Foam::conformalVoronoiMesh::addPatches
2460 const label nInternalFaces,
2464 bitSet& boundaryFacesToRemove,
2465 const List<DynamicList<face>>& patchFaces,
2466 const List<DynamicList<label>>& patchOwners,
2467 const List<DynamicList<bool>>& indirectPatchFace
2470 label nBoundaryFaces = 0;
2475 patchDicts[
p].set(
"startFace", nInternalFaces + nBoundaryFaces);
2477 nBoundaryFaces += patchFaces[
p].size();
2480 faces.setSize(nInternalFaces + nBoundaryFaces);
2481 owner.setSize(nInternalFaces + nBoundaryFaces);
2482 boundaryFacesToRemove.setSize(nInternalFaces + nBoundaryFaces);
2484 label facei = nInternalFaces;
2490 faces[facei] = patchFaces[
p][
f];
2491 owner[facei] = patchOwners[
p][
f];
2492 boundaryFacesToRemove[facei] = indirectPatchFace[
p][
f];
2500 void Foam::conformalVoronoiMesh::removeUnusedPoints
2507 Info<<
nl <<
"Removing unused points" <<
endl;
2509 bitSet ptUsed(
pts.
size(),
false);
2515 const face&
f = faces[fI];
2529 if (ptUsed.test(ptUI))
2531 oldToNew[ptUI] = pointi++;
2544 boundaryPts.setSize(pointi);
2561 Info<<
nl <<
"Removing unused cells" <<
endl;
2563 bitSet cellUsed(vertexCount(),
false);
2567 cellUsed.set(owner);
2568 cellUsed.set(neighbour);
2572 labelList oldToNew(cellUsed.size(), label(-1));
2579 if (cellUsed.test(cellUI))
2581 oldToNew[cellUI] = celli++;
2591 DynamicList<label> unusedCells;
2595 if (!cellUsed.test(cUI))
2597 unusedCells.append(cUI);
2601 if (unusedCells.size() > 0)
2605 <<
" unused cell labels" <<
endl;
2609 label& o = owner[oI];
2616 label&
n = neighbour[nI];
static bool checkMesh(const bool report, const polyMesh &mesh, const dictionary &dict, labelHashSet &wrongFaces, const bool dryRun=false)
Check mesh with mesh settings in dict. Collects incorrect faces.
void size(const label n)
Older name for setAddressableSize.
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
Binary search to find the index of the last element in a sorted list that is less than value...
pointFromPoint topoint(const Point &P)
List< cell > cellList
List of cell.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
void append(const T &val)
Append an element at the end of the list.
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
constexpr char nl
The newline '\n' character (0x0a)
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
bool coupled(solutionDict.getOrDefault("coupledEnergyField", false))
const dimensionedScalar c2
Second radiation constant: default SI units: [m.K].
static word newName(const label myProcNo, const label neighbProcNo)
Return the name of a processorPolyPatch.
Ostream & endl(Ostream &os)
Add newline and flush stream.
PointIndexHit< point > pointIndexHit
A PointIndexHit with a 3D point.
static bool & parRun() noexcept
Test if this a parallel run.
InfoProxy< IOstream > info() const noexcept
Return info proxy, used to print IOstream information to a stream.
Ignore writing from objectRegistry::writeObject()
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T. FatalIOError if not found, or if the number of tokens is incorrect.
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
labelList faceLabels(nFaceLabels)
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
List< labelList > labelListList
List of labelList.
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
UList< label > labelUList
A UList of labels.
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
static void allGatherList(List< T > &values, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Gather data, but keep individual values separate. Uses linear/tree communication. ...
List< face > faceList
List of faces.
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
UPtrList< const labelUList > faceCells() const
Return a list of faceCells for each patch.
vectorField pointField
pointField is a vectorField.
void setSize(const label n)
Alias for resize()
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Foam::autoPtr< Foam::dynamicFvMesh > meshPtr
static const Identity< scalar > I
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
Pair< labelPair > labelPairPair
Pair of labelPair.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
wordList patchNames(nPatches)
void reverse(UList< T > &list, const label n)
Reverse the first n elements of the list.
const wordList surface
Standard surface field types (scalar, vector, tensor, etc)
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
int debug
Static debugging option.
Pair< label > labelPair
A pair of labels.
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
void setSize(const label newLen)
Same as resize()
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
List< word > wordList
List of word.
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
vector point
Point is a vector.
#define WarningInFunction
Report a warning using Foam::Warning.
label nCells() const noexcept
Number of mesh cells.
static bool checkFaceDotProduct(const bool report, const scalar orthWarn, const polyMesh &, const vectorField &cellCentres, const vectorField &faceAreas, const labelList &checkFaces, const List< labelPair > &baffles, labelHashSet *setPtr)
See primitiveMesh.
const dimensionedScalar c
Speed of light in a vacuum.
const polyBoundaryMesh & patches
const std::string patch
OpenFOAM patch number as a std::string.
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
const dimensionedScalar c1
First radiation constant: default SI units: [W/m2].
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< vector > vectorField
Specialisation of Field<T> for vector.
static autoPtr< polyPatch > New(const word &patchType, const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm)
Return pointer to a new patch created on freestore from components.
PtrList< dictionary > patchDicts
List< label > labelList
A List of labels.
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
HashSet< labelPair, Foam::Hash< labelPair > > labelPairHashSet
A HashSet for a labelPair. The hashing is based on labelPair (FixedList) and is thus non-commutative...
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
List< bool > boolList
A List of bools.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
static constexpr const zero Zero
Global zero (0)