mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: support zone and zones for sampled cutting planes, sampledIsoSurface
- rework to use bitSet for more flexibility
This commit is contained in:
@ -108,7 +108,7 @@ void Foam::sampledIsoSurface::getIsoFields() const
|
||||
fvm
|
||||
)
|
||||
);
|
||||
volFieldPtr_ = storedVolFieldPtr_.operator->();
|
||||
volFieldPtr_ = storedVolFieldPtr_.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -132,7 +132,7 @@ void Foam::sampledIsoSurface::getIsoFields() const
|
||||
// (volPointInterpolation::interpolate with cache=false deletes any
|
||||
// registered one or if mesh.changing())
|
||||
|
||||
if (!subMeshPtr_.valid())
|
||||
if (subMeshPtr_.empty())
|
||||
{
|
||||
const word pointFldName =
|
||||
"volPointInterpolate_"
|
||||
@ -200,8 +200,8 @@ void Foam::sampledIsoSurface::getIsoFields() const
|
||||
}
|
||||
|
||||
|
||||
// If averaging redo the volField. Can only be done now since needs the
|
||||
// point field.
|
||||
// If averaging redo the volField.
|
||||
// Can only be done now since needs the point field.
|
||||
if (average_)
|
||||
{
|
||||
storedVolFieldPtr_.reset
|
||||
@ -261,7 +261,7 @@ void Foam::sampledIsoSurface::getIsoFields() const
|
||||
}
|
||||
|
||||
|
||||
// Pointfield on submesh
|
||||
// The point field on subMesh
|
||||
|
||||
const word pointFldName =
|
||||
"volPointInterpolate_"
|
||||
@ -360,30 +360,30 @@ bool Foam::sampledIsoSurface::updateGeometry() const
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get any subMesh
|
||||
if (zoneID_.index() != -1 && !subMeshPtr_.valid())
|
||||
// Get sub-mesh if any
|
||||
if
|
||||
(
|
||||
(-1 != mesh().cellZones().findIndex(zoneNames_))
|
||||
&& subMeshPtr_.empty()
|
||||
)
|
||||
{
|
||||
const polyBoundaryMesh& patches = mesh().boundaryMesh();
|
||||
|
||||
// Patch to put exposed internal faces into
|
||||
const label exposedPatchi = patches.findPatchID(exposedPatchName_);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Allocating subset of size "
|
||||
<< mesh().cellZones()[zoneID_.index()].size()
|
||||
<< " with exposed faces into patch "
|
||||
<< patches[exposedPatchi].name() << endl;
|
||||
}
|
||||
DebugInfo
|
||||
<< "Allocating subset of size "
|
||||
<< mesh().cellZones().selection(zoneNames_).count()
|
||||
<< " with exposed faces into patch "
|
||||
<< patches[exposedPatchi].name() << endl;
|
||||
|
||||
// Remove old mesh if any
|
||||
subMeshPtr_.clear();
|
||||
subMeshPtr_.reset
|
||||
(
|
||||
new fvMeshSubset
|
||||
(
|
||||
fvm,
|
||||
mesh().cellZones()[zoneID_.index()],
|
||||
mesh().cellZones().selection(zoneNames_),
|
||||
exposedPatchi
|
||||
)
|
||||
);
|
||||
@ -474,8 +474,8 @@ Foam::sampledIsoSurface::sampledIsoSurface
|
||||
mergeTol_(dict.lookupOrDefault("mergeTol", 1e-6)),
|
||||
regularise_(dict.lookupOrDefault("regularise", true)),
|
||||
average_(dict.lookupOrDefault("average", false)),
|
||||
zoneID_(dict.lookupOrDefault("zone", word::null), mesh.cellZones()),
|
||||
exposedPatchName_(word::null),
|
||||
zoneNames_(),
|
||||
exposedPatchName_(),
|
||||
surfPtr_(nullptr),
|
||||
prevTimeIndex_(-1),
|
||||
storedVolFieldPtr_(nullptr),
|
||||
@ -491,27 +491,30 @@ Foam::sampledIsoSurface::sampledIsoSurface
|
||||
<< " span across cells." << exit(FatalIOError);
|
||||
}
|
||||
|
||||
if (zoneID_.index() != -1)
|
||||
|
||||
if (!dict.readIfPresent("zones", zoneNames_) && dict.found("zone"))
|
||||
{
|
||||
zoneNames_.resize(1);
|
||||
dict.readEntry("zone", zoneNames_.first());
|
||||
}
|
||||
|
||||
if (-1 != mesh.cellZones().findIndex(zoneNames_))
|
||||
{
|
||||
dict.readEntry("exposedPatchName", exposedPatchName_);
|
||||
|
||||
if (mesh.boundaryMesh().findPatchID(exposedPatchName_) == -1)
|
||||
{
|
||||
FatalIOErrorInFunction
|
||||
(
|
||||
dict
|
||||
) << "Cannot find patch " << exposedPatchName_
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Cannot find patch " << exposedPatchName_
|
||||
<< " in which to put exposed faces." << endl
|
||||
<< "Valid patches are " << mesh.boundaryMesh().names()
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
if (debug && zoneID_.index() != -1)
|
||||
{
|
||||
Info<< "Restricting to cellZone " << zoneID_.name()
|
||||
<< " with exposed internal faces into patch "
|
||||
<< exposedPatchName_ << endl;
|
||||
}
|
||||
DebugInfo
|
||||
<< "Restricting to cellZone(s) " << flatOutput(zoneNames_)
|
||||
<< " with exposed internal faces into patch "
|
||||
<< exposedPatchName_ << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -54,7 +54,8 @@ Usage
|
||||
regularise | point snapping | yes |
|
||||
average | cell values from averaged point values | no | false
|
||||
bounds | limit with bounding box | no |
|
||||
zone | limit to specified zone | no |
|
||||
zone | limit to cell zone (name or regex) | no |
|
||||
zones | limit to cell zones (names, regexs) | no |
|
||||
exposedPatchName | name for zone subset | partly |
|
||||
\endtable
|
||||
|
||||
@ -68,7 +69,6 @@ SourceFiles
|
||||
|
||||
#include "isoSurface.H"
|
||||
#include "sampledSurface.H"
|
||||
#include "ZoneIDs.H"
|
||||
#include "fvMeshSubset.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -104,8 +104,8 @@ class sampledIsoSurface
|
||||
//- Whether to recalculate cell values as average of point values
|
||||
const bool average_;
|
||||
|
||||
//- Zone name/index (if restricted to zones)
|
||||
mutable cellZoneID zoneID_;
|
||||
//- The zone or zones for the iso-surface
|
||||
wordRes zoneNames_;
|
||||
|
||||
//- For zones: patch to put exposed faces into
|
||||
mutable word exposedPatchName_;
|
||||
|
||||
@ -201,7 +201,6 @@ Foam::sampledIsoSurfaceCell::sampledIsoSurfaceCell
|
||||
bounds_(dict.lookupOrDefault("bounds", boundBox::invertedBox)),
|
||||
regularise_(dict.lookupOrDefault("regularise", true)),
|
||||
average_(dict.lookupOrDefault("average", true)),
|
||||
zoneKey_(keyType::null),
|
||||
prevTimeIndex_(-1),
|
||||
meshCells_()
|
||||
{}
|
||||
|
||||
@ -56,6 +56,9 @@ Usage
|
||||
bounds | limit with bounding box | no |
|
||||
\endtable
|
||||
|
||||
Note
|
||||
Does not currently support cell zones.
|
||||
|
||||
SourceFiles
|
||||
sampledIsoSurfaceCell.C
|
||||
|
||||
@ -102,9 +105,6 @@ class sampledIsoSurfaceCell
|
||||
//- Whether to recalculate cell values as average of point values
|
||||
const bool average_;
|
||||
|
||||
//- If restricted to zones, name of this zone or a regular expression
|
||||
keyType zoneKey_;
|
||||
|
||||
|
||||
// Recreated for every isoSurface
|
||||
|
||||
|
||||
@ -46,6 +46,51 @@ namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::sampledCuttingPlane::checkBoundsIntersection
|
||||
(
|
||||
const plane& pln,
|
||||
const boundBox& meshBb
|
||||
) const
|
||||
{
|
||||
// Verify specified bounding box
|
||||
if (!bounds_.empty())
|
||||
{
|
||||
// Bounding box does not overlap with (global) mesh!
|
||||
if (!bounds_.overlaps(meshBb))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Bounds " << bounds_
|
||||
<< " do not overlap the mesh bounding box " << meshBb
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
// Plane does not intersect the bounding box
|
||||
if (!bounds_.intersects(pln))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Plane "<< pln << " does not intersect the bounds "
|
||||
<< bounds_
|
||||
<< nl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Plane does not intersect the (global) mesh!
|
||||
if (!meshBb.intersects(pln))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Plane "<< pln << " does not intersect the mesh bounds "
|
||||
<< meshBb
|
||||
<< nl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::sampledCuttingPlane::createGeometry()
|
||||
{
|
||||
if (debug)
|
||||
@ -62,29 +107,51 @@ void Foam::sampledCuttingPlane::createGeometry()
|
||||
// Clear derived data
|
||||
clearGeom();
|
||||
|
||||
// Get any subMesh
|
||||
if (zoneID_.index() != -1 && !subMeshPtr_.valid())
|
||||
const fvMesh& fvm = static_cast<const fvMesh&>(this->mesh());
|
||||
|
||||
// Get sub-mesh if any
|
||||
if
|
||||
(
|
||||
(-1 != mesh().cellZones().findIndex(zoneNames_))
|
||||
&& subMeshPtr_.empty()
|
||||
)
|
||||
{
|
||||
const polyBoundaryMesh& patches = mesh().boundaryMesh();
|
||||
|
||||
// Patch to put exposed internal faces into
|
||||
const label exposedPatchi = patches.findPatchID(exposedPatchName_);
|
||||
|
||||
bitSet cellsToSelect = mesh().cellZones().selection(zoneNames_);
|
||||
|
||||
DebugInfo
|
||||
<< "Allocating subset of size "
|
||||
<< mesh().cellZones()[zoneID_.index()].size()
|
||||
<< cellsToSelect.count()
|
||||
<< " with exposed faces into patch "
|
||||
<< patches[exposedPatchi].name() << endl;
|
||||
|
||||
subMeshPtr_.reset
|
||||
(
|
||||
new fvMeshSubset
|
||||
(
|
||||
static_cast<const fvMesh&>(mesh()),
|
||||
mesh().cellZones()[zoneID_.index()],
|
||||
exposedPatchi
|
||||
)
|
||||
);
|
||||
|
||||
// If we will use a fvMeshSubset so can apply bounds as well to make
|
||||
// the initial selection smaller.
|
||||
if (!bounds_.empty() && cellsToSelect.any())
|
||||
{
|
||||
const auto& cellCentres = fvm.C();
|
||||
|
||||
for (const label celli : cellsToSelect)
|
||||
{
|
||||
const point& cc = cellCentres[celli];
|
||||
|
||||
if (!bounds_.contains(cc))
|
||||
{
|
||||
cellsToSelect.unset(celli);
|
||||
}
|
||||
}
|
||||
|
||||
DebugInfo
|
||||
<< "Bounded subset of size "
|
||||
<< cellsToSelect.count() << endl;
|
||||
}
|
||||
|
||||
subMeshPtr_.reset(new fvMeshSubset(fvm, cellsToSelect, exposedPatchi));
|
||||
}
|
||||
|
||||
|
||||
@ -93,9 +160,11 @@ void Foam::sampledCuttingPlane::createGeometry()
|
||||
(
|
||||
subMeshPtr_.valid()
|
||||
? subMeshPtr_().subMesh()
|
||||
: static_cast<const fvMesh&>(this->mesh())
|
||||
: fvm
|
||||
);
|
||||
|
||||
checkBoundsIntersection(plane_, mesh.bounds());
|
||||
|
||||
|
||||
// Distance to cell centres
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -121,7 +190,7 @@ void Foam::sampledCuttingPlane::createGeometry()
|
||||
|
||||
// Internal field
|
||||
{
|
||||
const pointField& cc = mesh.cellCentres();
|
||||
const auto& cc = mesh.cellCentres();
|
||||
scalarField& fld = cellDistance.primitiveFieldRef();
|
||||
|
||||
forAll(cc, i)
|
||||
@ -167,6 +236,7 @@ void Foam::sampledCuttingPlane::createGeometry()
|
||||
}
|
||||
else
|
||||
{
|
||||
// Other side cell centres?
|
||||
const pointField& cc = mesh.C().boundaryField()[patchi];
|
||||
fvPatchScalarField& fld = cellDistanceBf[patchi];
|
||||
|
||||
@ -242,43 +312,6 @@ void Foam::sampledCuttingPlane::createGeometry()
|
||||
//)
|
||||
);
|
||||
|
||||
// Verify specified bounding box
|
||||
if (!bounds_.empty())
|
||||
{
|
||||
// Bounding box does not overlap with (global) mesh!
|
||||
if (!bounds_.overlaps(mesh.bounds()))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Bounds " << bounds_
|
||||
<< " do not overlap the mesh bounding box " << mesh.bounds()
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
// Plane does not intersect the bounding box
|
||||
if (!bounds_.intersects(plane_))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Plane "<< plane_ << " does not intersect the bounds "
|
||||
<< bounds_
|
||||
<< nl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Plane does not intersect the (global) mesh!
|
||||
if (!mesh.bounds().intersects(plane_))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Plane "<< plane_ << " does not intersect the mesh bounds "
|
||||
<< mesh.bounds()
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
print(Pout);
|
||||
@ -302,32 +335,36 @@ Foam::sampledCuttingPlane::sampledCuttingPlane
|
||||
mergeTol_(dict.lookupOrDefault("mergeTol", 1e-6)),
|
||||
regularise_(dict.lookupOrDefault("regularise", true)),
|
||||
average_(dict.lookupOrDefault("average", false)),
|
||||
zoneID_(dict.lookupOrDefault("zone", word::null), mesh.cellZones()),
|
||||
exposedPatchName_(word::null),
|
||||
zoneNames_(),
|
||||
exposedPatchName_(),
|
||||
needsUpdate_(true),
|
||||
subMeshPtr_(nullptr),
|
||||
cellDistancePtr_(nullptr),
|
||||
isoSurfPtr_(nullptr)
|
||||
{
|
||||
if (zoneID_.index() != -1)
|
||||
if (!dict.readIfPresent("zones", zoneNames_) && dict.found("zone"))
|
||||
{
|
||||
zoneNames_.resize(1);
|
||||
dict.readEntry("zone", zoneNames_.first());
|
||||
}
|
||||
|
||||
if (-1 != mesh.cellZones().findIndex(zoneNames_))
|
||||
{
|
||||
dict.readEntry("exposedPatchName", exposedPatchName_);
|
||||
|
||||
if (mesh.boundaryMesh().findPatchID(exposedPatchName_) == -1)
|
||||
if (-1 == mesh.boundaryMesh().findPatchID(exposedPatchName_))
|
||||
{
|
||||
FatalErrorInFunction
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Cannot find patch " << exposedPatchName_
|
||||
<< " in which to put exposed faces." << endl
|
||||
<< "Valid patches are " << mesh.boundaryMesh().names()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
if (debug && zoneID_.index() != -1)
|
||||
{
|
||||
Info<< "Restricting to cellZone " << zoneID_.name()
|
||||
<< " with exposed internal faces into patch "
|
||||
<< exposedPatchName_ << endl;
|
||||
}
|
||||
DebugInfo
|
||||
<< "Restricting to cellZone(s) " << flatOutput(zoneNames_)
|
||||
<< " with exposed internal faces into patch "
|
||||
<< exposedPatchName_ << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -55,10 +55,14 @@ Usage
|
||||
mergeTol | tolerance for merging points | no | 1e-6
|
||||
regularise | point snapping | no | true
|
||||
bounds | limit with bounding box | no |
|
||||
zone | limit to specified zone | no |
|
||||
zone | limit to cell zone (name or regex) | no |
|
||||
zones | limit to cell zones (names, regexs) | no |
|
||||
exposedPatchName | name for zone subset | partly |
|
||||
\endtable
|
||||
|
||||
Note
|
||||
The keyword \c zones has priority over \c zone.
|
||||
|
||||
SeeAlso
|
||||
Foam::plane
|
||||
|
||||
@ -74,7 +78,6 @@ SourceFiles
|
||||
#include "isoSurface.H"
|
||||
//#include "isoSurfaceCell.H"
|
||||
#include "plane.H"
|
||||
#include "ZoneIDs.H"
|
||||
#include "fvMeshSubset.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -107,8 +110,8 @@ class sampledCuttingPlane
|
||||
//- Whether to recalculate cell values as average of point values
|
||||
const bool average_;
|
||||
|
||||
//- Zone name/index (if restricted to zones)
|
||||
mutable cellZoneID zoneID_;
|
||||
//- The zone or zones in which cutting is to occur
|
||||
wordRes zoneNames_;
|
||||
|
||||
//- For zones: patch to put exposed faces into
|
||||
mutable word exposedPatchName_;
|
||||
@ -117,7 +120,7 @@ class sampledCuttingPlane
|
||||
mutable bool needsUpdate_;
|
||||
|
||||
|
||||
//- Optional subsetted mesh
|
||||
//- Mesh subset (optional: only used with zones)
|
||||
autoPtr<fvMeshSubset> subMeshPtr_;
|
||||
|
||||
//- Distance to cell centres
|
||||
@ -133,6 +136,13 @@ class sampledCuttingPlane
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Check and warn if bounding box does not intersect mesh or plane
|
||||
void checkBoundsIntersection
|
||||
(
|
||||
const plane& pln,
|
||||
const boundBox& meshBb
|
||||
) const;
|
||||
|
||||
//- Create iso surface
|
||||
void createGeometry();
|
||||
|
||||
|
||||
@ -44,6 +44,159 @@ namespace Foam
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::sampledPlane::checkBoundsIntersection
|
||||
(
|
||||
const plane& pln,
|
||||
const boundBox& meshBb
|
||||
) const
|
||||
{
|
||||
// Verify specified bounding box
|
||||
if (!bounds_.empty())
|
||||
{
|
||||
// Bounding box does not overlap with (global) mesh!
|
||||
if (!bounds_.overlaps(meshBb))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Bounds " << bounds_
|
||||
<< " do not overlap the mesh bounding box " << meshBb
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
// Plane does not intersect the bounding box
|
||||
if (!bounds_.intersects(pln))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Plane "<< pln << " does not intersect the bounds "
|
||||
<< bounds_
|
||||
<< nl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Plane does not intersect the (global) mesh!
|
||||
if (!meshBb.intersects(pln))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Plane "<< pln << " does not intersect the mesh bounds "
|
||||
<< meshBb
|
||||
<< nl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::bitSet Foam::sampledPlane::cellSelection
|
||||
(
|
||||
const bool warnIntersect
|
||||
) const
|
||||
{
|
||||
// Zones requested and in use?
|
||||
const bool hasZones =
|
||||
returnReduce
|
||||
(
|
||||
(-1 != mesh().cellZones().findIndex(zoneNames_)),
|
||||
andOp<bool>()
|
||||
);
|
||||
|
||||
|
||||
bitSet cellsToSelect;
|
||||
|
||||
if (hasZones)
|
||||
{
|
||||
cellsToSelect = mesh().cellZones().selection(zoneNames_);
|
||||
}
|
||||
|
||||
|
||||
// Subset the zoned cells with the bounds_.
|
||||
// For a full mesh, use the bounds to define the cell selection.
|
||||
|
||||
// If there are zones cells, use them to build the effective mesh
|
||||
// bound box.
|
||||
// Note that for convenience we use cell centres here instead of the
|
||||
// cell points, since it will only be used for checking.
|
||||
|
||||
boundBox meshBb;
|
||||
|
||||
if (bounds_.empty())
|
||||
{
|
||||
// No bounds restriction, but will need the effective mesh boundBox
|
||||
// for checking intersections
|
||||
|
||||
if (hasZones && warnIntersect)
|
||||
{
|
||||
const auto& cellCentres = static_cast<const fvMesh&>(mesh()).C();
|
||||
|
||||
for (const label celli : cellsToSelect)
|
||||
{
|
||||
const point& cc = cellCentres[celli];
|
||||
|
||||
meshBb.add(cc);
|
||||
}
|
||||
|
||||
meshBb.reduce();
|
||||
}
|
||||
else
|
||||
{
|
||||
meshBb = mesh().bounds(); // use the regular mesh bounding box
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& cellCentres = static_cast<const fvMesh&>(mesh()).C();
|
||||
|
||||
// Only examine cells already set
|
||||
if (hasZones)
|
||||
{
|
||||
for (const label celli : cellsToSelect)
|
||||
{
|
||||
const point& cc = cellCentres[celli];
|
||||
|
||||
meshBb.add(cc);
|
||||
|
||||
if (!bounds_.contains(cc))
|
||||
{
|
||||
cellsToSelect.unset(celli);
|
||||
}
|
||||
}
|
||||
|
||||
meshBb.reduce();
|
||||
}
|
||||
else
|
||||
{
|
||||
const label len = mesh().nCells();
|
||||
|
||||
cellsToSelect.resize(len);
|
||||
|
||||
for (label celli=0; celli < len; ++celli)
|
||||
{
|
||||
const point& cc = cellCentres[celli];
|
||||
|
||||
if (bounds_.contains(cc))
|
||||
{
|
||||
cellsToSelect.set(celli);
|
||||
}
|
||||
}
|
||||
|
||||
meshBb = mesh().bounds(); // use the regular mesh bounding box
|
||||
}
|
||||
}
|
||||
|
||||
if (warnIntersect)
|
||||
{
|
||||
checkBoundsIntersection(*this, meshBb);
|
||||
}
|
||||
|
||||
return cellsToSelect;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::sampledPlane::sampledPlane
|
||||
@ -51,21 +204,29 @@ Foam::sampledPlane::sampledPlane
|
||||
const word& name,
|
||||
const polyMesh& mesh,
|
||||
const plane& planeDesc,
|
||||
const keyType& zoneKey,
|
||||
const wordRes& zones,
|
||||
const bool triangulate
|
||||
)
|
||||
:
|
||||
sampledSurface(name, mesh),
|
||||
cuttingPlane(planeDesc),
|
||||
zoneKey_(zoneKey),
|
||||
zoneNames_(zones),
|
||||
bounds_(),
|
||||
triangulate_(triangulate),
|
||||
needsUpdate_(true)
|
||||
{
|
||||
if (debug && zoneKey_.size() && mesh.cellZones().findIndex(zoneKey_) == -1)
|
||||
if (debug)
|
||||
{
|
||||
Info<< "cellZone(s) " << zoneKey_
|
||||
<< " not found - using entire mesh" << endl;
|
||||
if (!zoneNames_.empty())
|
||||
{
|
||||
Info<< " cellZones " << flatOutput(zoneNames_);
|
||||
|
||||
if (-1 == mesh.cellZones().findIndex(zoneNames_))
|
||||
{
|
||||
Info<< " not found!";
|
||||
}
|
||||
Info<< endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,28 +240,61 @@ Foam::sampledPlane::sampledPlane
|
||||
:
|
||||
sampledSurface(name, mesh, dict),
|
||||
cuttingPlane(plane(dict)),
|
||||
zoneKey_(dict.lookupOrDefault<keyType>("zone", keyType::null)),
|
||||
zoneNames_(),
|
||||
bounds_(dict.lookupOrDefault("bounds", boundBox::invertedBox)),
|
||||
triangulate_(dict.lookupOrDefault("triangulate", true)),
|
||||
needsUpdate_(true)
|
||||
{
|
||||
if (!dict.readIfPresent("zones", zoneNames_) && dict.found("zone"))
|
||||
{
|
||||
zoneNames_.resize(1);
|
||||
dict.readEntry("zone", zoneNames_.first());
|
||||
}
|
||||
|
||||
|
||||
// Make plane relative to the coordinateSystem (Cartesian)
|
||||
// allow lookup from global coordinate systems
|
||||
if (dict.found("coordinateSystem"))
|
||||
{
|
||||
coordinateSystem cs(mesh, dict.subDict("coordinateSystem"));
|
||||
|
||||
const point base = cs.globalPosition(planeDesc().origin());
|
||||
const point orig = cs.globalPosition(planeDesc().origin());
|
||||
const vector norm = cs.globalVector(planeDesc().normal());
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "plane " << name << " :"
|
||||
<< " origin:" << origin()
|
||||
<< " normal:" << normal()
|
||||
<< " defined within a local coordinateSystem" << endl;
|
||||
}
|
||||
|
||||
// Assign the plane description
|
||||
static_cast<plane&>(*this) = plane(base, norm);
|
||||
static_cast<plane&>(*this) = plane(orig, norm);
|
||||
}
|
||||
|
||||
if (debug && zoneKey_.size() && mesh.cellZones().findIndex(zoneKey_) == -1)
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "cellZone(s) " << zoneKey_
|
||||
<< " not found - using entire mesh" << endl;
|
||||
Info<< "plane " << name << " :"
|
||||
<< " origin:" << origin()
|
||||
<< " normal:" << normal();
|
||||
|
||||
if (!bounds_.empty())
|
||||
{
|
||||
Info<< " bounds:" << bounds_;
|
||||
}
|
||||
|
||||
if (!zoneNames_.empty())
|
||||
{
|
||||
Info<< " cellZones " << flatOutput(zoneNames_);
|
||||
|
||||
if (-1 == mesh.cellZones().findIndex(zoneNames_))
|
||||
{
|
||||
Info<< " not found!";
|
||||
}
|
||||
}
|
||||
Info<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,99 +331,7 @@ bool Foam::sampledPlane::update()
|
||||
|
||||
sampledSurface::clearGeom();
|
||||
|
||||
const plane& pln = static_cast<const plane&>(*this);
|
||||
|
||||
// Verify specified bounding box
|
||||
if (!bounds_.empty())
|
||||
{
|
||||
// Bounding box does not overlap with (global) mesh!
|
||||
if (!bounds_.overlaps(mesh().bounds()))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Bounds " << bounds_
|
||||
<< " do not overlap the mesh bounding box " << mesh().bounds()
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
// Plane does not intersect the bounding box
|
||||
if (!bounds_.intersects(pln))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Plane "<< pln << " does not intersect the bounds "
|
||||
<< bounds_
|
||||
<< nl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Plane does not intersect the (global) mesh!
|
||||
if (!mesh().bounds().intersects(pln))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Plane "<< pln << " does not intersect the mesh bounds "
|
||||
<< mesh().bounds()
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
|
||||
labelList selectedCells
|
||||
(
|
||||
mesh().cellZones().selection(zoneKey_).sortedToc()
|
||||
);
|
||||
|
||||
bool fullMesh = returnReduce(selectedCells.empty(), andOp<bool>());
|
||||
|
||||
if (!bounds_.empty())
|
||||
{
|
||||
const auto& cellCentres = static_cast<const fvMesh&>(mesh()).C();
|
||||
|
||||
if (fullMesh)
|
||||
{
|
||||
const label len = mesh().nCells();
|
||||
|
||||
selectedCells.setSize(len);
|
||||
|
||||
label count = 0;
|
||||
for (label celli=0; celli < len; ++celli)
|
||||
{
|
||||
if (bounds_.contains(cellCentres[celli]))
|
||||
{
|
||||
selectedCells[count++] = celli;
|
||||
}
|
||||
}
|
||||
|
||||
selectedCells.setSize(count);
|
||||
}
|
||||
else
|
||||
{
|
||||
label count = 0;
|
||||
for (const label celli : selectedCells)
|
||||
{
|
||||
if (bounds_.contains(cellCentres[celli]))
|
||||
{
|
||||
selectedCells[count++] = celli;
|
||||
}
|
||||
}
|
||||
|
||||
selectedCells.setSize(count);
|
||||
}
|
||||
|
||||
fullMesh = false;
|
||||
}
|
||||
|
||||
if (fullMesh)
|
||||
{
|
||||
reCut(mesh(), triangulate_);
|
||||
}
|
||||
else
|
||||
{
|
||||
reCut(mesh(), triangulate_, selectedCells);
|
||||
}
|
||||
performCut(mesh(), triangulate_, this->cellSelection(true));
|
||||
|
||||
if (debug)
|
||||
{
|
||||
@ -334,11 +436,11 @@ Foam::tmp<Foam::tensorField> Foam::sampledPlane::interpolate
|
||||
void Foam::sampledPlane::print(Ostream& os) const
|
||||
{
|
||||
os << "sampledPlane: " << name() << " :"
|
||||
<< " base:" << plane::origin()
|
||||
<< " normal:" << plane::normal()
|
||||
<< " triangulate:" << triangulate_
|
||||
<< " faces:" << faces().size()
|
||||
<< " points:" << points().size();
|
||||
<< " origin:" << plane::origin()
|
||||
<< " normal:" << plane::normal()
|
||||
<< " triangulate:" << triangulate_
|
||||
<< " faces:" << faces().size()
|
||||
<< " points:" << points().size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -54,7 +54,8 @@ Usage
|
||||
planeType | plane description (pointAndNormal etc) | yes |
|
||||
triangulate | triangulate faces | no | true
|
||||
bounds | limit with bounding box | no |
|
||||
zone | limit to specified zone | no |
|
||||
zone | limit to cell zone (name or regex) | no |
|
||||
zones | limit to cell zones (names, regexs) | no |
|
||||
coordinateSystem | plane relative to given coordinate system | no |
|
||||
\endtable
|
||||
|
||||
@ -65,6 +66,7 @@ SeeAlso
|
||||
|
||||
Note
|
||||
Does not actually cut until update() called.
|
||||
The keyword \c zones has priority over \c zone.
|
||||
|
||||
SourceFiles
|
||||
sampledPlane.C
|
||||
@ -93,8 +95,8 @@ class sampledPlane
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- If restricted to zones, name of this zone or a regular expression
|
||||
const keyType zoneKey_;
|
||||
//- The zone or zones in which cutting is to occur
|
||||
wordRes zoneNames_;
|
||||
|
||||
//- Optional bounding box to trim triangles against
|
||||
const boundBox bounds_;
|
||||
@ -108,6 +110,20 @@ class sampledPlane
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Check and warn if bounding box does not intersect mesh or plane
|
||||
void checkBoundsIntersection
|
||||
(
|
||||
const plane& pln,
|
||||
const boundBox& meshBb
|
||||
) const;
|
||||
|
||||
//- Define cell selection from zones and bounding box.
|
||||
// Optionally check and warn if the plane does not intersect
|
||||
// with the bounds of the mesh (or submesh) or if the bounding box
|
||||
// does not overlap with the mesh (or submesh)
|
||||
bitSet cellSelection(const bool warnIntersect=false) const;
|
||||
|
||||
|
||||
//- Sample volume field onto surface faces
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sampleOnFaces
|
||||
@ -137,7 +153,7 @@ public:
|
||||
const word& name,
|
||||
const polyMesh& mesh,
|
||||
const plane& planeDesc,
|
||||
const keyType& zoneKey = word::null,
|
||||
const wordRes& zones = wordRes(),
|
||||
const bool triangulate = true
|
||||
);
|
||||
|
||||
|
||||
@ -150,10 +150,9 @@ Foam::sampledThresholdCellFaces::sampledThresholdCellFaces
|
||||
fieldName_(dict.get<word>("field")),
|
||||
lowerThreshold_(dict.lookupOrDefault<scalar>("lowerLimit", -VGREAT)),
|
||||
upperThreshold_(dict.lookupOrDefault<scalar>("upperLimit", VGREAT)),
|
||||
zoneKey_(keyType::null),
|
||||
triangulate_(dict.lookupOrDefault("triangulate", false)),
|
||||
prevTimeIndex_(-1),
|
||||
meshCells_(0)
|
||||
meshCells_()
|
||||
{
|
||||
if (!dict.found("lowerLimit") && !dict.found("upperLimit"))
|
||||
{
|
||||
|
||||
@ -99,9 +99,6 @@ class sampledThresholdCellFaces
|
||||
//- Threshold value
|
||||
const scalar upperThreshold_;
|
||||
|
||||
//- If restricted to zones, name of this zone or a regular expression
|
||||
keyType zoneKey_;
|
||||
|
||||
//- Triangulated faces or keep faces as is
|
||||
bool triangulate_;
|
||||
|
||||
|
||||
@ -45,6 +45,157 @@ namespace Foam
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::surfMeshSamplePlane::checkBoundsIntersection
|
||||
(
|
||||
const plane& pln,
|
||||
const boundBox& meshBb
|
||||
) const
|
||||
{
|
||||
// Verify specified bounding box
|
||||
if (!bounds_.empty())
|
||||
{
|
||||
// Bounding box does not overlap with (global) mesh!
|
||||
if (!bounds_.overlaps(meshBb))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Bounds " << bounds_
|
||||
<< " do not overlap the mesh bounding box " << mesh().bounds()
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
// Plane does not intersect the bounding box
|
||||
if (!bounds_.intersects(pln))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Plane "<< pln << " does not intersect the bounds "
|
||||
<< bounds_
|
||||
<< nl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Plane does not intersect the (global) mesh!
|
||||
if (!meshBb.intersects(pln))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Plane "<< pln << " does not intersect the mesh bounds "
|
||||
<< meshBb
|
||||
<< nl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::bitSet Foam::surfMeshSamplePlane::cellSelection
|
||||
(
|
||||
const bool warnIntersect
|
||||
) const
|
||||
{
|
||||
// Zones requested and in use?
|
||||
const bool hasZones =
|
||||
returnReduce
|
||||
(
|
||||
(-1 != mesh().cellZones().findIndex(zoneNames_)),
|
||||
andOp<bool>()
|
||||
);
|
||||
|
||||
|
||||
bitSet cellsToSelect;
|
||||
|
||||
if (hasZones)
|
||||
{
|
||||
cellsToSelect = mesh().cellZones().selection(zoneNames_);
|
||||
}
|
||||
|
||||
// Subset the zoned cells with the bounds_.
|
||||
// For a full mesh, use the bounds to define the cell selection.
|
||||
|
||||
// If there are zones cells, use them to build the effective mesh
|
||||
// bound box.
|
||||
// Note that for convenience we use cell centres here instead of the
|
||||
// cell points, since it will only be used for checking.
|
||||
|
||||
boundBox meshBb;
|
||||
|
||||
if (bounds_.empty())
|
||||
{
|
||||
// No bounds restriction, but will need the effective mesh boundBox
|
||||
// for checking intersections
|
||||
|
||||
if (hasZones && warnIntersect)
|
||||
{
|
||||
const auto& cellCentres = static_cast<const fvMesh&>(mesh()).C();
|
||||
|
||||
for (const label celli : cellsToSelect)
|
||||
{
|
||||
const point& cc = cellCentres[celli];
|
||||
|
||||
meshBb.add(cc);
|
||||
}
|
||||
|
||||
meshBb.reduce();
|
||||
}
|
||||
else
|
||||
{
|
||||
meshBb = mesh().bounds(); // use the regular mesh bounding box
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& cellCentres = static_cast<const fvMesh&>(mesh()).C();
|
||||
|
||||
// Only examine cells already set
|
||||
if (hasZones)
|
||||
{
|
||||
for (const label celli : cellsToSelect)
|
||||
{
|
||||
const point& cc = cellCentres[celli];
|
||||
|
||||
meshBb.add(cc);
|
||||
|
||||
if (!bounds_.contains(cc))
|
||||
{
|
||||
cellsToSelect.unset(celli);
|
||||
}
|
||||
}
|
||||
|
||||
meshBb.reduce();
|
||||
}
|
||||
else
|
||||
{
|
||||
const label len = mesh().nCells();
|
||||
|
||||
cellsToSelect.resize(len);
|
||||
|
||||
for (label celli=0; celli < len; ++celli)
|
||||
{
|
||||
const point& cc = cellCentres[celli];
|
||||
|
||||
if (bounds_.contains(cc))
|
||||
{
|
||||
cellsToSelect.set(celli);
|
||||
}
|
||||
}
|
||||
|
||||
meshBb = mesh().bounds(); // use the regular mesh bounding box
|
||||
}
|
||||
}
|
||||
|
||||
if (warnIntersect)
|
||||
{
|
||||
checkBoundsIntersection(*this, meshBb);
|
||||
}
|
||||
|
||||
return cellsToSelect;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::surfMeshSamplePlane::surfMeshSamplePlane
|
||||
@ -52,21 +203,29 @@ Foam::surfMeshSamplePlane::surfMeshSamplePlane
|
||||
const word& name,
|
||||
const polyMesh& mesh,
|
||||
const plane& planeDesc,
|
||||
const keyType& zoneKey,
|
||||
const wordRes& zones,
|
||||
const bool triangulate
|
||||
)
|
||||
:
|
||||
surfMeshSample(name, mesh),
|
||||
SurfaceSource(planeDesc),
|
||||
zoneKey_(zoneKey),
|
||||
zoneNames_(zones),
|
||||
bounds_(),
|
||||
triangulate_(triangulate),
|
||||
needsUpdate_(true)
|
||||
{
|
||||
if (debug && zoneKey_.size() && mesh.cellZones().findIndex(zoneKey_) == -1)
|
||||
if (debug)
|
||||
{
|
||||
Info<< "cellZone(s) " << zoneKey_
|
||||
<< " not found - using entire mesh" << endl;
|
||||
if (!zoneNames_.empty())
|
||||
{
|
||||
Info<< "cellZones " << flatOutput(zoneNames_);
|
||||
|
||||
if (-1 == mesh.cellZones().findIndex(zoneNames_))
|
||||
{
|
||||
Info<< " not found!";
|
||||
}
|
||||
Info<< endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,28 +239,60 @@ Foam::surfMeshSamplePlane::surfMeshSamplePlane
|
||||
:
|
||||
surfMeshSample(name, mesh, dict),
|
||||
SurfaceSource(plane(dict)),
|
||||
zoneKey_(dict.lookupOrDefault<keyType>("zone", keyType::null)),
|
||||
zoneNames_(),
|
||||
bounds_(dict.lookupOrDefault("bounds", boundBox::invertedBox)),
|
||||
triangulate_(dict.lookupOrDefault("triangulate", true)),
|
||||
needsUpdate_(true)
|
||||
{
|
||||
if (!dict.readIfPresent("zones", zoneNames_) && dict.found("zone"))
|
||||
{
|
||||
zoneNames_.resize(1);
|
||||
dict.readEntry("zone", zoneNames_.first());
|
||||
}
|
||||
|
||||
|
||||
// Make plane relative to the coordinateSystem (Cartesian)
|
||||
// allow lookup from global coordinate systems
|
||||
if (dict.found("coordinateSystem"))
|
||||
{
|
||||
coordinateSystem cs(mesh, dict.subDict("coordinateSystem"));
|
||||
|
||||
const point base = cs.globalPosition(planeDesc().origin());
|
||||
const point orig = cs.globalPosition(planeDesc().origin());
|
||||
const vector norm = cs.globalVector(planeDesc().normal());
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "plane " << name << " :"
|
||||
<< " origin:" << origin()
|
||||
<< " normal:" << normal()
|
||||
<< " defined within a local coordinateSystem" << endl;
|
||||
}
|
||||
|
||||
// Assign the plane description
|
||||
static_cast<plane&>(*this) = plane(base, norm);
|
||||
static_cast<plane&>(*this) = plane(orig, norm);
|
||||
}
|
||||
|
||||
if (debug && zoneKey_.size() && mesh.cellZones().findIndex(zoneKey_) == -1)
|
||||
if (debug)
|
||||
{
|
||||
Info<< "cellZone(s) " << zoneKey_
|
||||
<< " not found - using entire mesh" << endl;
|
||||
Info<< "plane " << name << " :"
|
||||
<< " origin:" << origin()
|
||||
<< " normal:" << normal();
|
||||
|
||||
if (!bounds_.empty())
|
||||
{
|
||||
Info<< " bounds:" << bounds_;
|
||||
}
|
||||
|
||||
if (!zoneNames_.empty())
|
||||
{
|
||||
Info<< " cellZones " << flatOutput(zoneNames_);
|
||||
|
||||
if (-1 == mesh.cellZones().findIndex(zoneNames_))
|
||||
{
|
||||
Info<< " not found!";
|
||||
}
|
||||
}
|
||||
Info<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,97 +325,7 @@ bool Foam::surfMeshSamplePlane::update()
|
||||
return false;
|
||||
}
|
||||
|
||||
const plane& pln = static_cast<const plane&>(*this);
|
||||
|
||||
// Verify specified bounding box
|
||||
if (!bounds_.empty())
|
||||
{
|
||||
// Bounding box does not overlap with (global) mesh!
|
||||
if (!bounds_.overlaps(mesh().bounds()))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Bounds " << bounds_
|
||||
<< " do not overlap the mesh bounding box " << mesh().bounds()
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
// Plane does not intersect the bounding box
|
||||
if (!bounds_.intersects(pln))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Plane "<< pln << " does not intersect the bounds "
|
||||
<< bounds_
|
||||
<< nl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Plane does not intersect the (global) mesh!
|
||||
if (!mesh().bounds().intersects(pln))
|
||||
{
|
||||
WarningInFunction
|
||||
<< nl
|
||||
<< name() << " : "
|
||||
<< "Plane "<< pln << " does not intersect the mesh bounds "
|
||||
<< mesh().bounds()
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
labelList selectedCells
|
||||
(
|
||||
mesh().cellZones().selection(zoneKey_).sortedToc()
|
||||
);
|
||||
|
||||
bool fullMesh = returnReduce(selectedCells.empty(), andOp<bool>());
|
||||
if (!bounds_.empty())
|
||||
{
|
||||
const auto& cellCentres = static_cast<const fvMesh&>(mesh()).C();
|
||||
|
||||
if (fullMesh)
|
||||
{
|
||||
const label len = mesh().nCells();
|
||||
|
||||
selectedCells.setSize(len);
|
||||
|
||||
label count = 0;
|
||||
for (label celli=0; celli < len; ++celli)
|
||||
{
|
||||
if (bounds_.contains(cellCentres[celli]))
|
||||
{
|
||||
selectedCells[count++] = celli;
|
||||
}
|
||||
}
|
||||
|
||||
selectedCells.setSize(count);
|
||||
}
|
||||
else
|
||||
{
|
||||
label count = 0;
|
||||
for (const label celli : selectedCells)
|
||||
{
|
||||
if (bounds_.contains(cellCentres[celli]))
|
||||
{
|
||||
selectedCells[count++] = celli;
|
||||
}
|
||||
}
|
||||
|
||||
selectedCells.setSize(count);
|
||||
}
|
||||
|
||||
fullMesh = false;
|
||||
}
|
||||
|
||||
if (fullMesh)
|
||||
{
|
||||
reCut(mesh(), triangulate_);
|
||||
}
|
||||
else
|
||||
{
|
||||
reCut(mesh(), triangulate_, selectedCells);
|
||||
}
|
||||
performCut(mesh(), triangulate_, this->cellSelection(true));
|
||||
|
||||
if (debug)
|
||||
{
|
||||
@ -263,11 +364,11 @@ bool Foam::surfMeshSamplePlane::sample
|
||||
void Foam::surfMeshSamplePlane::print(Ostream& os) const
|
||||
{
|
||||
os << "surfMeshSamplePlane: " << name() << " :"
|
||||
<< " base:" << plane::origin()
|
||||
<< " normal:" << plane::normal()
|
||||
<< " triangulate:" << triangulate_
|
||||
<< " faces:" << SurfaceSource::surfFaces().size()
|
||||
<< " points:" << SurfaceSource::points().size();
|
||||
<< " base:" << plane::origin()
|
||||
<< " normal:" << plane::normal()
|
||||
<< " triangulate:" << triangulate_
|
||||
<< " faces:" << SurfaceSource::surfFaces().size()
|
||||
<< " points:" << SurfaceSource::points().size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -63,8 +63,8 @@ class surfMeshSamplePlane
|
||||
|
||||
// Private data
|
||||
|
||||
//- If restricted to zones, name of this zone or a regular expression
|
||||
const keyType zoneKey_;
|
||||
//- The zone or zones in which cutting is to occur
|
||||
wordRes zoneNames_;
|
||||
|
||||
//- Optional bounding box to trim triangles against
|
||||
const boundBox bounds_;
|
||||
@ -78,6 +78,20 @@ class surfMeshSamplePlane
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Check and warn if bounding box does not intersect mesh or plane
|
||||
void checkBoundsIntersection
|
||||
(
|
||||
const plane& pln,
|
||||
const boundBox& meshBb
|
||||
) const;
|
||||
|
||||
//- Define cell selection from zones and bounding box.
|
||||
// Optionally check and warn if the plane does not intersect
|
||||
// with the bounds of the mesh (or submesh) or if the bounding box
|
||||
// does not overlap with the mesh (or submesh)
|
||||
bitSet cellSelection(const bool warnIntersect=false) const;
|
||||
|
||||
|
||||
//- Sample field on surface
|
||||
template<class Type>
|
||||
tmp<Field<Type>> sampleOnFaces
|
||||
@ -109,7 +123,7 @@ public:
|
||||
const word& name,
|
||||
const polyMesh& mesh,
|
||||
const plane& planeDesc,
|
||||
const keyType& zoneKey = word::null,
|
||||
const wordRes& zones = wordRes(),
|
||||
const bool triangulate = true
|
||||
);
|
||||
|
||||
|
||||
@ -24,117 +24,236 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "cuttingPlane.H"
|
||||
#include "primitiveMesh.H"
|
||||
#include "fvMesh.H"
|
||||
#include "volFields.H"
|
||||
#include "linePointRef.H"
|
||||
#include "meshTools.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
// Set values for what is close to zero and what is considered to
|
||||
// be positive (and not just rounding noise)
|
||||
//! \cond localScope
|
||||
static const Foam::scalar zeroish = Foam::SMALL;
|
||||
static const Foam::scalar positive = Foam::SMALL * 1E3;
|
||||
//! \endcond
|
||||
int Foam::cuttingPlane::debug(Foam::debug::debugSwitch("cuttingPlane", 0));
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
// Check edge/plane intersection based on crossings ... trivial check.
|
||||
inline bool intersectsEdge(const PackedList<2>& sides, const edge& e)
|
||||
{
|
||||
return (sides[e.first()] != sides[e.last()]);
|
||||
}
|
||||
|
||||
|
||||
// Check for face/plane intersection based on crossings
|
||||
// Took (-1,0,+1) from plane::sign and packed as (0,1,2).
|
||||
// Now use for left shift to obtain (1,2,4).
|
||||
//
|
||||
// Test accumulated value for an intersection with the plane.
|
||||
inline bool intersectsFace
|
||||
(
|
||||
const PackedList<2>& sides,
|
||||
const labelUList& indices
|
||||
)
|
||||
{
|
||||
unsigned accum = 0u;
|
||||
|
||||
for (const label pointi : indices)
|
||||
{
|
||||
accum |= (1u << sides[pointi]);
|
||||
}
|
||||
|
||||
// Accumulated value 3,5,6,7 indicates an intersection
|
||||
return (accum == 3 || accum >= 5);
|
||||
}
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::cuttingPlane::calcCutCells
|
||||
Foam::PackedList<2> Foam::cuttingPlane::classifySides
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const scalarField& dotProducts,
|
||||
const labelUList& cellIdLabels
|
||||
const plane& pln,
|
||||
const pointField& pts
|
||||
)
|
||||
{
|
||||
const labelListList& cellEdges = mesh.cellEdges();
|
||||
const edgeList& edges = mesh.edges();
|
||||
const label len = pts.size();
|
||||
|
||||
const label len =
|
||||
(notNull(cellIdLabels) ? cellIdLabels.size() : cellEdges.size());
|
||||
PackedList<2> output(len);
|
||||
|
||||
meshCells_.setSize(len);
|
||||
label cutcelli(0);
|
||||
|
||||
// Find the cut cells by detecting any cell that uses points with
|
||||
// opposing dotProducts.
|
||||
for (label listi = 0; listi < len; ++listi)
|
||||
// From signed (-1,0,+1) to (0,1,2) for PackedList
|
||||
for (label i=0; i < len; ++i)
|
||||
{
|
||||
const label celli =
|
||||
(notNull(cellIdLabels) ? cellIdLabels[listi] : listi);
|
||||
output.set(i, unsigned(1 + pln.sign(pts[i], SMALL)));
|
||||
}
|
||||
|
||||
const labelList& cEdges = cellEdges[celli];
|
||||
label nCutEdges = 0;
|
||||
return output;
|
||||
}
|
||||
|
||||
for (const label edgei : cEdges)
|
||||
|
||||
Foam::label Foam::cuttingPlane::calcCellCuts
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const PackedList<2>& sides,
|
||||
bitSet& cellCuts
|
||||
)
|
||||
{
|
||||
const faceList& faces = mesh.faces();
|
||||
|
||||
const label nCells = mesh.nCells();
|
||||
const label nFaces = mesh.nFaces();
|
||||
const label nInternFaces = mesh.nInternalFaces();
|
||||
|
||||
// Detect cells cuts from the face cuts
|
||||
|
||||
label nFaceCuts = 0;
|
||||
|
||||
// 1st face cut of cell
|
||||
bitSet hasCut1(nCells);
|
||||
|
||||
// 2nd face cut of cell
|
||||
bitSet hasCut2(nCells);
|
||||
|
||||
for (label facei = 0; facei < nInternFaces; ++facei)
|
||||
{
|
||||
if (intersectsFace(sides, faces[facei]))
|
||||
{
|
||||
const edge& e = edges[edgei];
|
||||
const label own = mesh.faceOwner()[facei];
|
||||
const label nei = mesh.faceNeighbour()[facei];
|
||||
|
||||
if
|
||||
(
|
||||
(dotProducts[e[0]] < zeroish && dotProducts[e[1]] > positive)
|
||||
|| (dotProducts[e[1]] < zeroish && dotProducts[e[0]] > positive)
|
||||
)
|
||||
++nFaceCuts;
|
||||
|
||||
if (!hasCut1.set(own))
|
||||
{
|
||||
if (++nCutEdges > 2)
|
||||
{
|
||||
meshCells_[cutcelli++] = celli;
|
||||
break;
|
||||
}
|
||||
hasCut2.set(own);
|
||||
}
|
||||
if (!hasCut1.set(nei))
|
||||
{
|
||||
hasCut2.set(nei);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set correct list size
|
||||
meshCells_.resize(cutcelli);
|
||||
for (label facei = nInternFaces; facei < nFaces; ++facei)
|
||||
{
|
||||
if (intersectsFace(sides, faces[facei]))
|
||||
{
|
||||
const label own = mesh.faceOwner()[facei];
|
||||
|
||||
++nFaceCuts;
|
||||
|
||||
if (!hasCut1.set(own))
|
||||
{
|
||||
hasCut2.set(own);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hasCut1.clearStorage(); // Not needed now
|
||||
|
||||
if (cellCuts.size())
|
||||
{
|
||||
cellCuts.resize(nCells); // safety
|
||||
cellCuts &= hasCut2; // restrict to cell subset
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<<"detected " << cellCuts.count() << "/" << nCells
|
||||
<< " cells cut, subsetted from "
|
||||
<< hasCut2.count() << "/" << nCells << " cells." << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cellCuts = std::move(hasCut2);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<<"detected " << cellCuts.count() << "/" << nCells
|
||||
<< " cells cut." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (debug && isA<fvMesh>(mesh))
|
||||
{
|
||||
const fvMesh& fvm = dynamicCast<const fvMesh&>(mesh);
|
||||
|
||||
volScalarField debugField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"cuttingPlane.cellCuts",
|
||||
fvm.time().timeName(),
|
||||
fvm.time(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
fvm,
|
||||
dimensionedScalar(dimless, Zero)
|
||||
);
|
||||
|
||||
auto& debugFld = debugField.primitiveFieldRef();
|
||||
|
||||
for (const label celli : cellCuts)
|
||||
{
|
||||
debugFld[celli] = 1;
|
||||
}
|
||||
|
||||
Pout<< "Writing cut types:"
|
||||
<< debugField.objectPath() << endl;
|
||||
|
||||
debugField.write();
|
||||
}
|
||||
|
||||
|
||||
return nFaceCuts;
|
||||
}
|
||||
|
||||
|
||||
void Foam::cuttingPlane::intersectEdges
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const scalarField& dotProducts,
|
||||
const PackedList<2>& sides,
|
||||
const bitSet& cellCuts,
|
||||
List<label>& edgePoint
|
||||
)
|
||||
{
|
||||
// Use the dotProducts to find out the cut edges.
|
||||
const edgeList& edges = mesh.edges();
|
||||
const pointField& points = mesh.points();
|
||||
|
||||
// Per edge -1 or the label of the intersection point
|
||||
edgePoint.resize(edges.size());
|
||||
|
||||
DynamicList<point> dynCuttingPoints(4*meshCells_.size());
|
||||
DynamicList<point> dynCutPoints(4*cellCuts.count());
|
||||
|
||||
forAll(edges, edgei)
|
||||
{
|
||||
const edge& e = edges[edgei];
|
||||
|
||||
if
|
||||
(
|
||||
(dotProducts[e[0]] < zeroish && dotProducts[e[1]] > positive)
|
||||
|| (dotProducts[e[1]] < zeroish && dotProducts[e[0]] > positive)
|
||||
)
|
||||
if (intersectsEdge(sides, points, e))
|
||||
{
|
||||
// Edge is cut
|
||||
edgePoint[edgei] = dynCuttingPoints.size();
|
||||
edgePoint[edgei] = dynCutPoints.size();
|
||||
|
||||
const point& p0 = points[e[0]];
|
||||
const point& p1 = points[e[1]];
|
||||
|
||||
const scalar alpha = lineIntersect(linePointRef(p0, p1));
|
||||
|
||||
if (alpha < zeroish)
|
||||
if (alpha < SMALL)
|
||||
{
|
||||
dynCuttingPoints.append(p0);
|
||||
dynCutPoints.append(p0);
|
||||
}
|
||||
else if (alpha >= 1.0)
|
||||
{
|
||||
dynCuttingPoints.append(p1);
|
||||
dynCutPoints.append(p1);
|
||||
}
|
||||
else
|
||||
{
|
||||
dynCuttingPoints.append((1-alpha)*p0 + alpha*p1);
|
||||
dynCutPoints.append((1-alpha)*p0 + alpha*p1);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -143,7 +262,7 @@ void Foam::cuttingPlane::intersectEdges
|
||||
}
|
||||
}
|
||||
|
||||
this->storedPoints().transfer(dynCuttingPoints);
|
||||
this->storedPoints().transfer(dynCutPoints);
|
||||
}
|
||||
|
||||
|
||||
@ -237,20 +356,22 @@ bool Foam::cuttingPlane::walkCell
|
||||
void Foam::cuttingPlane::walkCellCuts
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const labelUList& edgePoint
|
||||
const bitSet& cellCuts,
|
||||
const labelUList& edgePoint,
|
||||
const bool triangulate
|
||||
)
|
||||
{
|
||||
const pointField& cutPoints = this->points();
|
||||
|
||||
// use dynamic lists to handle triangulation and/or missed cuts
|
||||
DynamicList<face> dynCutFaces(meshCells_.size());
|
||||
DynamicList<label> dynCutCells(meshCells_.size());
|
||||
// Dynamic lists to handle triangulation and/or missed cuts
|
||||
|
||||
// scratch space for calculating the face vertices
|
||||
DynamicList<label> faceVerts(10);
|
||||
DynamicList<face> dynCutFaces(cellCuts.count());
|
||||
DynamicList<label> dynCutCells(cellCuts.count());
|
||||
|
||||
for (const label celli : meshCells_)
|
||||
// Scratch space for calculating the face vertices
|
||||
DynamicList<label> faceVerts(16);
|
||||
|
||||
for (const label celli : cellCuts)
|
||||
{
|
||||
// Find the starting edge to walk from.
|
||||
const labelList& cEdges = mesh.cellEdges()[celli];
|
||||
@ -334,6 +455,34 @@ Foam::cuttingPlane::cuttingPlane(const plane& pln)
|
||||
{}
|
||||
|
||||
|
||||
Foam::cuttingPlane::cuttingPlane
|
||||
(
|
||||
const plane& pln,
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const bitSet& cellIdLabels
|
||||
)
|
||||
:
|
||||
plane(pln)
|
||||
{
|
||||
performCut(mesh, triangulate, cellIdLabels);
|
||||
}
|
||||
|
||||
|
||||
Foam::cuttingPlane::cuttingPlane
|
||||
(
|
||||
const plane& pln,
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
bitSet&& cellIdLabels
|
||||
)
|
||||
:
|
||||
plane(pln)
|
||||
{
|
||||
performCut(mesh, triangulate, cellIdLabels);
|
||||
}
|
||||
|
||||
|
||||
Foam::cuttingPlane::cuttingPlane
|
||||
(
|
||||
const plane& pln,
|
||||
@ -344,34 +493,77 @@ Foam::cuttingPlane::cuttingPlane
|
||||
:
|
||||
plane(pln)
|
||||
{
|
||||
reCut(mesh, triangulate, cellIdLabels);
|
||||
performCut(mesh, triangulate, cellIdLabels);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::cuttingPlane::reCut
|
||||
void Foam::cuttingPlane::performCut
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
bitSet&& cellIdLabels
|
||||
)
|
||||
{
|
||||
MeshStorage::clear();
|
||||
meshCells_.clear();
|
||||
|
||||
// Pre-populate with restriction
|
||||
bitSet cellCuts(std::move(cellIdLabels));
|
||||
|
||||
if (cellCuts.size())
|
||||
{
|
||||
cellCuts.resize(mesh.nCells());
|
||||
}
|
||||
|
||||
// Classification of points with respect to the plane
|
||||
PackedList<2> sides = classifySides(*this, mesh.points());
|
||||
|
||||
// Determine cells that are (likely) cut
|
||||
// - some ambiguity when plane is exactly between cells
|
||||
calcCellCuts(mesh, sides, cellCuts);
|
||||
|
||||
// Determine cutPoints and return list of edge cuts.
|
||||
// per edge -1 or the label of the intersection point
|
||||
labelList edgePoint;
|
||||
intersectEdges(mesh, sides, cellCuts, edgePoint);
|
||||
|
||||
// Do topological walk around cell to find closed loop.
|
||||
walkCellCuts(mesh, cellCuts, edgePoint, triangulate);
|
||||
}
|
||||
|
||||
|
||||
void Foam::cuttingPlane::performCut
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const bitSet& cellIdLabels
|
||||
)
|
||||
{
|
||||
bitSet subsetCells(cellIdLabels);
|
||||
|
||||
performCut(mesh, triangulate, std::move(subsetCells));
|
||||
}
|
||||
|
||||
|
||||
void Foam::cuttingPlane::performCut
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const labelUList& cellIdLabels
|
||||
)
|
||||
{
|
||||
MeshStorage::clear();
|
||||
meshCells_.clear();
|
||||
bitSet subsetCells;
|
||||
|
||||
const scalarField dotProducts((mesh.points() - refPoint()) & normal());
|
||||
if (notNull(cellIdLabels))
|
||||
{
|
||||
// Pre-populate with restriction
|
||||
subsetCells.resize(mesh.nCells());
|
||||
subsetCells.set(cellIdLabels);
|
||||
}
|
||||
|
||||
// Determine cells that are (probably) cut.
|
||||
calcCutCells(mesh, dotProducts, cellIdLabels);
|
||||
|
||||
// Determine cutPoints and return list of edge cuts.
|
||||
// per edge -1 or the label of the intersection point
|
||||
labelList edgePoint;
|
||||
intersectEdges(mesh, dotProducts, edgePoint);
|
||||
|
||||
// Do topological walk around cell to find closed loop.
|
||||
walkCellCuts(mesh, triangulate, edgePoint);
|
||||
performCut(mesh, triangulate, std::move(subsetCells));
|
||||
}
|
||||
|
||||
|
||||
@ -380,11 +572,10 @@ void Foam::cuttingPlane::remapFaces
|
||||
const labelUList& faceMap
|
||||
)
|
||||
{
|
||||
if (notNull(faceMap) && faceMap.size())
|
||||
if (notNull(faceMap) && !faceMap.empty())
|
||||
{
|
||||
MeshStorage::remapFaces(faceMap);
|
||||
|
||||
// Renumber
|
||||
List<label> newCutCells(faceMap.size());
|
||||
forAll(faceMap, facei)
|
||||
{
|
||||
@ -399,7 +590,6 @@ void Foam::cuttingPlane::remapFaces
|
||||
|
||||
void Foam::cuttingPlane::operator=(const cuttingPlane& rhs)
|
||||
{
|
||||
// Check for assignment to self
|
||||
if (this == &rhs)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
|
||||
@ -25,10 +25,10 @@ Class
|
||||
Foam::cuttingPlane
|
||||
|
||||
Description
|
||||
Constructs plane through mesh.
|
||||
Constructs cutting plane through a mesh.
|
||||
|
||||
No attempt at resolving degenerate cases. Since the cut faces are
|
||||
usually quite ugly, they will always be triangulated.
|
||||
No attempt at resolving degenerate cases.
|
||||
Since the cut faces can be quite ugly, they will often be triangulated.
|
||||
|
||||
Note
|
||||
When the cutting plane coincides with a mesh face, the cell edge on the
|
||||
@ -45,6 +45,7 @@ SourceFiles
|
||||
#include "plane.H"
|
||||
#include "pointField.H"
|
||||
#include "faceList.H"
|
||||
#include "bitSet.H"
|
||||
#include "MeshedSurface.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -52,6 +53,7 @@ SourceFiles
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward declarations
|
||||
class primitiveMesh;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
@ -75,19 +77,28 @@ class cuttingPlane
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Determine cut cells, possibly restricted to a list of cells
|
||||
void calcCutCells
|
||||
//- Classify sides of plane (0=BACK, 1=ONPLANE, 2=FRONT) for each point
|
||||
static PackedList<2> classifySides
|
||||
(
|
||||
const primitiveMesh&,
|
||||
const scalarField& dotProducts,
|
||||
const labelUList& cellIdLabels = labelUList::null()
|
||||
const plane& pln,
|
||||
const pointField& pts
|
||||
);
|
||||
|
||||
//- Determine cut cells, possibly restricted to a list of cells
|
||||
// \return number of faces cut
|
||||
label calcCellCuts
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const PackedList<2>& planeSides,
|
||||
bitSet& cellCuts
|
||||
);
|
||||
|
||||
//- Determine intersection points (cutPoints).
|
||||
void intersectEdges
|
||||
(
|
||||
const primitiveMesh&,
|
||||
const scalarField& dotProducts,
|
||||
const primitiveMesh& mesh,
|
||||
const PackedList<2>& planeSides,
|
||||
const bitSet& cellCuts,
|
||||
List<label>& edgePoint
|
||||
);
|
||||
|
||||
@ -106,8 +117,9 @@ class cuttingPlane
|
||||
void walkCellCuts
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const labelUList& edgePoint
|
||||
const bitSet& cellCuts,
|
||||
const labelUList& edgePoint,
|
||||
const bool triangulate
|
||||
);
|
||||
|
||||
|
||||
@ -115,18 +127,35 @@ protected:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct plane description without cutting
|
||||
//- Construct from a plane description without any cutting
|
||||
cuttingPlane(const plane& pln);
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Recut mesh with existing plane, restricted to a list of cells
|
||||
void reCut
|
||||
//- Cut mesh with existing plane, restricted to a list of cells
|
||||
void performCut
|
||||
(
|
||||
const primitiveMesh&,
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const labelUList& cellIdLabels = labelUList::null()
|
||||
const bitSet& cellSelectionMask = bitSet()
|
||||
);
|
||||
|
||||
//- Cut mesh with existing plane, restricted to a list of cells
|
||||
// Reclaim memory for cellSelectionMask
|
||||
void performCut
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
bitSet&& cellSelectionMask
|
||||
);
|
||||
|
||||
//- Cut mesh with existing plane, restricted to a list of cells
|
||||
void performCut
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const labelUList& cellIdLabels
|
||||
);
|
||||
|
||||
//- Remap action on triangulation or cleanup
|
||||
@ -135,6 +164,10 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
//- Debug information
|
||||
static int debug;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from plane and mesh reference,
|
||||
@ -144,7 +177,27 @@ public:
|
||||
const plane& pln,
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const labelUList& cellIdLabels = labelUList::null()
|
||||
const bitSet& cellIdLabels = bitSet()
|
||||
);
|
||||
|
||||
//- Construct from plane and mesh reference,
|
||||
//- possibly restricted to a list of cells
|
||||
cuttingPlane
|
||||
(
|
||||
const plane& pln,
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
bitSet&& cellIdLabels
|
||||
);
|
||||
|
||||
//- Construct from plane and mesh reference,
|
||||
//- possibly restricted to a list of cells
|
||||
cuttingPlane
|
||||
(
|
||||
const plane& pln,
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const labelUList& cellIdLabels
|
||||
);
|
||||
|
||||
|
||||
@ -153,7 +206,7 @@ public:
|
||||
//- Return the plane used
|
||||
const plane& planeDesc() const
|
||||
{
|
||||
return static_cast<const plane&>(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//- The mesh cells cut by the plane
|
||||
|
||||
@ -74,7 +74,6 @@ Foam::distanceSurface::distanceSurface
|
||||
cell_(dict.lookupOrDefault("cell", true)),
|
||||
regularise_(dict.lookupOrDefault("regularise", true)),
|
||||
bounds_(dict.lookupOrDefault("bounds", boundBox::invertedBox)),
|
||||
zoneKey_(keyType::null),
|
||||
isoSurfCellPtr_(nullptr),
|
||||
isoSurfPtr_(nullptr)
|
||||
{}
|
||||
@ -120,7 +119,6 @@ Foam::distanceSurface::distanceSurface
|
||||
cell_(cell),
|
||||
regularise_(regularise),
|
||||
bounds_(bounds),
|
||||
zoneKey_(keyType::null),
|
||||
isoSurfCellPtr_(nullptr),
|
||||
isoSurfPtr_(nullptr)
|
||||
{}
|
||||
|
||||
@ -97,9 +97,6 @@ class distanceSurface
|
||||
//- Optional bounding box to trim triangles against
|
||||
const boundBox bounds_;
|
||||
|
||||
//- If restricted to zones, name of this zone or a regular expression
|
||||
keyType zoneKey_;
|
||||
|
||||
//- Distance to cell centres
|
||||
autoPtr<volScalarField> cellDistancePtr_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user