Commit 544941b9 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: support zone and zones for sampled cutting planes, sampledIsoSurface

- rework to use bitSet for more flexibility
parent cf7bd82c
...@@ -108,7 +108,7 @@ void Foam::sampledIsoSurface::getIsoFields() const ...@@ -108,7 +108,7 @@ void Foam::sampledIsoSurface::getIsoFields() const
fvm fvm
) )
); );
volFieldPtr_ = storedVolFieldPtr_.operator->(); volFieldPtr_ = storedVolFieldPtr_.get();
} }
else else
{ {
...@@ -132,7 +132,7 @@ void Foam::sampledIsoSurface::getIsoFields() const ...@@ -132,7 +132,7 @@ void Foam::sampledIsoSurface::getIsoFields() const
// (volPointInterpolation::interpolate with cache=false deletes any // (volPointInterpolation::interpolate with cache=false deletes any
// registered one or if mesh.changing()) // registered one or if mesh.changing())
if (!subMeshPtr_.valid()) if (subMeshPtr_.empty())
{ {
const word pointFldName = const word pointFldName =
"volPointInterpolate_" "volPointInterpolate_"
...@@ -200,8 +200,8 @@ void Foam::sampledIsoSurface::getIsoFields() const ...@@ -200,8 +200,8 @@ void Foam::sampledIsoSurface::getIsoFields() const
} }
// If averaging redo the volField. Can only be done now since needs the // If averaging redo the volField.
// point field. // Can only be done now since needs the point field.
if (average_) if (average_)
{ {
storedVolFieldPtr_.reset storedVolFieldPtr_.reset
...@@ -261,7 +261,7 @@ void Foam::sampledIsoSurface::getIsoFields() const ...@@ -261,7 +261,7 @@ void Foam::sampledIsoSurface::getIsoFields() const
} }
// Pointfield on submesh // The point field on subMesh
const word pointFldName = const word pointFldName =
"volPointInterpolate_" "volPointInterpolate_"
...@@ -360,30 +360,30 @@ bool Foam::sampledIsoSurface::updateGeometry() const ...@@ -360,30 +360,30 @@ bool Foam::sampledIsoSurface::updateGeometry() const
return false; return false;
} }
// Get any subMesh // Get sub-mesh if any
if (zoneID_.index() != -1 && !subMeshPtr_.valid()) if
(
(-1 != mesh().cellZones().findIndex(zoneNames_))
&& subMeshPtr_.empty()
)
{ {
const polyBoundaryMesh& patches = mesh().boundaryMesh(); const polyBoundaryMesh& patches = mesh().boundaryMesh();
// Patch to put exposed internal faces into // Patch to put exposed internal faces into
const label exposedPatchi = patches.findPatchID(exposedPatchName_); const label exposedPatchi = patches.findPatchID(exposedPatchName_);
if (debug) DebugInfo
{ << "Allocating subset of size "
Info<< "Allocating subset of size " << mesh().cellZones().selection(zoneNames_).count()
<< mesh().cellZones()[zoneID_.index()].size() << " with exposed faces into patch "
<< " with exposed faces into patch " << patches[exposedPatchi].name() << endl;
<< patches[exposedPatchi].name() << endl;
}
// Remove old mesh if any
subMeshPtr_.clear();
subMeshPtr_.reset subMeshPtr_.reset
( (
new fvMeshSubset new fvMeshSubset
( (
fvm, fvm,
mesh().cellZones()[zoneID_.index()], mesh().cellZones().selection(zoneNames_),
exposedPatchi exposedPatchi
) )
); );
...@@ -474,8 +474,8 @@ Foam::sampledIsoSurface::sampledIsoSurface ...@@ -474,8 +474,8 @@ Foam::sampledIsoSurface::sampledIsoSurface
mergeTol_(dict.lookupOrDefault("mergeTol", 1e-6)), mergeTol_(dict.lookupOrDefault("mergeTol", 1e-6)),
regularise_(dict.lookupOrDefault("regularise", true)), regularise_(dict.lookupOrDefault("regularise", true)),
average_(dict.lookupOrDefault("average", false)), average_(dict.lookupOrDefault("average", false)),
zoneID_(dict.lookupOrDefault("zone", word::null), mesh.cellZones()), zoneNames_(),
exposedPatchName_(word::null), exposedPatchName_(),
surfPtr_(nullptr), surfPtr_(nullptr),
prevTimeIndex_(-1), prevTimeIndex_(-1),
storedVolFieldPtr_(nullptr), storedVolFieldPtr_(nullptr),
...@@ -491,27 +491,30 @@ Foam::sampledIsoSurface::sampledIsoSurface ...@@ -491,27 +491,30 @@ Foam::sampledIsoSurface::sampledIsoSurface
<< " span across cells." << exit(FatalIOError); << " 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_); dict.readEntry("exposedPatchName", exposedPatchName_);
if (mesh.boundaryMesh().findPatchID(exposedPatchName_) == -1) if (mesh.boundaryMesh().findPatchID(exposedPatchName_) == -1)
{ {
FatalIOErrorInFunction FatalIOErrorInFunction(dict)
( << "Cannot find patch " << exposedPatchName_
dict
) << "Cannot find patch " << exposedPatchName_
<< " in which to put exposed faces." << endl << " in which to put exposed faces." << endl
<< "Valid patches are " << mesh.boundaryMesh().names() << "Valid patches are " << mesh.boundaryMesh().names()
<< exit(FatalIOError); << exit(FatalIOError);
} }
if (debug && zoneID_.index() != -1) DebugInfo
{ << "Restricting to cellZone(s) " << flatOutput(zoneNames_)
Info<< "Restricting to cellZone " << zoneID_.name() << " with exposed internal faces into patch "
<< " with exposed internal faces into patch " << exposedPatchName_ << endl;
<< exposedPatchName_ << endl;
}
} }
} }
......
...@@ -54,7 +54,8 @@ Usage ...@@ -54,7 +54,8 @@ Usage
regularise | point snapping | yes | regularise | point snapping | yes |
average | cell values from averaged point values | no | false average | cell values from averaged point values | no | false
bounds | limit with bounding box | no | 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 | exposedPatchName | name for zone subset | partly |
\endtable \endtable
...@@ -68,7 +69,6 @@ SourceFiles ...@@ -68,7 +69,6 @@ SourceFiles
#include "isoSurface.H" #include "isoSurface.H"
#include "sampledSurface.H" #include "sampledSurface.H"
#include "ZoneIDs.H"
#include "fvMeshSubset.H" #include "fvMeshSubset.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
...@@ -104,8 +104,8 @@ class sampledIsoSurface ...@@ -104,8 +104,8 @@ class sampledIsoSurface
//- Whether to recalculate cell values as average of point values //- Whether to recalculate cell values as average of point values
const bool average_; const bool average_;
//- Zone name/index (if restricted to zones) //- The zone or zones for the iso-surface
mutable cellZoneID zoneID_; wordRes zoneNames_;
//- For zones: patch to put exposed faces into //- For zones: patch to put exposed faces into
mutable word exposedPatchName_; mutable word exposedPatchName_;
......
...@@ -201,7 +201,6 @@ Foam::sampledIsoSurfaceCell::sampledIsoSurfaceCell ...@@ -201,7 +201,6 @@ Foam::sampledIsoSurfaceCell::sampledIsoSurfaceCell
bounds_(dict.lookupOrDefault("bounds", boundBox::invertedBox)), bounds_(dict.lookupOrDefault("bounds", boundBox::invertedBox)),
regularise_(dict.lookupOrDefault("regularise", true)), regularise_(dict.lookupOrDefault("regularise", true)),
average_(dict.lookupOrDefault("average", true)), average_(dict.lookupOrDefault("average", true)),
zoneKey_(keyType::null),
prevTimeIndex_(-1), prevTimeIndex_(-1),
meshCells_() meshCells_()
{} {}
......
...@@ -56,6 +56,9 @@ Usage ...@@ -56,6 +56,9 @@ Usage
bounds | limit with bounding box | no | bounds | limit with bounding box | no |
\endtable \endtable
Note
Does not currently support cell zones.
SourceFiles SourceFiles
sampledIsoSurfaceCell.C sampledIsoSurfaceCell.C
...@@ -102,9 +105,6 @@ class sampledIsoSurfaceCell ...@@ -102,9 +105,6 @@ class sampledIsoSurfaceCell
//- Whether to recalculate cell values as average of point values //- Whether to recalculate cell values as average of point values
const bool average_; const bool average_;
//- If restricted to zones, name of this zone or a regular expression
keyType zoneKey_;
// Recreated for every isoSurface // Recreated for every isoSurface
......
...@@ -46,6 +46,51 @@ namespace Foam ...@@ -46,6 +46,51 @@ namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * 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() void Foam::sampledCuttingPlane::createGeometry()
{ {
if (debug) if (debug)
...@@ -62,29 +107,51 @@ void Foam::sampledCuttingPlane::createGeometry() ...@@ -62,29 +107,51 @@ void Foam::sampledCuttingPlane::createGeometry()
// Clear derived data // Clear derived data
clearGeom(); clearGeom();
// Get any subMesh const fvMesh& fvm = static_cast<const fvMesh&>(this->mesh());
if (zoneID_.index() != -1 && !subMeshPtr_.valid())
// Get sub-mesh if any
if
(
(-1 != mesh().cellZones().findIndex(zoneNames_))
&& subMeshPtr_.empty()
)
{ {
const polyBoundaryMesh& patches = mesh().boundaryMesh(); const polyBoundaryMesh& patches = mesh().boundaryMesh();
// Patch to put exposed internal faces into // Patch to put exposed internal faces into
const label exposedPatchi = patches.findPatchID(exposedPatchName_); const label exposedPatchi = patches.findPatchID(exposedPatchName_);
bitSet cellsToSelect = mesh().cellZones().selection(zoneNames_);
DebugInfo DebugInfo
<< "Allocating subset of size " << "Allocating subset of size "
<< mesh().cellZones()[zoneID_.index()].size() << cellsToSelect.count()
<< " with exposed faces into patch " << " with exposed faces into patch "
<< patches[exposedPatchi].name() << endl; << patches[exposedPatchi].name() << endl;
subMeshPtr_.reset
( // If we will use a fvMeshSubset so can apply bounds as well to make
new fvMeshSubset // the initial selection smaller.
( if (!bounds_.empty() && cellsToSelect.any())
static_cast<const fvMesh&>(mesh()), {
mesh().cellZones()[zoneID_.index()], const auto& cellCentres = fvm.C();
exposedPatchi
) 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() ...@@ -93,9 +160,11 @@ void Foam::sampledCuttingPlane::createGeometry()
( (
subMeshPtr_.valid() subMeshPtr_.valid()
? subMeshPtr_().subMesh() ? subMeshPtr_().subMesh()
: static_cast<const fvMesh&>(this->mesh()) : fvm
); );
checkBoundsIntersection(plane_, mesh.bounds());
// Distance to cell centres // Distance to cell centres
// ~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -121,7 +190,7 @@ void Foam::sampledCuttingPlane::createGeometry() ...@@ -121,7 +190,7 @@ void Foam::sampledCuttingPlane::createGeometry()
// Internal field // Internal field
{ {
const pointField& cc = mesh.cellCentres(); const auto& cc = mesh.cellCentres();
scalarField& fld = cellDistance.primitiveFieldRef(); scalarField& fld = cellDistance.primitiveFieldRef();
forAll(cc, i) forAll(cc, i)
...@@ -167,6 +236,7 @@ void Foam::sampledCuttingPlane::createGeometry() ...@@ -167,6 +236,7 @@ void Foam::sampledCuttingPlane::createGeometry()
} }
else else
{ {
// Other side cell centres?
const pointField& cc = mesh.C().boundaryField()[patchi]; const pointField& cc = mesh.C().boundaryField()[patchi];
fvPatchScalarField& fld = cellDistanceBf[patchi]; fvPatchScalarField& fld = cellDistanceBf[patchi];
...@@ -242,43 +312,6 @@ void Foam::sampledCuttingPlane::createGeometry() ...@@ -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) if (debug)
{ {
print(Pout); print(Pout);
...@@ -302,32 +335,36 @@ Foam::sampledCuttingPlane::sampledCuttingPlane ...@@ -302,32 +335,36 @@ Foam::sampledCuttingPlane::sampledCuttingPlane
mergeTol_(dict.lookupOrDefault("mergeTol", 1e-6)), mergeTol_(dict.lookupOrDefault("mergeTol", 1e-6)),
regularise_(dict.lookupOrDefault("regularise", true)), regularise_(dict.lookupOrDefault("regularise", true)),
average_(dict.lookupOrDefault("average", false)), average_(dict.lookupOrDefault("average", false)),
zoneID_(dict.lookupOrDefault("zone", word::null), mesh.cellZones()), zoneNames_(),
exposedPatchName_(word::null), exposedPatchName_(),
needsUpdate_(true), needsUpdate_(true),
subMeshPtr_(nullptr), subMeshPtr_(nullptr),
cellDistancePtr_(nullptr), cellDistancePtr_(nullptr),
isoSurfPtr_(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_); dict.readEntry("exposedPatchName", exposedPatchName_);
if (mesh.boundaryMesh().findPatchID(exposedPatchName_) == -1) if (-1 == mesh.boundaryMesh().findPatchID(exposedPatchName_))
{ {
FatalErrorInFunction FatalIOErrorInFunction(dict)
<< "Cannot find patch " << exposedPatchName_ << "Cannot find patch " << exposedPatchName_
<< " in which to put exposed faces." << endl << " in which to put exposed faces." << endl
<< "Valid patches are " << mesh.boundaryMesh().names() << "Valid patches are " << mesh.boundaryMesh().names()
<< exit(FatalError); << exit(FatalError);
} }
if (debug && zoneID_.index() != -1) DebugInfo
{ << "Restricting to cellZone(s) " << flatOutput(zoneNames_)
Info<< "Restricting to cellZone " << zoneID_.name() << " with exposed internal faces into patch "
<< " with exposed internal faces into patch " << exposedPatchName_ << endl;
<< exposedPatchName_ << endl;
}
} }
} }
......
...@@ -55,10 +55,14 @@ Usage ...@@ -55,10 +55,14 @@ Usage
mergeTol | tolerance for merging points | no | 1e-6 mergeTol | tolerance for merging points | no | 1e-6
regularise | point snapping | no | true regularise | point snapping | no | true
bounds | limit with bounding box | no | 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 | exposedPatchName | name for zone subset | partly |
\endtable \endtable
Note
The keyword \c zones has priority over \c zone.
SeeAlso SeeAlso
Foam::plane Foam::plane
...@@ -74,7 +78,6 @@ SourceFiles ...@@ -74,7 +78,6 @@ SourceFiles
#include "isoSurface.H" #include "isoSurface.H"
//#include "isoSurfaceCell.H" //#include "isoSurfaceCell.H"
#include "plane.H" #include "plane.H"
#include "ZoneIDs.H"
#include "fvMeshSubset.H" #include "fvMeshSubset.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
...@@ -107,8 +110,8 @@ class sampledCuttingPlane ...@@ -107,8 +110,8 @@ class sampledCuttingPlane
//- Whether to recalculate cell values as average of point values //- Whether to recalculate cell values as average of point values
const bool average_; const bool average_;
//- Zone name/index (if restricted to zones) //- The zone or zones in which cutting is to occur
mutable cellZoneID zoneID_;