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();
58 cit->cellIndex() = Cb::ctUnassigned;
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());
703 label nStoppedInsertion = 0;
714 const pointIndexHitAndFeatureList& otherSurfEdges =
715 procSurfLocations[proci];
717 forAll(otherSurfEdges, peI)
719 const Foam::point& pt = otherSurfEdges[peI].first().hitPoint();
722 pointIsNearSurfaceLocation(pt, nearest);
725 pointIsNearFeatureEdgeLocation(pt, nearestEdge);
727 if (nearest.hit() || nearestEdge.hit())
731 if (!hits[proci].
found(peI))
733 hits[proci].insert(peI);
746 synchronisedSurfLocations.append(surfaceHits[eI]);
750 surfacePtLocationTreePtr_().remove(surfaceToTreeShape[eI]);
762 const label nNotInserted =
returnReduce(nStoppedInsertion, sumOp<label>());
764 Info<<
" Not inserting total of " << nNotInserted <<
" locations"
767 surfaceHits = synchronisedSurfLocations;
773 Foam::label Foam::conformalVoronoiMesh::synchroniseEdgeTrees
775 const DynamicList<label>& edgeToTreeShape,
776 pointIndexHitAndFeatureList& featureEdgeHits
779 Info<<
" Edge tree synchronisation" <<
endl;
781 pointIndexHitAndFeatureDynList synchronisedEdgeLocations
783 featureEdgeHits.size()
786 List<pointIndexHitAndFeatureDynList> procEdgeLocations(
Pstream::nProcs());
795 label nStoppedInsertion = 0;
806 pointIndexHitAndFeatureList& otherProcEdges = procEdgeLocations[proci];
808 forAll(otherProcEdges, peI)
810 const Foam::point& pt = otherProcEdges[peI].first().hitPoint();
813 pointIsNearFeatureEdgeLocation(pt, nearest);
826 if (!hits[proci].
found(peI))
828 hits[proci].insert(peI);
837 forAll(featureEdgeHits, eI)
841 synchronisedEdgeLocations.append(featureEdgeHits[eI]);
845 edgeLocationTreePtr_().remove(edgeToTreeShape[eI]);
857 const label nNotInserted =
returnReduce(nStoppedInsertion, sumOp<label>());
859 Info<<
" Not inserting total of " << nNotInserted <<
" locations"
862 featureEdgeHits = synchronisedEdgeLocations;
868 bool Foam::conformalVoronoiMesh::surfaceLocationConformsToInside
870 const pointIndexHitAndFeature& info
873 if (info.first().hit())
877 geometryToConformTo_.getNormal
880 List<pointIndexHit>(1, info.first()),
886 const scalar ppDist = pointPairDistance(info.first().hitPoint());
888 const Foam::point innerPoint = info.first().hitPoint() - ppDist*
n;
890 if (!geometryToConformTo_.inside(innerPoint))
902 bool Foam::conformalVoronoiMesh::dualCellSurfaceAnyIntersection
904 const Delaunay::Finite_vertices_iterator& vit
907 std::list<Facet> facets;
908 incident_facets(vit, std::back_inserter(facets));
912 std::list<Facet>::iterator fit=facets.begin();
919 is_infinite(fit->first)
920 || is_infinite(fit->first->neighbor(fit->second))
921 || !fit->first->hasInternalPoint()
922 || !fit->first->neighbor(fit->second)->hasInternalPoint()
929 Foam::point dE1 = fit->first->neighbor(fit->second)->dual();
936 bool inProc = clipLineToProc(
topoint(vit->point()), a,
b);
942 && geometryToConformTo_.findSurfaceAnyIntersection(a,
b)
950 if (geometryToConformTo_.findSurfaceAnyIntersection(dE0, dE1))
961 bool Foam::conformalVoronoiMesh::dualCellSurfaceAllIntersections
963 const Delaunay::Finite_vertices_iterator& vit,
964 pointIndexHitAndFeatureDynList& infoList
967 bool flagIntersection =
false;
969 std::list<Facet> facets;
970 incident_facets(vit, std::back_inserter(facets));
974 std::list<Facet>::iterator fit = facets.begin();
981 is_infinite(fit->first)
982 || is_infinite(fit->first->neighbor(fit->second))
983 || !fit->first->hasInternalPoint()
984 || !fit->first->neighbor(fit->second)->hasInternalPoint()
993 Foam::point dE1 = fit->first->neighbor(fit->second)->dual();
996 label hitSurfaceIntersection = -1;
1000 bool inProc = clipLineToProc(
topoint(vit->point()), dE0, dE1);
1008 geometryToConformTo_.findSurfaceNearestIntersection
1013 hitSurfaceIntersection
1016 if (infoIntersection.hit())
1020 geometryToConformTo_.getNormal
1022 hitSurfaceIntersection,
1023 List<pointIndexHit>(1, infoIntersection),
1031 const plane
p(infoIntersection.hitPoint(),
n);
1033 const plane::ray r(vertex,
n);
1035 const scalar d =
p.normalIntersect(r);
1039 pointIndexHitAndFeature info;
1040 geometryToConformTo_.findSurfaceNearest
1043 4.0*
magSqr(newPoint - vertex),
1048 bool rejectPoint =
false;
1050 if (!surfaceLocationConformsToInside(info))
1055 if (!rejectPoint && info.first().hit())
1057 if (!infoList.empty())
1064 infoList[hitI].first().index()
1065 == info.first().index()
1073 = infoList[hitI].first().hitPoint();
1075 const scalar separationDistance =
1076 mag(
p - info.first().hitPoint());
1078 const scalar minSepDist =
1081 foamyHexMeshControls().removalDistCoeff()
1088 if (separationDistance < minSepDist)
1099 if (!rejectPoint && info.first().hit())
1101 flagIntersection =
true;
1102 infoList.append(info);
1107 return flagIntersection;
1111 bool Foam::conformalVoronoiMesh::clipLineToProc
1118 bool inProc =
false;
1120 pointIndexHit findAnyIntersection = decomposition_().findLine(a,
b);
1122 if (!findAnyIntersection.hit())
1142 b = findAnyIntersection.hitPoint();
1147 a = findAnyIntersection.hitPoint();
1155 void Foam::conformalVoronoiMesh::dualCellLargestSurfaceProtrusion
1157 const Delaunay::Finite_vertices_iterator& vit,
1159 label& hitSurfaceLargest
1164 hitSurfaceLargest = -1;
1166 std::list<Facet> facets;
1167 finite_incident_facets(vit, std::back_inserter(facets));
1171 scalar maxProtrusionDistance = maxSurfaceProtrusion(vert);
1175 std::list<Facet>::iterator fit = facets.begin();
1176 fit != facets.end();
1180 Cell_handle
c1 = fit->first;
1181 Cell_handle
c2 = fit->first->neighbor(fit->second);
1185 is_infinite(
c1) || is_infinite(
c2)
1187 !
c1->internalOrBoundaryDualVertex()
1188 || !
c2->internalOrBoundaryDualVertex()
1190 || !
c1->real() || !
c2->real()
1207 >
magSqr(geometryToConformTo().globalBounds().
mag())
1216 geometryToConformTo_.findSurfaceNearestIntersection
1228 allGeometry_[hitSurface].getNormal
1230 List<pointIndexHit>(1, surfHit),
1236 const scalar normalProtrusionDistance
1238 (endPt - surfHit.hitPoint()) &
n
1241 if (normalProtrusionDistance > maxProtrusionDistance)
1243 const plane
p(surfHit.hitPoint(),
n);
1245 const plane::ray r(endPt, -
n);
1247 const scalar d =
p.normalIntersect(r);
1251 pointIndexHitAndFeature info;
1252 geometryToConformTo_.findSurfaceNearest
1255 4.0*
magSqr(newPoint - endPt),
1260 if (info.first().hit())
1264 surfaceLocationConformsToInside
1266 pointIndexHitAndFeature(info.first(), info.second())
1270 surfHitLargest = info.first();
1271 hitSurfaceLargest = info.second();
1273 maxProtrusionDistance = normalProtrusionDistance;
1284 surfHitLargest.hit()
1287 && !decomposition().positionOnThisProcessor(surfHitLargest.hitPoint())
1295 hitSurfaceLargest = -1;
1300 void Foam::conformalVoronoiMesh::dualCellLargestSurfaceIncursion
1302 const Delaunay::Finite_vertices_iterator& vit,
1304 label& hitSurfaceLargest
1309 hitSurfaceLargest = -1;
1311 std::list<Facet> facets;
1312 finite_incident_facets(vit, std::back_inserter(facets));
1316 scalar minIncursionDistance = -maxSurfaceProtrusion(vert);
1320 std::list<Facet>::iterator fit = facets.begin();
1321 fit != facets.end();
1325 Cell_handle
c1 = fit->first;
1326 Cell_handle
c2 = fit->first->neighbor(fit->second);
1330 is_infinite(
c1) || is_infinite(
c2)
1332 !
c1->internalOrBoundaryDualVertex()
1333 || !
c2->internalOrBoundaryDualVertex()
1335 || !
c1->real() || !
c2->real()
1352 >
magSqr(geometryToConformTo().globalBounds().
mag())
1361 geometryToConformTo_.findSurfaceNearestIntersection
1373 allGeometry_[hitSurface].getNormal
1375 List<pointIndexHit>(1, surfHit),
1381 scalar normalIncursionDistance
1383 (endPt - surfHit.hitPoint()) &
n
1386 if (normalIncursionDistance < minIncursionDistance)
1388 const plane
p(surfHit.hitPoint(),
n);
1390 const plane::ray r(endPt,
n);
1392 const scalar d =
p.normalIntersect(r);
1396 pointIndexHitAndFeature info;
1397 geometryToConformTo_.findSurfaceNearest
1400 4.0*
magSqr(newPoint - endPt),
1405 if (info.first().hit())
1409 surfaceLocationConformsToInside
1411 pointIndexHitAndFeature(info.first(), info.second())
1415 surfHitLargest = info.first();
1416 hitSurfaceLargest = info.second();
1418 minIncursionDistance = normalIncursionDistance;
1429 surfHitLargest.hit()
1432 && !decomposition().positionOnThisProcessor(surfHitLargest.hitPoint())
1440 hitSurfaceLargest = -1;
1445 void Foam::conformalVoronoiMesh::reportProcessorOccupancy()
1449 Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
1450 vit != finite_vertices_end();
1459 && !decomposition().positionOnThisProcessor(
topoint(vit->point()))
1462 Pout<<
topoint(vit->point()) <<
" is not on this processor "
1575 void Foam::conformalVoronoiMesh::limitDisplacement
1577 const Delaunay::Finite_vertices_iterator& vit,
1587 displacement =
Zero;
1599 if (!geometryToConformTo_.globalBounds().contains(dispPt))
1604 else if (geometryToConformTo_.findSurfaceAnyIntersection(pt, dispPt))
1615 scalar searchDistanceSqr =
sqr
1617 2*vit->targetCellSize()
1618 *foamyHexMeshControls().pointPairDistanceCoeff()
1621 geometryToConformTo_.findSurfaceNearest
1633 if (
magSqr(pt - surfHit.hitPoint()) <= searchDistanceSqr)
1636 displacement =
Zero;
1647 displacement *= 0.5;
1649 limitDisplacement(vit, displacement, callCount);
1654 Foam::scalar Foam::conformalVoronoiMesh::angleBetweenSurfacePoints
1661 label pAsurfaceHit = -1;
1663 const scalar searchDist = 5.0*targetCellSize(pA);
1665 geometryToConformTo_.findSurfaceNearest
1680 allGeometry_[pAsurfaceHit].getNormal
1682 List<pointIndexHit>(1, pAhit),
1686 const vector nA = norm[0];
1689 label pBsurfaceHit = -1;
1691 geometryToConformTo_.findSurfaceNearest
1704 allGeometry_[pBsurfaceHit].getNormal
1706 List<pointIndexHit>(1, pBhit),
1710 const vector nB = norm[0];
1716 bool Foam::conformalVoronoiMesh::nearSurfacePoint
1718 pointIndexHitAndFeature& pHit
1724 const bool closeToSurfacePt = pointIsNearSurfaceLocation(pt, closePoint);
1730 magSqr(pt - closePoint.hitPoint())
1731 >
sqr(pointPairDistance(pt))
1735 const scalar cosAngle =
1736 angleBetweenSurfacePoints(pt, closePoint.hitPoint());
1739 if (cosAngle < searchAngleOppositeSurface)
1742 label pCloseSurfaceHit = -1;
1744 const scalar searchDist = targetCellSize(closePoint.hitPoint());
1746 geometryToConformTo_.findSurfaceNearest
1748 closePoint.hitPoint(),
1756 allGeometry_[pCloseSurfaceHit].getNormal
1758 List<pointIndexHit>(1, pCloseHit),
1762 const vector& nA = norm[0];
1765 label oppositeSurfaceHit = -1;
1767 geometryToConformTo_.findSurfaceNearestIntersection
1769 closePoint.hitPoint() + 0.5*pointPairDistance(pt)*nA,
1770 closePoint.hitPoint() + 5*targetCellSize(pt)*nA,
1775 if (oppositeHit.hit())
1778 pHit.first() = oppositeHit;
1779 pHit.second() = oppositeSurfaceHit;
1781 return !closeToSurfacePt;
1786 return closeToSurfacePt;
1790 bool Foam::conformalVoronoiMesh::appendToSurfacePtTree
1795 label startIndex = existingSurfacePtLocations_.size();
1797 existingSurfacePtLocations_.append(pt);
1799 label endIndex = existingSurfacePtLocations_.size();
1801 return surfacePtLocationTreePtr_().insert(startIndex, endIndex);
1805 bool Foam::conformalVoronoiMesh::appendToEdgeLocationTree
1810 label startIndex = existingEdgeLocations_.size();
1812 existingEdgeLocations_.append(pt);
1814 label endIndex = existingEdgeLocations_.size();
1816 return edgeLocationTreePtr_().insert(startIndex, endIndex);
1821 Foam::conformalVoronoiMesh::nearestFeatureEdgeLocations
1826 const scalar exclusionRangeSqr = featureEdgeExclusionDistanceSqr(pt);
1829 = edgeLocationTreePtr_().findSphere(pt, exclusionRangeSqr);
1831 DynamicList<pointIndexHit> dynPointHit;
1835 label index = elems[elemI];
1838 = edgeLocationTreePtr_().shapes().shapePoints()[index];
1842 dynPointHit.append(nearHit);
1849 bool Foam::conformalVoronoiMesh::pointIsNearFeatureEdgeLocation
1854 const scalar exclusionRangeSqr = featureEdgeExclusionDistanceSqr(pt);
1857 = edgeLocationTreePtr_().findNearest(pt, exclusionRangeSqr);
1863 bool Foam::conformalVoronoiMesh::pointIsNearFeatureEdgeLocation
1869 const scalar exclusionRangeSqr = featureEdgeExclusionDistanceSqr(pt);
1871 info = edgeLocationTreePtr_().findNearest(pt, exclusionRangeSqr);
1877 bool Foam::conformalVoronoiMesh::pointIsNearSurfaceLocation
1884 pointIsNearSurfaceLocation(pt, info);
1890 bool Foam::conformalVoronoiMesh::pointIsNearSurfaceLocation
1896 const scalar exclusionRangeSqr = surfacePtExclusionDistanceSqr(pt);
1898 info = surfacePtLocationTreePtr_().findNearest(pt, exclusionRangeSqr);
1904 bool Foam::conformalVoronoiMesh::nearFeatureEdgeLocation
1912 const scalar exclusionRangeSqr = featureEdgeExclusionDistanceSqr(pt);
1914 bool closeToFeatureEdge =
1915 pointIsNearFeatureEdgeLocation(pt, nearestEdgeHit);
1917 if (closeToFeatureEdge)
1919 List<pointIndexHit> nearHits = nearestFeatureEdgeLocations(pt);
1928 label featureHit = -1;
1930 geometryToConformTo_.findEdgeNearest
1938 const extendedFeatureEdgeMesh& eMesh
1939 = geometryToConformTo_.features()[featureHit];
1941 const vector& edgeDir = eMesh.edgeDirections()[edgeHit.index()];
1943 const vector lineBetweenPoints = pt - info.hitPoint();
1945 const scalar cosAngle
1957 mag(cosAngle) < searchConeAngle
1958 && (
mag(lineBetweenPoints) > pointPairDistance(pt))
1963 closeToFeatureEdge =
false;
1967 closeToFeatureEdge =
true;
1973 return closeToFeatureEdge;
1977 void Foam::conformalVoronoiMesh::buildEdgeLocationTree
1979 const DynamicList<Foam::point>& existingEdgeLocations
1982 treeBoundBox overallBb
1984 geometryToConformTo_.globalBounds().extend(rndGen_, 1
e-4)
1990 edgeLocationTreePtr_.reset
1992 new dynamicIndexedOctree<dynamicTreeDataPoint>
1994 dynamicTreeDataPoint(existingEdgeLocations),
2004 void Foam::conformalVoronoiMesh::buildSurfacePtLocationTree
2006 const DynamicList<Foam::point>& existingSurfacePtLocations
2009 treeBoundBox overallBb
2011 geometryToConformTo_.globalBounds().extend(rndGen_, 1
e-4)
2017 surfacePtLocationTreePtr_.reset
2019 new dynamicIndexedOctree<dynamicTreeDataPoint>
2021 dynamicTreeDataPoint(existingSurfacePtLocations),
2031 void Foam::conformalVoronoiMesh::addSurfaceAndEdgeHits
2034 const pointIndexHitAndFeatureDynList& surfaceIntersections,
2035 scalar surfacePtReplaceDistCoeffSqr,
2036 scalar edgeSearchDistCoeffSqr,
2037 pointIndexHitAndFeatureDynList& surfaceHits,
2038 pointIndexHitAndFeatureDynList& featureEdgeHits,
2039 DynamicList<label>& surfaceToTreeShape,
2040 DynamicList<label>& edgeToTreeShape,
2041 Map<scalar>& surfacePtToEdgePtDist,
2045 const scalar cellSize = targetCellSize(vit);
2046 const scalar cellSizeSqr =
sqr(cellSize);
2048 forAll(surfaceIntersections, sI)
2050 pointIndexHitAndFeature surfHitI = surfaceIntersections[sI];
2052 bool keepSurfacePoint =
true;
2054 if (!surfHitI.first().hit())
2059 const Foam::point& surfPt = surfHitI.first().hitPoint();
2061 bool isNearFeaturePt = nearFeaturePt(surfPt);
2063 bool isNearFeatureEdge = surfacePtNearFeatureEdge(surfPt);
2065 bool isNearSurfacePt = nearSurfacePoint(surfHitI);
2067 if (isNearFeaturePt || isNearSurfacePt || isNearFeatureEdge)
2069 keepSurfacePoint =
false;
2072 List<List<pointIndexHit>> edHitsByFeature;
2076 const scalar searchRadiusSqr = edgeSearchDistCoeffSqr*cellSizeSqr;
2078 geometryToConformTo_.findAllNearestEdges
2086 forAll(edHitsByFeature, i)
2088 const label featureHit = featuresHit[i];
2090 List<pointIndexHit>& edHits = edHitsByFeature[i];
2103 && !decomposition().positionOnThisProcessor(edPt)
2110 if (!nearFeaturePt(edPt))
2115 < surfacePtReplaceDistCoeffSqr*cellSizeSqr
2125 keepSurfacePoint =
false;
2137 !nearFeatureEdgeLocation(edHit, nearestEdgeHit)
2140 appendToEdgeLocationTree(edPt);
2142 edgeToTreeShape.append
2144 existingEdgeLocations_.size() - 1
2149 featureEdgeHits.append
2151 pointIndexHitAndFeature(edHit, featureHit)
2157 surfacePtToEdgePtDist.insert
2159 existingEdgeLocations_.size() - 1,
2165 label hitIndex = nearestEdgeHit.index();
2172 < surfacePtToEdgePtDist[hitIndex]
2175 featureEdgeHits[hitIndex] =
2176 pointIndexHitAndFeature(edHit, featureHit);
2178 existingEdgeLocations_[hitIndex] =
2180 surfacePtToEdgePtDist[hitIndex] =
2186 edgeLocationTreePtr_().remove(hitIndex);
2187 edgeLocationTreePtr_().insert
2199 if (keepSurfacePoint)
2201 surfaceHits.append(surfHitI);
2202 appendToSurfacePtTree(surfPt);
2203 surfaceToTreeShape.append(existingSurfacePtLocations_.size() - 1);
2215 void Foam::conformalVoronoiMesh::storeSurfaceConformation()
2217 Info<<
nl <<
"Storing surface conformation" <<
endl;
2219 surfaceConformationVertices_.clear();
2222 DynamicList<Vb> tempSurfaceVertices(number_of_vertices()/10);
2226 Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
2227 vit != finite_vertices_end();
2236 && vit->boundaryPoint()
2237 && !vit->featurePoint()
2238 && !vit->constrained()
2241 tempSurfaceVertices.append
2254 tempSurfaceVertices.shrink();
2256 surfaceConformationVertices_.transfer(tempSurfaceVertices);
2261 label(surfaceConformationVertices_.size()),
2264 <<
" vertices" <<
nl <<
endl;
2268 void Foam::conformalVoronoiMesh::reinsertSurfaceConformation()
2270 Info<<
nl <<
"Reinserting stored surface conformation" <<
endl;
2272 Map<label> oldToNewIndices =
2273 insertPointPairs(surfaceConformationVertices_,
true,
true);
2275 ptPairs_.reIndex(oldToNewIndices);
2277 bitSet selectedElems(surfaceConformationVertices_.size(),
true);
2279 forAll(surfaceConformationVertices_, vI)
2281 Vb& v = surfaceConformationVertices_[vI];
2282 label& vIndex = v.
index();
2284 const auto iter = oldToNewIndices.cfind(vIndex);
2288 const label newIndex = *iter;
2296 selectedElems.unset(vI);
2301 inplaceSubset<bitSet, List<Vb>>
2304 surfaceConformationVertices_