From 705e4ec25766a3d52cbe6c57d47544a7c8b182a2 Mon Sep 17 00:00:00 2001 From: Konstantinos Date: Mon, 26 Feb 2024 16:44:38 +0100 Subject: [PATCH] levelset: check cell intersection by interecting its interfaces --- src/levelset/levelSetCommon.hpp | 4 ++- src/levelset/levelSetObject.cpp | 32 +++++++++++++++++++-- src/levelset/levelSetSegmentationObject.cpp | 8 +++++- src/levelset/levelSetSegmentationObject.hpp | 1 - 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/levelset/levelSetCommon.hpp b/src/levelset/levelSetCommon.hpp index da81d8a7d0..beda4ee5c1 100644 --- a/src/levelset/levelSetCommon.hpp +++ b/src/levelset/levelSetCommon.hpp @@ -119,7 +119,9 @@ enum class LevelSetIntersectionMode{ FAST_FUZZY=0, /**< Compares levelset value to tangent and bounding radius of a cell */ FAST_GUARANTEE_TRUE=1, /**< All LevelSetIntersectionStatus::TRUE are accurate but LevelSetIntersectionStatus::FALSE may be wrong */ FAST_GUARANTEE_FALSE=2, /**< All LevelSetIntersectionStatus::FALSE are accurate but LevelSetIntersectionStatus::TRUE may be wrong */ - ACCURATE=3 /**< Accurate but more costly checks */ + ACCURATE_LOW_ORDER=3, /**< Accurate but more costly checks. Handles the zero level set as planar. */ + ACCURATE_HIGH_ORDER=4, /**< Accurate but more costly checks. Takes into consideration the curvature of the zero level set surface */ + ACCURATE=ACCURATE_LOW_ORDER }; /*! diff --git a/src/levelset/levelSetObject.cpp b/src/levelset/levelSetObject.cpp index 13f8a93124..bf73d00c85 100644 --- a/src/levelset/levelSetObject.cpp +++ b/src/levelset/levelSetObject.cpp @@ -1406,12 +1406,17 @@ LevelSetIntersectionStatus LevelSetObject::_intersectInterfaceSurface(long id, i * larger than the bounding radius LevelSetIntersectionStatus::FALSE is returned, * otherwise LevelSetIntersectionStatus::TRUE. * - * If mode==LevelSetIntersectionMode::ACCURATE, the same checks of fuzzy mode are + * If mode==LevelSetIntersectionMode::ACCURATE_LOW_ORDER, the same checks of fuzzy mode are * performed, however, in the cases where fuzzy mode would return CLOSE, an additional * check on the intersection between the tangent plane at the projection point and the * cell is performed. Errors of the method are related to the ratio of surface curvature * over cell size. * + * If mode==LevelSetIntersectionMode::ACCURATE_HIGH_ORDER, the same checks of the low order + * accurate mode, but the curvature of the zero level set is accounted as well. Each interface + * evaluates its own distance from it. Also, this is the only mode taking into consideration + * possible high order smoothing of the surface. + * * The bounding sphere is the sphere with the minimum radius that contains all the * cell vertices and has the center in the cell centroid. * @@ -1470,7 +1475,7 @@ LevelSetIntersectionStatus LevelSetObject::_intersectCellSurface(long id, double break; } - case LevelSetIntersectionMode::ACCURATE: + case LevelSetIntersectionMode::ACCURATE_LOW_ORDER: { double boundingSphere = m_kernel->computeCellBoundingRadius(id) ; if(utils::DoubleFloatingGreater()(distance, boundingSphere, distanceTolerance, distanceTolerance)){ @@ -1492,6 +1497,29 @@ LevelSetIntersectionStatus LevelSetObject::_intersectCellSurface(long id, double break; } + + case LevelSetIntersectionMode::ACCURATE_HIGH_ORDER: + { + double boundingSphere = m_kernel->computeCellBoundingRadius(id) ; + if(utils::DoubleFloatingGreater()(distance, boundingSphere, distanceTolerance, distanceTolerance)){ + return LevelSetIntersectionStatus::FALSE; + } + + double tangentSphere = m_kernel->computeCellTangentRadius(id) ; + if(utils::DoubleFloatingLessEqual()(distance, tangentSphere, distanceTolerance, distanceTolerance)){ + return LevelSetIntersectionStatus::TRUE; + } + + int nInterfaces = m_kernel->getMesh()->getCell(id).getInterfaceCount(); + for (int i = 0; i < nInterfaces; ++i) { + if (_intersectInterfaceSurface(id, i, distanceTolerance) == LevelSetIntersectionStatus::TRUE) { + return LevelSetIntersectionStatus::TRUE; + } + } + return LevelSetIntersectionStatus::FALSE; + + break; + } } BITPIT_UNREACHABLE("cannot reach"); diff --git a/src/levelset/levelSetSegmentationObject.cpp b/src/levelset/levelSetSegmentationObject.cpp index c75a16906b..a52a5bfc80 100644 --- a/src/levelset/levelSetSegmentationObject.cpp +++ b/src/levelset/levelSetSegmentationObject.cpp @@ -1725,12 +1725,18 @@ LevelSetIntersectionStatus LevelSetSegmentationBaseObject::evalIntersectedInterf * larger than the bounding radius LevelSetIntersectionStatus::FALSE is returned, * otherwise LevelSetIntersectionStatus::TRUE. * - * If mode==LevelSetIntersectionMode::ACCURATE, the same checks of fuzzy mode are + * If mode==LevelSetIntersectionMode::ACCURATE_LOW_ORDER, the same checks of fuzzy mode are * performed, however, in the cases where fuzzy mode would return CLOSE, an additional * check on the intersection between the tangent plane at the projection point and the * cell is performed. Errors of the method are related to the ratio of surface curvature * over cell size. * + * If mode==LevelSetIntersectionMode::ACCURATE_HIGH_ORDER, the same checks of the low order + * accurate mode, but the curvature of the zero level set is accounted as well. Each interface + * evaluates its own distance from it. Also, this is the only mode taking into consideration + * possible high order smoothing of the surface. + * + * * The bounding sphere is the sphere with the minimum radius that contains all the * cell vertices and has the center in the cell centroid. * diff --git a/src/levelset/levelSetSegmentationObject.hpp b/src/levelset/levelSetSegmentationObject.hpp index c64db2b971..fef8518a0b 100644 --- a/src/levelset/levelSetSegmentationObject.hpp +++ b/src/levelset/levelSetSegmentationObject.hpp @@ -208,7 +208,6 @@ class LevelSetSegmentationObject : public LevelSetSegmentationBaseObject { void setSurface(const SurfUnstructured *surface, bool force = false); void setSurface(const SurfUnstructured *surface, double featureAngle, bool force = false); void setSurface(const SurfUnstructured *surface, double featureAngle, LevelSetSurfaceSmoothing surfaceSmoothing, bool force = false); - void setSurface(const SurfUnstructured *surface, double featureAngle, LevelSetSurfaceSmoothing surfaceSmoothing); const SurfaceSkdTree & getSearchTree() const;