mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: simplify distance calculation in distanceSurface
- use normal instead of volumeType to decide on the sign. This provides a continuous field and eliminates special handling of GREAT in iso-surface routines. - fix regression in isoSurfaceCell cutting that was introduced by the previous adjustments for distanceSurface
This commit is contained in:
@ -29,7 +29,6 @@ License
|
|||||||
#include "volPointInterpolation.H"
|
#include "volPointInterpolation.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
#include "fvMesh.H"
|
#include "fvMesh.H"
|
||||||
#include "volumeType.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -134,8 +133,6 @@ void Foam::distanceSurface::createGeometry()
|
|||||||
|
|
||||||
const fvMesh& fvm = static_cast<const fvMesh&>(mesh_);
|
const fvMesh& fvm = static_cast<const fvMesh&>(mesh_);
|
||||||
|
|
||||||
const labelList& own = fvm.faceOwner();
|
|
||||||
|
|
||||||
// Distance to cell centres
|
// Distance to cell centres
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@ -173,35 +170,14 @@ void Foam::distanceSurface::createGeometry()
|
|||||||
|
|
||||||
if (signed_)
|
if (signed_)
|
||||||
{
|
{
|
||||||
List<volumeType> volType;
|
vectorField norms;
|
||||||
|
surfPtr_().getNormal(nearest, norms);
|
||||||
|
|
||||||
surfPtr_().getVolumeType(cc, volType);
|
forAll(norms, i)
|
||||||
|
|
||||||
forAll(volType, i)
|
|
||||||
{
|
{
|
||||||
volumeType vT = volType[i];
|
const point diff(cc[i] - nearest[i].hitPoint());
|
||||||
|
|
||||||
if (vT == volumeType::OUTSIDE)
|
fld[i] = sign(diff & norms[i]) * Foam::mag(diff);
|
||||||
{
|
|
||||||
fld[i] = Foam::mag(cc[i] - nearest[i].hitPoint());
|
|
||||||
}
|
|
||||||
else if (vT == volumeType::INSIDE)
|
|
||||||
{
|
|
||||||
fld[i] = -Foam::mag(cc[i] - nearest[i].hitPoint());
|
|
||||||
}
|
|
||||||
else if (vT == volumeType::UNKNOWN)
|
|
||||||
{
|
|
||||||
// Treat as very far outside
|
|
||||||
fld[i] = GREAT;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "getVolumeType failure:"
|
|
||||||
<< " neither INSIDE or OUTSIDE but "
|
|
||||||
<< volumeType::names[vT]
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -223,9 +199,6 @@ void Foam::distanceSurface::createGeometry()
|
|||||||
const pointField& cc = fvm.C().boundaryField()[patchi];
|
const pointField& cc = fvm.C().boundaryField()[patchi];
|
||||||
fvPatchScalarField& fld = cellDistanceBf[patchi];
|
fvPatchScalarField& fld = cellDistanceBf[patchi];
|
||||||
|
|
||||||
const label patchStarti = fvm.boundaryMesh()[patchi].start();
|
|
||||||
|
|
||||||
|
|
||||||
List<pointIndexHit> nearest;
|
List<pointIndexHit> nearest;
|
||||||
surfPtr_().findNearest
|
surfPtr_().findNearest
|
||||||
(
|
(
|
||||||
@ -236,41 +209,14 @@ void Foam::distanceSurface::createGeometry()
|
|||||||
|
|
||||||
if (signed_)
|
if (signed_)
|
||||||
{
|
{
|
||||||
List<volumeType> volType;
|
vectorField norms;
|
||||||
|
surfPtr_().getNormal(nearest, norms);
|
||||||
|
|
||||||
surfPtr_().getVolumeType(cc, volType);
|
forAll(norms, i)
|
||||||
|
|
||||||
forAll(volType, i)
|
|
||||||
{
|
{
|
||||||
volumeType vT = volType[i];
|
const point diff(cc[i] - nearest[i].hitPoint());
|
||||||
|
|
||||||
if (vT == volumeType::OUTSIDE)
|
fld[i] = sign(diff & norms[i]) * Foam::mag(diff);
|
||||||
{
|
|
||||||
fld[i] = Foam::mag(cc[i] - nearest[i].hitPoint());
|
|
||||||
}
|
|
||||||
else if (vT == volumeType::INSIDE)
|
|
||||||
{
|
|
||||||
fld[i] = -Foam::mag(cc[i] - nearest[i].hitPoint());
|
|
||||||
}
|
|
||||||
else if (vT == volumeType::UNKNOWN)
|
|
||||||
{
|
|
||||||
// Nothing known, so use the cell value.
|
|
||||||
// - this avoids spurious changes on the boundary
|
|
||||||
|
|
||||||
// The cell value
|
|
||||||
const label meshFacei = i+patchStarti;
|
|
||||||
const scalar& cellVal = cellDistance[own[meshFacei]];
|
|
||||||
|
|
||||||
fld[i] = cellVal;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "getVolumeType failure:"
|
|
||||||
<< " neither INSIDE or OUTSIDE but "
|
|
||||||
<< volumeType::names[vT]
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -303,44 +249,21 @@ void Foam::distanceSurface::createGeometry()
|
|||||||
|
|
||||||
if (signed_)
|
if (signed_)
|
||||||
{
|
{
|
||||||
List<volumeType> volType;
|
vectorField norms;
|
||||||
|
surfPtr_().getNormal(nearest, norms);
|
||||||
|
|
||||||
surfPtr_().getVolumeType(pts, volType);
|
forAll(norms, i)
|
||||||
|
|
||||||
forAll(volType, i)
|
|
||||||
{
|
{
|
||||||
volumeType vT = volType[i];
|
const point diff(pts[i] - nearest[i].hitPoint());
|
||||||
|
|
||||||
if (vT == volumeType::OUTSIDE)
|
pointDistance_[i] = sign(diff & norms[i]) * Foam::mag(diff);
|
||||||
{
|
|
||||||
pointDistance_[i] =
|
|
||||||
Foam::mag(pts[i] - nearest[i].hitPoint());
|
|
||||||
}
|
|
||||||
else if (vT == volumeType::INSIDE)
|
|
||||||
{
|
|
||||||
pointDistance_[i] =
|
|
||||||
-Foam::mag(pts[i] - nearest[i].hitPoint());
|
|
||||||
}
|
|
||||||
else if (vT == volumeType::UNKNOWN)
|
|
||||||
{
|
|
||||||
// Treat as very far outside
|
|
||||||
pointDistance_[i] = GREAT;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "getVolumeType failure:"
|
|
||||||
<< " neither INSIDE or OUTSIDE but "
|
|
||||||
<< volumeType::names[vT]
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
forAll(nearest, i)
|
forAll(nearest, i)
|
||||||
{
|
{
|
||||||
pointDistance_[i] = Foam::mag(pts[i]-nearest[i].hitPoint());
|
pointDistance_[i] = Foam::mag(pts[i] - nearest[i].hitPoint());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,14 +60,6 @@ namespace Foam
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Avoid detecting change if the cells have been marked as GREAT
|
|
||||||
// (ie, ignore them)
|
|
||||||
static inline constexpr bool ignoreValue(const scalar val)
|
|
||||||
{
|
|
||||||
return (val >= 0.5*Foam::GREAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
@ -165,7 +157,7 @@ void Foam::isoSurface::syncUnseparatedPoints
|
|||||||
|
|
||||||
forAll(nbrPts, pointi)
|
forAll(nbrPts, pointi)
|
||||||
{
|
{
|
||||||
label nbrPointi = nbrPts[pointi];
|
const label nbrPointi = nbrPts[pointi];
|
||||||
patchInfo[nbrPointi] = pointValues[meshPts[pointi]];
|
patchInfo[nbrPointi] = pointValues[meshPts[pointi]];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,39 +306,19 @@ bool Foam::isoSurface::isEdgeOfFaceCut
|
|||||||
const bool neiLower
|
const bool neiLower
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
// Could also count number of edges cut and return when they are > 1
|
|
||||||
// but doesn't appear to improve anything
|
|
||||||
|
|
||||||
forAll(f, fp)
|
forAll(f, fp)
|
||||||
{
|
{
|
||||||
const scalar& pt0Value = pVals[f[fp]];
|
const bool fpLower = (pVals[f[fp]] < iso_);
|
||||||
|
|
||||||
if (ignoreValue(pt0Value))
|
if
|
||||||
|
(
|
||||||
|
fpLower != ownLower
|
||||||
|
|| fpLower != neiLower
|
||||||
|
|| fpLower != (pVals[f[f.fcIndex(fp)]] < iso_)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool fpLower = (pt0Value < iso_);
|
|
||||||
|
|
||||||
if (fpLower != ownLower || fpLower != neiLower)
|
|
||||||
{
|
|
||||||
// ++ncut;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
const scalar& pt1Value = pVals[f[f.fcIndex(fp)]];
|
|
||||||
|
|
||||||
if (!ignoreValue(pt1Value) && (fpLower != (pt1Value < iso_)))
|
|
||||||
{
|
|
||||||
// ++ncut;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if (ncut > 1)
|
|
||||||
// {
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -401,17 +373,9 @@ void Foam::isoSurface::calcCutTypes
|
|||||||
faceCutType_.setSize(mesh_.nFaces());
|
faceCutType_.setSize(mesh_.nFaces());
|
||||||
faceCutType_ = NOTCUT;
|
faceCutType_ = NOTCUT;
|
||||||
|
|
||||||
// Avoid detecting change if the cells have been marked as GREAT
|
|
||||||
// (ie, ignore them)
|
|
||||||
|
|
||||||
for (label facei = 0; facei < mesh_.nInternalFaces(); ++facei)
|
for (label facei = 0; facei < mesh_.nInternalFaces(); ++facei)
|
||||||
{
|
{
|
||||||
const scalar& ownValue = cVals[own[facei]];
|
const scalar& ownValue = cVals[own[facei]];
|
||||||
if (ignoreValue(ownValue))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool ownLower = (ownValue < iso_);
|
const bool ownLower = (ownValue < iso_);
|
||||||
|
|
||||||
scalar nbrValue;
|
scalar nbrValue;
|
||||||
@ -427,11 +391,6 @@ void Foam::isoSurface::calcCutTypes
|
|||||||
nbrPoint
|
nbrPoint
|
||||||
);
|
);
|
||||||
|
|
||||||
if (ignoreValue(nbrValue))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool neiLower = (nbrValue < iso_);
|
const bool neiLower = (nbrValue < iso_);
|
||||||
|
|
||||||
if (ownLower != neiLower)
|
if (ownLower != neiLower)
|
||||||
@ -503,7 +462,6 @@ void Foam::isoSurface::calcCutTypes
|
|||||||
|
|
||||||
|
|
||||||
// Propagate internal face cuts into the cells.
|
// Propagate internal face cuts into the cells.
|
||||||
// For cells marked as ignore (eg, GREAT) - skip this.
|
|
||||||
|
|
||||||
for (label facei = 0; facei < mesh_.nInternalFaces(); ++facei)
|
for (label facei = 0; facei < mesh_.nInternalFaces(); ++facei)
|
||||||
{
|
{
|
||||||
@ -512,20 +470,12 @@ void Foam::isoSurface::calcCutTypes
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if
|
if (cellCutType_[own[facei]] == NOTCUT)
|
||||||
(
|
|
||||||
cellCutType_[own[facei]] == NOTCUT
|
|
||||||
&& !ignoreValue(cVals[own[facei]])
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
cellCutType_[own[facei]] = CUT;
|
cellCutType_[own[facei]] = CUT;
|
||||||
++nCutCells_;
|
++nCutCells_;
|
||||||
}
|
}
|
||||||
if
|
if (cellCutType_[nei[facei]] == NOTCUT)
|
||||||
(
|
|
||||||
cellCutType_[nei[facei]] == NOTCUT
|
|
||||||
&& !ignoreValue(cVals[nei[facei]])
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
cellCutType_[nei[facei]] = CUT;
|
cellCutType_[nei[facei]] = CUT;
|
||||||
++nCutCells_;
|
++nCutCells_;
|
||||||
@ -534,8 +484,6 @@ void Foam::isoSurface::calcCutTypes
|
|||||||
|
|
||||||
|
|
||||||
// Propagate boundary face cuts into the cells.
|
// Propagate boundary face cuts into the cells.
|
||||||
// For cells marked as ignore (eg, GREAT) - skip this and
|
|
||||||
// also suppress the boundary face cut to prevent dangling face cuts.
|
|
||||||
|
|
||||||
for (label facei = mesh_.nInternalFaces(); facei < mesh_.nFaces(); ++facei)
|
for (label facei = mesh_.nInternalFaces(); facei < mesh_.nFaces(); ++facei)
|
||||||
{
|
{
|
||||||
@ -544,12 +492,7 @@ void Foam::isoSurface::calcCutTypes
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ignoreValue(cVals[own[facei]]))
|
if (cellCutType_[own[facei]] == NOTCUT)
|
||||||
{
|
|
||||||
// Suppress dangling boundary face cut
|
|
||||||
faceCutType_[facei] = NOTCUT;
|
|
||||||
}
|
|
||||||
else if (cellCutType_[own[facei]] == NOTCUT)
|
|
||||||
{
|
{
|
||||||
cellCutType_[own[facei]] = CUT;
|
cellCutType_[own[facei]] = CUT;
|
||||||
++nCutCells_;
|
++nCutCells_;
|
||||||
@ -774,10 +717,8 @@ void Foam::isoSurface::calcSnappedPoint
|
|||||||
|
|
||||||
bool anyCut = false;
|
bool anyCut = false;
|
||||||
|
|
||||||
forAll(pFaces, i)
|
for (const label facei : pFaces)
|
||||||
{
|
{
|
||||||
label facei = pFaces[i];
|
|
||||||
|
|
||||||
if (faceCutType_[facei] == CUT)
|
if (faceCutType_[facei] == CUT)
|
||||||
{
|
{
|
||||||
anyCut = true;
|
anyCut = true;
|
||||||
@ -795,12 +736,10 @@ void Foam::isoSurface::calcSnappedPoint
|
|||||||
label nOther = 0;
|
label nOther = 0;
|
||||||
point otherPointSum = Zero;
|
point otherPointSum = Zero;
|
||||||
|
|
||||||
forAll(pFaces, pFacei)
|
for (const label facei : pFaces)
|
||||||
{
|
{
|
||||||
// Create points for all intersections close to point
|
// Create points for all intersections close to point
|
||||||
// (i.e. from pyramid edges)
|
// (i.e. from pyramid edges)
|
||||||
|
|
||||||
label facei = pFaces[pFacei];
|
|
||||||
const face& f = mesh_.faces()[facei];
|
const face& f = mesh_.faces()[facei];
|
||||||
label own = mesh_.faceOwner()[facei];
|
label own = mesh_.faceOwner()[facei];
|
||||||
|
|
||||||
|
|||||||
@ -44,20 +44,6 @@ namespace Foam
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
// Avoid detecting change if the cells have been marked as GREAT
|
|
||||||
// (ie, ignore them)
|
|
||||||
static inline constexpr bool ignoreValue(const scalar val)
|
|
||||||
{
|
|
||||||
return (val >= 0.5*Foam::GREAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::scalar Foam::isoSurfaceCell::isoFraction
|
Foam::scalar Foam::isoSurfaceCell::isoFraction
|
||||||
@ -99,11 +85,6 @@ Foam::isoSurfaceCell::cellCutType Foam::isoSurfaceCell::calcCutType
|
|||||||
const label celli
|
const label celli
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
if (ignoreValue(cellValues[celli]))
|
|
||||||
{
|
|
||||||
return NOTCUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
const cell& cFaces = mesh_.cells()[celli];
|
const cell& cFaces = mesh_.cells()[celli];
|
||||||
|
|
||||||
if (isTet.test(celli))
|
if (isTet.test(celli))
|
||||||
@ -137,11 +118,7 @@ Foam::isoSurfaceCell::cellCutType Foam::isoSurfaceCell::calcCutType
|
|||||||
// Check pyramids cut
|
// Check pyramids cut
|
||||||
for (const label labi : f)
|
for (const label labi : f)
|
||||||
{
|
{
|
||||||
if
|
if (cellLower != (pointValues[labi] < iso_))
|
||||||
(
|
|
||||||
!ignoreValue(pointValues[labi])
|
|
||||||
&& cellLower != (pointValues[labi] < iso_)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
edgeCut = true;
|
edgeCut = true;
|
||||||
break;
|
break;
|
||||||
@ -187,11 +164,7 @@ Foam::isoSurfaceCell::cellCutType Foam::isoSurfaceCell::calcCutType
|
|||||||
|
|
||||||
for (const label pointi : cPoints)
|
for (const label pointi : cPoints)
|
||||||
{
|
{
|
||||||
if
|
if (cellLower != (pointValues[pointi] < iso_))
|
||||||
(
|
|
||||||
!ignoreValue(pointValues[pointi])
|
|
||||||
&& cellLower != (pointValues[pointi] < iso_)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
++nCuts;
|
++nCuts;
|
||||||
}
|
}
|
||||||
@ -201,7 +174,7 @@ Foam::isoSurfaceCell::cellCutType Foam::isoSurfaceCell::calcCutType
|
|||||||
{
|
{
|
||||||
return SPHERE;
|
return SPHERE;
|
||||||
}
|
}
|
||||||
else if (nCuts > 1)
|
else
|
||||||
{
|
{
|
||||||
return CUT;
|
return CUT;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user