38 const Foam::scalar Foam::conformalVoronoiMesh::searchConeAngle
41 const Foam::scalar Foam::conformalVoronoiMesh::searchAngleOppositeSurface
47 void Foam::conformalVoronoiMesh::conformToSurface()
49 this->resetCellCount();
53 Delaunay::Finite_cells_iterator cit = finite_cells_begin();
54 cit != finite_cells_end();
61 if (!reconformToSurface())
64 reinsertSurfaceConformation();
68 sync(decomposition().procBounds());
76 buildSurfaceConformation();
78 if (distributeBackground(*
this))
82 sync(decomposition().procBounds());
88 storeSurfaceConformation();
95 bool Foam::conformalVoronoiMesh::reconformToSurface()
const 100 % foamyHexMeshControls().surfaceConformationRebuildFrequency() == 0
111 Foam::label Foam::conformalVoronoiMesh::findVerticesNearBoundaries()
113 label countNearBoundaryVertices = 0;
117 Delaunay::Finite_facets_iterator fit = finite_facets_begin();
118 fit != finite_facets_end();
122 Cell_handle
c1 = fit->first;
123 Cell_handle
c2 = fit->first->neighbor(fit->second);
125 if (is_infinite(
c1) || is_infinite(
c2))
133 if (!geometryToConformTo_.findSurfaceAnyIntersection(dE0, dE1))
138 for (label celli = 0; celli < 4; ++celli)
140 Vertex_handle v =
c1->vertex(celli);
145 && v->internalPoint()
146 && fit->second != celli
149 v->setNearBoundary();
153 for (label celli = 0; celli < 4; ++celli)
155 Vertex_handle v =
c2->vertex(celli);
160 && v->internalPoint()
161 && fit->second != celli
164 v->setNearBoundary();
171 Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
172 vit != finite_vertices_end();
176 if (vit->nearBoundary())
178 countNearBoundaryVertices++;
219 return countNearBoundaryVertices;
223 void Foam::conformalVoronoiMesh::buildSurfaceConformation()
225 timeCheck(
"Start buildSurfaceConformation");
228 <<
"Rebuilding surface conformation for more iterations" 231 existingEdgeLocations_.clearStorage();
232 existingSurfacePtLocations_.clearStorage();
234 buildEdgeLocationTree(existingEdgeLocations_);
235 buildSurfacePtLocationTree(existingSurfacePtLocations_);
237 label initialTotalHits = 0;
268 label countNearBoundaryVertices = findVerticesNearBoundaries();
270 Info<<
" Vertices marked as being near a boundary: " 271 <<
returnReduce(countNearBoundaryVertices, sumOp<label>())
272 <<
" (estimated)" <<
endl;
274 timeCheck(
"After set near boundary");
276 const scalar edgeSearchDistCoeffSqr =
277 foamyHexMeshControls().edgeSearchDistCoeffSqr();
279 const scalar surfacePtReplaceDistCoeffSqr =
280 foamyHexMeshControls().surfacePtReplaceDistCoeffSqr();
282 const label AtoV = label(6/
Foam::pow(scalar(number_of_vertices()), 3));
286 pointIndexHitAndFeatureDynList featureEdgeHits(AtoV/4);
287 pointIndexHitAndFeatureDynList surfaceHits(AtoV);
288 DynamicList<label> edgeToTreeShape(AtoV/4);
289 DynamicList<label> surfaceToTreeShape(AtoV);
291 Map<scalar> surfacePtToEdgePtDist(AtoV/4);
295 Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
296 vit != finite_vertices_end();
300 if (vit->nearBoundary())
302 pointIndexHitAndFeatureDynList surfaceIntersections(AtoV);
306 dualCellSurfaceAllIntersections
317 addSurfaceAndEdgeHits
320 surfaceIntersections,
321 surfacePtReplaceDistCoeffSqr,
322 edgeSearchDistCoeffSqr,
327 surfacePtToEdgePtDist,
334 countNearBoundaryVertices--;
339 Info<<
" Vertices marked as being near a boundary: " 340 <<
returnReduce(countNearBoundaryVertices, sumOp<label>())
341 <<
" (after dual surface intersection)" <<
endl;
343 label nVerts = number_of_vertices();
344 label nSurfHits = surfaceHits.size();
345 label nFeatEdHits = featureEdgeHits.size();
349 reduce(nVerts, sumOp<label>());
350 reduce(nSurfHits, sumOp<label>());
351 reduce(nFeatEdHits, sumOp<label>());
354 Info<<
nl <<
"Initial conformation" <<
nl 355 <<
" Number of vertices " << nVerts <<
nl 356 <<
" Number of surface hits " << nSurfHits <<
nl 357 <<
" Number of edge hits " << nFeatEdHits
363 synchroniseSurfaceTrees(surfaceToTreeShape, surfaceHits);
366 DynamicList<Vb>
pts(2*surfaceHits.size() + 3*featureEdgeHits.size());
368 insertSurfacePointPairs
371 "surfaceConformationLocations_initial.obj",
378 synchroniseEdgeTrees(edgeToTreeShape, featureEdgeHits);
381 insertEdgePointGroups
384 "edgeConformationLocations_initial.obj",
390 Map<label> oldToNewIndices = insertPointPairs(
pts,
true,
true);
393 ptPairs_.reIndex(oldToNewIndices);
399 timeCheck(
"After initial conformation");
401 initialTotalHits = nSurfHits + nFeatEdHits;
410 autoPtr<labelPairHashSet> receivedVertices;
414 forAll(referralVertices, proci)
426 receivedVertices.reset
434 decomposition_().procBounds(),
440 label iterationNo = 0;
442 label maxIterations = foamyHexMeshControls().maxConformationIterations();
444 scalar iterationToInitialHitRatioLimit =
445 foamyHexMeshControls().iterationToInitialHitRatioLimit();
447 label hitLimit = label(iterationToInitialHitRatioLimit*initialTotalHits);
449 Info<<
nl <<
"Stopping iterations when: " <<
nl 450 <<
" total number of hits drops below " 451 << iterationToInitialHitRatioLimit
452 <<
" of initial hits (" << hitLimit <<
")" <<
nl 454 <<
" maximum number of iterations (" << maxIterations
460 label totalHits = initialTotalHits;
465 && totalHits >= hitLimit
466 && iterationNo < maxIterations
469 pointIndexHitAndFeatureDynList surfaceHits(0.5*AtoV);
470 pointIndexHitAndFeatureDynList featureEdgeHits(0.25*AtoV);
471 DynamicList<label> surfaceToTreeShape(AtoV/2);
472 DynamicList<label> edgeToTreeShape(AtoV/4);
474 Map<scalar> surfacePtToEdgePtDist;
478 Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
479 vit != finite_vertices_end();
490 || vit->internalBoundaryPoint()
491 || (vit->internalOrBoundaryPoint() && vit->referred())
494 pointIndexHitAndFeatureDynList surfaceIntersections(0.5*AtoV);
501 dualCellLargestSurfaceProtrusion(vit, surfHit, hitSurface);
505 surfaceIntersections.append
507 pointIndexHitAndFeature(surfHit, hitSurface)
510 addSurfaceAndEdgeHits
513 surfaceIntersections,
514 surfacePtReplaceDistCoeffSqr,
515 edgeSearchDistCoeffSqr,
520 surfacePtToEdgePtDist,
528 if (vit->nearBoundary())
536 vit->externalBoundaryPoint()
537 || (vit->externalBoundaryPoint() && vit->referred())
540 pointIndexHitAndFeatureDynList surfaceIntersections(0.5*AtoV);
547 dualCellLargestSurfaceIncursion(vit, surfHit, hitSurface);
551 surfaceIntersections.append
553 pointIndexHitAndFeature(surfHit, hitSurface)
556 addSurfaceAndEdgeHits
559 surfaceIntersections,
560 surfacePtReplaceDistCoeffSqr,
561 edgeSearchDistCoeffSqr,
566 surfacePtToEdgePtDist,
573 label nVerts = number_of_vertices();
574 label nSurfHits = surfaceHits.size();
575 label nFeatEdHits = featureEdgeHits.size();
579 reduce(nVerts, sumOp<label>());
580 reduce(nSurfHits, sumOp<label>());
581 reduce(nFeatEdHits, sumOp<label>());
584 Info<<
nl <<
"Conformation iteration " << iterationNo <<
nl 585 <<
" Number of vertices " << nVerts <<
nl 586 <<
" Number of surface hits " << nSurfHits <<
nl 587 <<
" Number of edge hits " << nFeatEdHits
590 totalHits = nSurfHits + nFeatEdHits;
592 label nNotInserted = 0;
600 synchroniseSurfaceTrees(surfaceToTreeShape, surfaceHits);
605 2*surfaceHits.size() + 3*featureEdgeHits.size()
608 insertSurfacePointPairs
611 "surfaceConformationLocations_" +
name(iterationNo) +
".obj",
619 synchroniseEdgeTrees(edgeToTreeShape, featureEdgeHits);
622 insertEdgePointGroups
625 "edgeConformationLocations_" +
name(iterationNo) +
".obj",
631 Map<label> oldToNewIndices = insertPointPairs(
pts,
true,
true);
634 ptPairs_.reIndex(oldToNewIndices);
642 decomposition_().procBounds(),
649 timeCheck(
"Conformation iteration " +
name(iterationNo));
653 if (iterationNo == maxIterations)
656 <<
"Maximum surface conformation iterations (" 657 << maxIterations <<
") reached." <<
endl;
660 if (totalHits <= nNotInserted)
662 Info<<
nl <<
"Total hits (" << totalHits
663 <<
") less than number of failed insertions (" << nNotInserted
664 <<
"), stopping iterations" <<
endl;
668 if (totalHits < hitLimit)
670 Info<<
nl <<
"Total hits (" << totalHits
671 <<
") less than limit (" << hitLimit
672 <<
"), stopping iterations" <<
endl;
676 edgeLocationTreePtr_.clear();
677 surfacePtLocationTreePtr_.clear();
681 Foam::label Foam::conformalVoronoiMesh::synchroniseSurfaceTrees
683 const DynamicList<label>& surfaceToTreeShape,
684 pointIndexHitAndFeatureList& surfaceHits
687 Info<<
" Surface tree synchronisation" <<
endl;
689 pointIndexHitAndFeatureDynList synchronisedSurfLocations
694 List<pointIndexHitAndFeatureDynList> procSurfLocations(
Pstream::nProcs());
700 label nStoppedInsertion = 0;
711 const pointIndexHitAndFeatureList& otherSurfEdges =
712 procSurfLocations[proci];
714 forAll(otherSurfEdges, peI)
716 const Foam::point& pt = otherSurfEdges[peI].first().hitPoint();
719 pointIsNearSurfaceLocation(pt, nearest);
722 pointIsNearFeatureEdgeLocation(pt, nearestEdge);
724 if (nearest.hit() || nearestEdge.hit())
727 hits[proci].insert(peI);
738 synchronisedSurfLocations.append(surfaceHits[eI]);
742 surfacePtLocationTreePtr_().remove(surfaceToTreeShape[eI]);
754 const label nNotInserted =
returnReduce(nStoppedInsertion, sumOp<label>());
756 Info<<
" Not inserting total of " << nNotInserted <<
" locations" 759 surfaceHits = synchronisedSurfLocations;
765 Foam::label Foam::conformalVoronoiMesh::synchroniseEdgeTrees
767 const DynamicList<label>& edgeToTreeShape,
768 pointIndexHitAndFeatureList& featureEdgeHits
771 Info<<
" Edge tree synchronisation" <<
endl;
773 pointIndexHitAndFeatureDynList synchronisedEdgeLocations
775 featureEdgeHits.size()
778 List<pointIndexHitAndFeatureDynList> procEdgeLocations(
Pstream::nProcs());
784 label nStoppedInsertion = 0;
795 pointIndexHitAndFeatureList& otherProcEdges = procEdgeLocations[proci];
797 forAll(otherProcEdges, peI)
799 const Foam::point& pt = otherProcEdges[peI].first().hitPoint();
802 pointIsNearFeatureEdgeLocation(pt, nearest);
814 hits[proci].insert(peI);
821 forAll(featureEdgeHits, eI)
825 synchronisedEdgeLocations.append(featureEdgeHits[eI]);
829 edgeLocationTreePtr_().remove(edgeToTreeShape[eI]);
841 const label nNotInserted =
returnReduce(nStoppedInsertion, sumOp<label>());
843 Info<<
" Not inserting total of " << nNotInserted <<
" locations" 846 featureEdgeHits = synchronisedEdgeLocations;
852 bool Foam::conformalVoronoiMesh::surfaceLocationConformsToInside
854 const pointIndexHitAndFeature& info
857 if (info.first().hit())
861 geometryToConformTo_.getNormal
864 List<pointIndexHit>(1, info.first()),
870 const scalar ppDist = pointPairDistance(info.first().hitPoint());
872 const Foam::point innerPoint = info.first().hitPoint() - ppDist*
n;
874 if (!geometryToConformTo_.inside(innerPoint))
886 bool Foam::conformalVoronoiMesh::dualCellSurfaceAnyIntersection
888 const Delaunay::Finite_vertices_iterator& vit
891 std::list<Facet> facets;
892 incident_facets(vit, std::back_inserter(facets));
896 std::list<Facet>::iterator fit=facets.begin();
903 is_infinite(fit->first)
904 || is_infinite(fit->first->neighbor(fit->second))
905 || !fit->first->hasInternalPoint()
906 || !fit->first->neighbor(fit->second)->hasInternalPoint()
913 Foam::point dE1 = fit->first->neighbor(fit->second)->dual();
920 bool inProc = clipLineToProc(
topoint(vit->point()), a,
b);
926 && geometryToConformTo_.findSurfaceAnyIntersection(a,
b)
934 if (geometryToConformTo_.findSurfaceAnyIntersection(dE0, dE1))
945 bool Foam::conformalVoronoiMesh::dualCellSurfaceAllIntersections
947 const Delaunay::Finite_vertices_iterator& vit,
948 pointIndexHitAndFeatureDynList& infoList
951 bool flagIntersection =
false;
953 std::list<Facet> facets;
954 incident_facets(vit, std::back_inserter(facets));
958 std::list<Facet>::iterator fit = facets.begin();
965 is_infinite(fit->first)
966 || is_infinite(fit->first->neighbor(fit->second))
967 || !fit->first->hasInternalPoint()
968 || !fit->first->neighbor(fit->second)->hasInternalPoint()
977 Foam::point dE1 = fit->first->neighbor(fit->second)->dual();
980 label hitSurfaceIntersection = -1;
984 bool inProc = clipLineToProc(
topoint(vit->point()), dE0, dE1);
992 geometryToConformTo_.findSurfaceNearestIntersection
997 hitSurfaceIntersection
1000 if (infoIntersection.hit())
1004 geometryToConformTo_.getNormal
1006 hitSurfaceIntersection,
1007 List<pointIndexHit>(1, infoIntersection),
1015 const plane
p(infoIntersection.hitPoint(),
n);
1017 const plane::ray r(vertex,
n);
1019 const scalar d =
p.normalIntersect(r);
1023 pointIndexHitAndFeature info;
1024 geometryToConformTo_.findSurfaceNearest
1027 4.0*
magSqr(newPoint - vertex),
1032 bool rejectPoint =
false;
1034 if (!surfaceLocationConformsToInside(info))
1039 if (!rejectPoint && info.first().hit())
1041 if (!infoList.empty())
1048 infoList[hitI].first().index()
1049 == info.first().index()
1057 = infoList[hitI].first().hitPoint();
1059 const scalar separationDistance =
1060 mag(
p - info.first().hitPoint());
1062 const scalar minSepDist =
1065 foamyHexMeshControls().removalDistCoeff()
1072 if (separationDistance < minSepDist)
1083 if (!rejectPoint && info.first().hit())
1085 flagIntersection =
true;
1086 infoList.append(info);
1091 return flagIntersection;
1095 bool Foam::conformalVoronoiMesh::clipLineToProc
1102 bool inProc =
false;
1104 pointIndexHit findAnyIntersection = decomposition_().findLine(a,
b);
1106 if (!findAnyIntersection.hit())
1126 b = findAnyIntersection.hitPoint();
1131 a = findAnyIntersection.hitPoint();
1139 void Foam::conformalVoronoiMesh::dualCellLargestSurfaceProtrusion
1141 const Delaunay::Finite_vertices_iterator& vit,
1143 label& hitSurfaceLargest
1148 hitSurfaceLargest = -1;
1150 std::list<Facet> facets;
1151 finite_incident_facets(vit, std::back_inserter(facets));
1155 scalar maxProtrusionDistance = maxSurfaceProtrusion(vert);
1159 std::list<Facet>::iterator fit = facets.begin();
1160 fit != facets.end();
1164 Cell_handle
c1 = fit->first;
1165 Cell_handle
c2 = fit->first->neighbor(fit->second);
1169 is_infinite(
c1) || is_infinite(
c2)
1171 !
c1->internalOrBoundaryDualVertex()
1172 || !
c2->internalOrBoundaryDualVertex()
1174 || !
c1->real() || !
c2->real()
1191 >
magSqr(geometryToConformTo().globalBounds().
mag())
1200 geometryToConformTo_.findSurfaceNearestIntersection
1212 allGeometry_[hitSurface].getNormal
1214 List<pointIndexHit>(1, surfHit),
1220 const scalar normalProtrusionDistance
1222 (endPt - surfHit.hitPoint()) &
n 1225 if (normalProtrusionDistance > maxProtrusionDistance)
1227 const plane
p(surfHit.hitPoint(),
n);
1229 const plane::ray r(endPt, -
n);
1231 const scalar d =
p.normalIntersect(r);
1235 pointIndexHitAndFeature info;
1236 geometryToConformTo_.findSurfaceNearest
1239 4.0*
magSqr(newPoint - endPt),
1244 if (info.first().hit())
1248 surfaceLocationConformsToInside
1250 pointIndexHitAndFeature(info.first(), info.second())
1254 surfHitLargest = info.first();
1255 hitSurfaceLargest = info.second();
1257 maxProtrusionDistance = normalProtrusionDistance;
1268 surfHitLargest.hit()
1271 && !decomposition().positionOnThisProcessor(surfHitLargest.hitPoint())
1279 hitSurfaceLargest = -1;
1284 void Foam::conformalVoronoiMesh::dualCellLargestSurfaceIncursion
1286 const Delaunay::Finite_vertices_iterator& vit,
1288 label& hitSurfaceLargest
1293 hitSurfaceLargest = -1;
1295 std::list<Facet> facets;
1296 finite_incident_facets(vit, std::back_inserter(facets));
1300 scalar minIncursionDistance = -maxSurfaceProtrusion(vert);
1304 std::list<Facet>::iterator fit = facets.begin();
1305 fit != facets.end();
1309 Cell_handle
c1 = fit->first;
1310 Cell_handle
c2 = fit->first->neighbor(fit->second);
1314 is_infinite(
c1) || is_infinite(
c2)
1316 !
c1->internalOrBoundaryDualVertex()
1317 || !
c2->internalOrBoundaryDualVertex()
1319 || !
c1->real() || !
c2->real()
1336 >
magSqr(geometryToConformTo().globalBounds().
mag())
1345 geometryToConformTo_.findSurfaceNearestIntersection
1357 allGeometry_[hitSurface].getNormal
1359 List<pointIndexHit>(1, surfHit),
1365 scalar normalIncursionDistance
1367 (endPt - surfHit.hitPoint()) &
n 1370 if (normalIncursionDistance < minIncursionDistance)
1372 const plane
p(surfHit.hitPoint(),
n);
1374 const plane::ray r(endPt,
n);
1376 const scalar d =
p.normalIntersect(r);
1380 pointIndexHitAndFeature info;
1381 geometryToConformTo_.findSurfaceNearest
1384 4.0*
magSqr(newPoint - endPt),
1389 if (info.first().hit())
1393 surfaceLocationConformsToInside
1395 pointIndexHitAndFeature(info.first(), info.second())
1399 surfHitLargest = info.first();
1400 hitSurfaceLargest = info.second();
1402 minIncursionDistance = normalIncursionDistance;
1413 surfHitLargest.hit()
1416 && !decomposition().positionOnThisProcessor(surfHitLargest.hitPoint())
1424 hitSurfaceLargest = -1;
1429 void Foam::conformalVoronoiMesh::reportProcessorOccupancy()
1433 Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
1434 vit != finite_vertices_end();
1443 && !decomposition().positionOnThisProcessor(
topoint(vit->point()))
1446 Pout<<
topoint(vit->point()) <<
" is not on this processor " 1559 void Foam::conformalVoronoiMesh::limitDisplacement
1561 const Delaunay::Finite_vertices_iterator& vit,
1571 displacement =
Zero;
1583 if (!geometryToConformTo_.globalBounds().contains(dispPt))
1588 else if (geometryToConformTo_.findSurfaceAnyIntersection(pt, dispPt))
1599 scalar searchDistanceSqr =
sqr 1601 2*vit->targetCellSize()
1602 *foamyHexMeshControls().pointPairDistanceCoeff()
1605 geometryToConformTo_.findSurfaceNearest
1617 if (surfHit.point().distSqr(pt) <= searchDistanceSqr)
1620 displacement =
Zero;
1631 displacement *= 0.5;
1633 limitDisplacement(vit, displacement, callCount);
1638 Foam::scalar Foam::conformalVoronoiMesh::angleBetweenSurfacePoints
1645 label pAsurfaceHit = -1;
1647 const scalar searchDist = 5.0*targetCellSize(pA);
1649 geometryToConformTo_.findSurfaceNearest
1664 allGeometry_[pAsurfaceHit].getNormal
1666 List<pointIndexHit>(1, pAhit),
1670 const vector nA = norm[0];
1673 label pBsurfaceHit = -1;
1675 geometryToConformTo_.findSurfaceNearest
1688 allGeometry_[pBsurfaceHit].getNormal
1690 List<pointIndexHit>(1, pBhit),
1694 const vector nB = norm[0];
1700 bool Foam::conformalVoronoiMesh::nearSurfacePoint
1702 pointIndexHitAndFeature& pHit
1708 const bool closeToSurfacePt = pointIsNearSurfaceLocation(pt, closePoint);
1714 closePoint.hitPoint().distSqr(pt)
1715 >
sqr(pointPairDistance(pt))
1719 const scalar cosAngle =
1720 angleBetweenSurfacePoints(pt, closePoint.hitPoint());
1723 if (cosAngle < searchAngleOppositeSurface)
1726 label pCloseSurfaceHit = -1;
1728 const scalar searchDist = targetCellSize(closePoint.hitPoint());
1730 geometryToConformTo_.findSurfaceNearest
1732 closePoint.hitPoint(),
1740 allGeometry_[pCloseSurfaceHit].getNormal
1742 List<pointIndexHit>(1, pCloseHit),
1746 const vector& nA = norm[0];
1749 label oppositeSurfaceHit = -1;
1751 geometryToConformTo_.findSurfaceNearestIntersection
1753 closePoint.hitPoint() + 0.5*pointPairDistance(pt)*nA,
1754 closePoint.hitPoint() + 5*targetCellSize(pt)*nA,
1759 if (oppositeHit.hit())
1762 pHit.first() = oppositeHit;
1763 pHit.second() = oppositeSurfaceHit;
1765 return !closeToSurfacePt;
1770 return closeToSurfacePt;
1774 bool Foam::conformalVoronoiMesh::appendToSurfacePtTree
1779 label startIndex = existingSurfacePtLocations_.size();
1781 existingSurfacePtLocations_.append(pt);
1783 label endIndex = existingSurfacePtLocations_.size();
1785 return surfacePtLocationTreePtr_().insert(startIndex, endIndex);
1789 bool Foam::conformalVoronoiMesh::appendToEdgeLocationTree
1794 label startIndex = existingEdgeLocations_.size();
1796 existingEdgeLocations_.append(pt);
1798 label endIndex = existingEdgeLocations_.size();
1800 return edgeLocationTreePtr_().insert(startIndex, endIndex);
1805 Foam::conformalVoronoiMesh::nearestFeatureEdgeLocations
1810 const auto&
tree = edgeLocationTreePtr_();
1812 const scalar exclusionRangeSqr = featureEdgeExclusionDistanceSqr(pt);
1816 DynamicList<pointIndexHit> dynPointHit(elems.size());
1818 for (
const label index : elems)
1825 tree.shapes().centre(index),
1835 bool Foam::conformalVoronoiMesh::pointIsNearFeatureEdgeLocation
1840 const scalar exclusionRangeSqr = featureEdgeExclusionDistanceSqr(pt);
1843 = edgeLocationTreePtr_().findNearest(pt, exclusionRangeSqr);
1849 bool Foam::conformalVoronoiMesh::pointIsNearFeatureEdgeLocation
1855 const scalar exclusionRangeSqr = featureEdgeExclusionDistanceSqr(pt);
1857 info = edgeLocationTreePtr_().findNearest(pt, exclusionRangeSqr);
1863 bool Foam::conformalVoronoiMesh::pointIsNearSurfaceLocation
1870 pointIsNearSurfaceLocation(pt, info);
1876 bool Foam::conformalVoronoiMesh::pointIsNearSurfaceLocation
1882 const scalar exclusionRangeSqr = surfacePtExclusionDistanceSqr(pt);
1884 info = surfacePtLocationTreePtr_().findNearest(pt, exclusionRangeSqr);
1890 bool Foam::conformalVoronoiMesh::nearFeatureEdgeLocation
1898 const scalar exclusionRangeSqr = featureEdgeExclusionDistanceSqr(pt);
1900 bool closeToFeatureEdge =
1901 pointIsNearFeatureEdgeLocation(pt, nearestEdgeHit);
1903 if (closeToFeatureEdge)
1905 List<pointIndexHit> nearHits = nearestFeatureEdgeLocations(pt);
1914 label featureHit = -1;
1916 geometryToConformTo_.findEdgeNearest
1924 const extendedFeatureEdgeMesh& eMesh
1925 = geometryToConformTo_.features()[featureHit];
1927 const vector& edgeDir = eMesh.edgeDirections()[edgeHit.index()];
1929 const vector lineBetweenPoints = pt - info.hitPoint();
1931 const scalar cosAngle
1943 mag(cosAngle) < searchConeAngle
1944 && (
mag(lineBetweenPoints) > pointPairDistance(pt))
1949 closeToFeatureEdge =
false;
1953 closeToFeatureEdge =
true;
1959 return closeToFeatureEdge;
1963 void Foam::conformalVoronoiMesh::buildEdgeLocationTree
1965 const DynamicList<Foam::point>& existingEdgeLocations
1968 treeBoundBox overallBb
1970 geometryToConformTo_.globalBounds().extend(rndGen_, 1
e-4, ROOTVSMALL)
1973 edgeLocationTreePtr_.reset
1975 new dynamicIndexedOctree<dynamicTreeDataPoint>
1977 dynamicTreeDataPoint(existingEdgeLocations),
1987 void Foam::conformalVoronoiMesh::buildSurfacePtLocationTree
1989 const DynamicList<Foam::point>& existingSurfacePtLocations
1992 treeBoundBox overallBb
1994 geometryToConformTo_.globalBounds().extend(rndGen_, 1
e-4, ROOTVSMALL)
1997 surfacePtLocationTreePtr_.reset
1999 new dynamicIndexedOctree<dynamicTreeDataPoint>
2001 dynamicTreeDataPoint(existingSurfacePtLocations),
2011 void Foam::conformalVoronoiMesh::addSurfaceAndEdgeHits
2014 const pointIndexHitAndFeatureDynList& surfaceIntersections,
2015 scalar surfacePtReplaceDistCoeffSqr,
2016 scalar edgeSearchDistCoeffSqr,
2017 pointIndexHitAndFeatureDynList& surfaceHits,
2018 pointIndexHitAndFeatureDynList& featureEdgeHits,
2019 DynamicList<label>& surfaceToTreeShape,
2020 DynamicList<label>& edgeToTreeShape,
2021 Map<scalar>& surfacePtToEdgePtDist,
2025 const scalar cellSize = targetCellSize(vit);
2026 const scalar cellSizeSqr =
sqr(cellSize);
2028 forAll(surfaceIntersections, sI)
2030 pointIndexHitAndFeature surfHitI = surfaceIntersections[sI];
2032 bool keepSurfacePoint =
true;
2034 if (!surfHitI.first().hit())
2039 const Foam::point& surfPt = surfHitI.first().hitPoint();
2041 bool isNearFeaturePt = nearFeaturePt(surfPt);
2043 bool isNearFeatureEdge = surfacePtNearFeatureEdge(surfPt);
2045 bool isNearSurfacePt = nearSurfacePoint(surfHitI);
2047 if (isNearFeaturePt || isNearSurfacePt || isNearFeatureEdge)
2049 keepSurfacePoint =
false;
2052 List<List<pointIndexHit>> edHitsByFeature;
2056 const scalar searchRadiusSqr = edgeSearchDistCoeffSqr*cellSizeSqr;
2058 geometryToConformTo_.findAllNearestEdges
2066 forAll(edHitsByFeature, i)
2068 const label featureHit = featuresHit[i];
2070 List<pointIndexHit>& edHits = edHitsByFeature[i];
2083 && !decomposition().positionOnThisProcessor(edPt)
2090 if (!nearFeaturePt(edPt))
2094 surfPt.distSqr(edPt)
2095 < surfacePtReplaceDistCoeffSqr*cellSizeSqr
2105 keepSurfacePoint =
false;
2117 !nearFeatureEdgeLocation(edHit, nearestEdgeHit)
2120 appendToEdgeLocationTree(edPt);
2122 edgeToTreeShape.append
2124 existingEdgeLocations_.size() - 1
2129 featureEdgeHits.append
2131 pointIndexHitAndFeature(edHit, featureHit)
2137 surfacePtToEdgePtDist.insert
2139 existingEdgeLocations_.size() - 1,
2140 surfPt.distSqr(edPt)
2145 label hitIndex = nearestEdgeHit.index();
2151 surfPt.distSqr(edPt)
2152 < surfacePtToEdgePtDist[hitIndex]
2155 featureEdgeHits[hitIndex] =
2156 pointIndexHitAndFeature(edHit, featureHit);
2158 existingEdgeLocations_[hitIndex] =
2160 surfacePtToEdgePtDist[hitIndex] =
2161 surfPt.distSqr(edPt);
2166 edgeLocationTreePtr_().remove(hitIndex);
2167 edgeLocationTreePtr_().insert
2179 if (keepSurfacePoint)
2181 surfaceHits.append(surfHitI);
2182 appendToSurfacePtTree(surfPt);
2183 surfaceToTreeShape.append(existingSurfacePtLocations_.size() - 1);
2195 void Foam::conformalVoronoiMesh::storeSurfaceConformation()
2197 Info<<
nl <<
"Storing surface conformation" <<
endl;
2199 surfaceConformationVertices_.clear();
2202 DynamicList<Vb> tempSurfaceVertices(number_of_vertices()/10);
2206 Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
2207 vit != finite_vertices_end();
2216 && vit->boundaryPoint()
2217 && !vit->featurePoint()
2218 && !vit->constrained()
2221 tempSurfaceVertices.append
2234 tempSurfaceVertices.shrink();
2236 surfaceConformationVertices_.transfer(tempSurfaceVertices);
2241 label(surfaceConformationVertices_.size()),
2244 <<
" vertices" <<
nl <<
endl;
2248 void Foam::conformalVoronoiMesh::reinsertSurfaceConformation()
2250 Info<<
nl <<
"Reinserting stored surface conformation" <<
endl;
2252 Map<label> oldToNewIndices =
2253 insertPointPairs(surfaceConformationVertices_,
true,
true);
2255 ptPairs_.reIndex(oldToNewIndices);
2257 bitSet selectedElems(surfaceConformationVertices_.size(),
true);
2259 forAll(surfaceConformationVertices_, vI)
2261 Vb& v = surfaceConformationVertices_[vI];
2262 label& vIndex = v.
index();
2264 const auto iter = oldToNewIndices.cfind(vIndex);
2268 const label newIndex = *iter;
2276 selectedElems.unset(vI);
2281 inplaceSubset<bitSet, List<Vb>>
2284 surfaceConformationVertices_
pointFromPoint topoint(const Point &P)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
dimensionedSymmTensor sqr(const dimensionedVector &dv)
static rangeType allProcs(const label communicator=worldComm)
Range of process indices for all processes.
constexpr char nl
The newline '\n' character (0x0a)
const dimensionedScalar c2
Second radiation constant: default SI units: [m.K].
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.
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 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.
An indexed form of CGAL::Triangulation_vertex_base_3<K> used to keep track of the Delaunay vertices i...
#define forAll(list, i)
Loop across all elements in list.
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. ...
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
const dimensionedScalar e
Elementary charge.
dimensionedScalar cos(const dimensionedScalar &ds)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
complex limit(const complex &c1, const complex &c2)
Tree tree(triangles.begin(), triangles.end())
constexpr scalar pi(M_PI)
Istream and Ostream manipulators taking arguments.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
#define WarningInFunction
Report a warning using Foam::Warning.
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.
List< label > labelList
A List of labels.
HashSet< labelPair, Foam::Hash< labelPair > > labelPairHashSet
A HashSet for a labelPair. The hashing is based on labelPair (FixedList) and is thus non-commutative...
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
static void listCombineReduce(List< T > &values, const CombineOp &cop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
After completion all processors have the same data.
static constexpr const zero Zero
Global zero (0)