ENH: improve distanceSurface handling (issue #1012)

- 'signed' input parameter only mandatory for distance > 0.
  A distance <= 0 is always signed and the input parameter is ignored.

- Use normal distance when distance == 0. This has no effect when
  the surface has no open edges, but improves on rounding issues
  around the zero crossing when the surface has open edges.

  This may still need future revisiting.
This commit is contained in:
Mark Olesen
2018-09-19 14:18:57 +02:00
parent 9973c378b9
commit 4aa94bd1d7
5 changed files with 59 additions and 27 deletions

View File

@ -68,8 +68,7 @@ Foam::distanceSurface::distanceSurface
distance_(dict.get<scalar>("distance")), distance_(dict.get<scalar>("distance")),
signed_ signed_
( (
// Always signed when distance = 0. distance_ < 0 || equal(distance_, Zero) || dict.get<bool>("signed")
dict.get<bool>("signed") || equal(distance_, Zero)
), ),
cell_(dict.lookupOrDefault("cell", true)), cell_(dict.lookupOrDefault("cell", true)),
regularise_(dict.lookupOrDefault("regularise", true)), regularise_(dict.lookupOrDefault("regularise", true)),
@ -113,8 +112,7 @@ Foam::distanceSurface::distanceSurface
distance_(distance), distance_(distance),
signed_ signed_
( (
// Always signed when distance = 0. signedDistance || distance_ < 0 || equal(distance_, Zero)
signedDistance || equal(distance_, Zero)
), ),
cell_(cell), cell_(cell),
regularise_(regularise), regularise_(regularise),
@ -148,7 +146,7 @@ void Foam::distanceSurface::createGeometry()
( (
IOobject IOobject
( (
"cellDistance", "distanceSurface.cellDistance",
fvm.time().timeName(), fvm.time().timeName(),
fvm.time(), fvm.time(),
IOobject::NO_READ, IOobject::NO_READ,
@ -164,7 +162,8 @@ void Foam::distanceSurface::createGeometry()
// For distance = 0 (and isoSurfaceCell) we apply additional filtering // For distance = 0 (and isoSurfaceCell) we apply additional filtering
// to limit the extent of open edges. // to limit the extent of open edges.
const bool filterCells = (cell_ && signed_ && equal(distance_, Zero)); const bool isZeroDist = equal(distance_, Zero);
const bool filterCells = (cell_ && isZeroDist);
bitSet ignoreCells; bitSet ignoreCells;
if (filterCells) if (filterCells)
@ -185,7 +184,7 @@ void Foam::distanceSurface::createGeometry()
nearest nearest
); );
if (signed_) if (signed_ || isZeroDist)
{ {
vectorField norms; vectorField norms;
surfPtr_().getNormal(nearest, norms); surfPtr_().getNormal(nearest, norms);
@ -196,7 +195,12 @@ void Foam::distanceSurface::createGeometry()
{ {
const point diff(cc[i] - nearest[i].hitPoint()); const point diff(cc[i] - nearest[i].hitPoint());
fld[i] = sign(diff & norms[i]) * Foam::mag(diff); fld[i] =
(
isZeroDist // Use normal distance
? (diff & norms[i])
: Foam::sign(diff & norms[i]) * Foam::mag(diff)
);
// Since cellPoints() is used in isoSurfaceCell too, // Since cellPoints() is used in isoSurfaceCell too,
// no additional overhead caused here // no additional overhead caused here
@ -250,7 +254,12 @@ void Foam::distanceSurface::createGeometry()
{ {
const point diff(cc[i] - nearest[i].hitPoint()); const point diff(cc[i] - nearest[i].hitPoint());
fld[i] = sign(diff & norms[i]) * Foam::mag(diff); fld[i] =
(
isZeroDist // Use normal distance
? (diff & norms[i])
: Foam::sign(diff & norms[i]) * Foam::mag(diff)
);
} }
} }
else else
@ -290,7 +299,12 @@ void Foam::distanceSurface::createGeometry()
{ {
const point diff(pts[i] - nearest[i].hitPoint()); const point diff(pts[i] - nearest[i].hitPoint());
pointDistance_[i] = sign(diff & norms[i]) * Foam::mag(diff); pointDistance_[i] =
(
isZeroDist // Use normal distance
? (diff & norms[i])
: Foam::sign(diff & norms[i]) * Foam::mag(diff)
);
} }
} }
else else
@ -311,7 +325,7 @@ void Foam::distanceSurface::createGeometry()
( (
IOobject IOobject
( (
"pointDistance", "distanceSurface.pointDistance",
fvm.time().timeName(), fvm.time().timeName(),
fvm.time(), fvm.time(),
IOobject::NO_READ, IOobject::NO_READ,

View File

@ -25,27 +25,28 @@ Class
Foam::distanceSurface Foam::distanceSurface
Description Description
A surface defined by distance to an input surface - using either A surface defined by a distance from an input searchable surface.
an isoSurfaceCell or an isoSurface. Uses an isoSurfaceCell or an isoSurface algorithm for constructing the
distance surface.
Usage Usage
Dictionary controls: Dictionary controls:
\table \table
Property | Description | Required | Default Property | Description | Required | Default
distance | distance from surface | yes | distance | distance from surface | yes |
signed | apply sign for +ve/-ve distance | yes | signed | Use sign when distance is positive | partly |
cell | use isoSurfaceCell algorithm | no | true cell | use isoSurfaceCell algorithm | no | true
regularise | point snapping | yes | regularise | Point snapping for iso-surface | yes |
bounds | limit with bounding box | no | bounds | Limit with bounding box | no |
surfaceType | type of surface | yes | surfaceType | Type of surface | yes |
surfaceName | name of surface in \c triSurface/ | no | dict name surfaceName | Name of surface in \c triSurface/ | no | dict name
\endtable \endtable
Note Note
Some special adjustments are undertaken for distance = 0. For distance = 0, some special adjustments.
- Always treated as signed (ignoring the input value), since it is - Always signed (ignoring the input value).
nearly impossible to generate any surface otherwise. - Use normal distance from surface (for better treatment of open edges).
- With the isoSurfaceCell algorithm is used, additional checks for open - When the isoSurfaceCell algorithm is used, additional checks for open
surfaces edges are used to limit the extend of resulting distance surfaces edges are used to limit the extend of resulting distance
surface. The resulting surface elements will not, however, contain surface. The resulting surface elements will not, however, contain
partial cell coverage. partial cell coverage.
@ -88,13 +89,13 @@ class distanceSurface
//- Signed distance //- Signed distance
const bool signed_; const bool signed_;
//- Whether to use isoSurfaceCell or isoSurface //- Use isoSurfaceCell (true) or isoSurface (false) algorithm
const bool cell_; const bool cell_;
//- Whether to coarsen //- Whether to coarsen iso-surface triangles
const bool regularise_; const bool regularise_;
//- Optional bounding box to trim triangles against //- Optional bounding box to trim against
const boundBox bounds_; const boundBox bounds_;
//- Distance to cell centres //- Distance to cell centres

View File

@ -1481,7 +1481,7 @@ Foam::isoSurface::isoSurface
( (
IOobject IOobject
( (
"cutType", "isoSurface.cutType",
fvm.time().timeName(), fvm.time().timeName(),
fvm.time(), fvm.time(),
IOobject::NO_READ, IOobject::NO_READ,

View File

@ -1342,7 +1342,7 @@ Foam::isoSurfaceCell::isoSurfaceCell
( (
IOobject IOobject
( (
"cutType", "isoSurfaceCell.cutType",
fvm.time().timeName(), fvm.time().timeName(),
fvm.time(), fvm.time(),
IOobject::NO_READ, IOobject::NO_READ,

View File

@ -42,6 +42,13 @@ debug
} }
} }
_disk1
{
surfaceType disk;
origin (-0.1 -0.05 0);
normal (1 1 1);
radius 0.015;
}
surfaces surfaces
( (
@ -55,6 +62,16 @@ debug
surfaceName angledPlane.obj; surfaceName angledPlane.obj;
} }
disk1
{
${_disk1}
type distanceSurface;
distance 0;
cell false;
signed true;
triangulate false;
}
iso iso
{ {
type isoSurface; type isoSurface;