ENH: cellZones support for isoSurface cell/topo sampling variants (#1678)

- better alignment of sampling Cell/Point/Topo inputs

- make exposedPatchName optional for isoSurface, cuttingPlane. This
  was a holdover requirement from an older version of fvMeshSubset
This commit is contained in:
Mark Olesen
2020-12-07 12:42:35 +01:00
parent 9da5215786
commit ccde68d410
13 changed files with 284 additions and 178 deletions

View File

@ -60,14 +60,21 @@ Foam::sampledDistanceSurface::sampleOnPoints
// Assume volPointInterpolation for the point field! // Assume volPointInterpolation for the point field!
const auto& volFld = interpolator.psi(); const auto& volFld = interpolator.psi();
auto tpointFld = tmp<GeometricField<Type, fvPatchField, volMesh>> tvolFld(volFld);
volPointInterpolation::New(volFld.mesh()).interpolate(volFld); tmp<GeometricField<Type, pointPatchField, pointMesh>> tpointFld;
return distanceSurface::interpolate // Interpolated point field
tpointFld.reset
( (
(average_ ? pointAverage(tpointFld())() : volFld), volPointInterpolation::New(tvolFld().mesh()).interpolate(tvolFld())
tpointFld()
); );
if (average_)
{
tvolFld.reset(pointAverage(tpointFld()));
}
return distanceSurface::interpolate(tvolFld(), tpointFld());
} }

View File

@ -327,16 +327,14 @@ bool Foam::sampledIsoSurface::updateGeometry() const
&& (-1 != mesh().cellZones().findIndex(zoneNames_)) && (-1 != mesh().cellZones().findIndex(zoneNames_))
) )
{ {
const polyBoundaryMesh& patches = mesh().boundaryMesh(); const label exposedPatchi =
mesh().boundaryMesh().findPatchID(exposedPatchName_);
// Patch to put exposed internal faces into
const label exposedPatchi = patches.findPatchID(exposedPatchName_);
DebugInfo DebugInfo
<< "Allocating subset of size " << "Allocating subset of size "
<< mesh().cellZones().selection(zoneNames_).count() << mesh().cellZones().selection(zoneNames_).count()
<< " with exposed faces into patch " << " with exposed faces into patch "
<< patches[exposedPatchi].name() << endl; << exposedPatchi << endl;
subMeshPtr_.reset subMeshPtr_.reset
( (
@ -359,36 +357,25 @@ bool Foam::sampledIsoSurface::updateGeometry() const
// Clear derived data // Clear derived data
clearGeom(); clearGeom();
refPtr<volScalarField> tvolFld(*volFieldPtr_);
refPtr<pointScalarField> tpointFld(*pointFieldPtr_);
if (subMeshPtr_) if (subMeshPtr_)
{ {
const volScalarField& vfld = *volSubFieldPtr_; tvolFld.cref(*volSubFieldPtr_);
tpointFld.cref(*pointSubFieldPtr_);
}
isoSurfacePtr_.reset isoSurfacePtr_.reset
( (
new isoSurfacePoint new isoSurfacePoint
( (
vfld, tvolFld(),
*pointSubFieldPtr_, tpointFld(),
isoVal_, isoVal_,
isoParams_ isoParams_
) )
); );
}
else
{
const volScalarField& vfld = *volFieldPtr_;
isoSurfacePtr_.reset
(
new isoSurfacePoint
(
vfld,
*pointFieldPtr_,
isoVal_,
isoParams_
)
);
}
if (debug) if (debug)
@ -455,21 +442,12 @@ Foam::sampledIsoSurface::sampledIsoSurface
if (-1 != mesh.cellZones().findIndex(zoneNames_)) if (-1 != mesh.cellZones().findIndex(zoneNames_))
{ {
dict.readEntry("exposedPatchName", exposedPatchName_); dict.readIfPresent("exposedPatchName", exposedPatchName_);
if (mesh.boundaryMesh().findPatchID(exposedPatchName_) == -1)
{
FatalIOErrorInFunction(dict)
<< "Cannot find patch " << exposedPatchName_
<< " in which to put exposed faces." << endl
<< "Valid patches are " << mesh.boundaryMesh().names()
<< exit(FatalIOError);
}
DebugInfo DebugInfo
<< "Restricting to cellZone(s) " << flatOutput(zoneNames_) << "Restricting to cellZone(s) " << flatOutput(zoneNames_)
<< " with exposed internal faces into patch " << " with exposed internal faces into patch "
<< exposedPatchName_ << endl; << mesh.boundaryMesh().findPatchID(exposedPatchName_) << endl;
} }
} }

View File

@ -57,7 +57,7 @@ Usage
bounds | limit with bounding box | no | bounds | limit with bounding box | no |
zone | limit to cell zone (name or regex) | no | zone | limit to cell zone (name or regex) | no |
zones | limit to cell zones (names, regexs) | no | zones | limit to cell zones (names, regexs) | no |
exposedPatchName | name for zone subset | partly | exposedPatchName | name for zone subset | optional |
regularise | point snapping (bool or enum) | no | true regularise | point snapping (bool or enum) | no | true
mergeTol | tolerance for merging points | no | 1e-6 mergeTol | tolerance for merging points | no | 1e-6
\endtable \endtable

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2018 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,12 +27,13 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "sampledIsoSurfaceCell.H" #include "sampledIsoSurfaceCell.H"
#include "isoSurfaceCell.H"
#include "dictionary.H" #include "dictionary.H"
#include "fvMesh.H"
#include "volFields.H" #include "volFields.H"
#include "volPointInterpolation.H" #include "volPointInterpolation.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
#include "fvMesh.H" #include "fvMesh.H"
#include "isoSurfaceCell.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -65,8 +66,28 @@ bool Foam::sampledIsoSurfaceCell::updateGeometry() const
// Clear derived data // Clear derived data
sampledSurface::clearGeom(); sampledSurface::clearGeom();
// Use field from database, or try to read it in
// Handle cell zones as inverse (blocked) selection
if (!ignoreCellsPtr_)
{
ignoreCellsPtr_.reset(new bitSet);
if (-1 != mesh().cellZones().findIndex(zoneNames_))
{
bitSet select(mesh().cellZones().selection(zoneNames_));
if (select.any() && !select.all())
{
// From selection to blocking
select.flip();
*ignoreCellsPtr_ = std::move(select);
}
}
}
// Use field from database, or try to read it in
const auto* cellFldPtr = fvm.findObject<volScalarField>(isoField_); const auto* cellFldPtr = fvm.findObject<volScalarField>(isoField_);
if (debug) if (debug)
@ -111,7 +132,7 @@ bool Foam::sampledIsoSurfaceCell::updateGeometry() const
auto tpointFld = volPointInterpolation::New(fvm).interpolate(cellFld); auto tpointFld = volPointInterpolation::New(fvm).interpolate(cellFld);
// Non-averaged? Use reference // Field reference (assuming non-averaged)
tmp<scalarField> tcellValues(cellFld.primitiveField()); tmp<scalarField> tcellValues(cellFld.primitiveField());
if (average_) if (average_)
@ -139,25 +160,25 @@ bool Foam::sampledIsoSurfaceCell::updateGeometry() const
} }
} }
meshedSurface& mySurface = const_cast<sampledIsoSurfaceCell&>(*this); meshedSurface& mySurface = const_cast<sampledIsoSurfaceCell&>(*this);
{
isoSurfaceCell surf isoSurfaceCell surf
( (
fvm, fvm,
tcellValues(), tcellValues(), // A primitiveField
tpointFld().primitiveField(), tpointFld().primitiveField(),
isoVal_, isoVal_,
isoParams_ isoParams_,
*ignoreCellsPtr_
); );
mySurface.transfer(static_cast<meshedSurface&>(surf)); mySurface.transfer(static_cast<meshedSurface&>(surf));
meshCells_.transfer(surf.meshCells()); meshCells_.transfer(surf.meshCells());
}
if (debug) if (debug)
{ {
Pout<< "isoSurfaceCell::updateGeometry() : constructed iso:" Pout<< "isoSurfaceCell::updateGeometry() : constructed iso:" << nl
<< nl
<< " isoField : " << isoField_ << nl << " isoField : " << isoField_ << nl
<< " isoValue : " << isoVal_ << nl << " isoValue : " << isoVal_ << nl
<< " average : " << Switch(average_) << nl << " average : " << Switch(average_) << nl
@ -188,10 +209,24 @@ Foam::sampledIsoSurfaceCell::sampledIsoSurfaceCell
isoVal_(dict.get<scalar>("isoValue")), isoVal_(dict.get<scalar>("isoValue")),
isoParams_(dict), isoParams_(dict),
average_(dict.getOrDefault("average", true)), average_(dict.getOrDefault("average", true)),
zoneNames_(),
prevTimeIndex_(-1), prevTimeIndex_(-1),
meshCells_() meshCells_(),
ignoreCellsPtr_(nullptr)
{ {
isoParams_.algorithm(isoSurfaceParams::ALGO_CELL); // Force isoParams_.algorithm(isoSurfaceParams::ALGO_CELL); // Force
if (!dict.readIfPresent("zones", zoneNames_) && dict.found("zone"))
{
zoneNames_.resize(1);
dict.readEntry("zone", zoneNames_.first());
}
if (-1 != mesh.cellZones().findIndex(zoneNames_))
{
DebugInfo
<< "Restricting to cellZone(s) " << flatOutput(zoneNames_) << endl;
}
} }
@ -216,6 +251,8 @@ bool Foam::sampledIsoSurfaceCell::expire()
// Clear derived data // Clear derived data
sampledSurface::clearGeom(); sampledSurface::clearGeom();
ignoreCellsPtr_.reset(nullptr);
// Already marked as expired // Already marked as expired
if (prevTimeIndex_ == -1) if (prevTimeIndex_ == -1)
{ {

View File

@ -55,13 +55,12 @@ Usage
isoValue | value of iso-surface | yes | isoValue | value of iso-surface | 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 cell zone (name or regex) | no |
zones | limit to cell zones (names, regexs) | no |
regularise | point snapping | yes | regularise | point snapping | yes |
mergeTol | tolerance for merging points | no | 1e-6 mergeTol | tolerance for merging points | no | 1e-6
\endtable \endtable
Note
Does not currently support cell zones.
SourceFiles SourceFiles
sampledIsoSurfaceCell.C sampledIsoSurfaceCell.C
sampledIsoSurfaceCellTemplates.C sampledIsoSurfaceCellTemplates.C
@ -105,19 +104,28 @@ class sampledIsoSurfaceCell
//- Parameters (filtering etc) for iso-surface //- Parameters (filtering etc) for iso-surface
isoSurfaceParams isoParams_; isoSurfaceParams isoParams_;
//- Whether to recalculate cell values as average of point values //- Recalculate cell values as average of point values
bool average_; bool average_;
//- The zone or zones for the iso-surface
wordRes zoneNames_;
// Recreated for every isoSurface // Recreated for every isoSurface
//- Time at last call, also track if surface needs an update //- Time at last call, also track if surface needs an update
mutable label prevTimeIndex_; mutable label prevTimeIndex_;
//- For every triangle the original cell in mesh //- For every face the original cell in mesh (direct storage)
mutable labelList meshCells_; mutable labelList meshCells_;
// Mesh subsetting
//- Cached ignore cells for sub-mesh (zoned)
mutable autoPtr<bitSet> ignoreCellsPtr_;
// Private Member Functions // Private Member Functions
//- Create iso surface (if time has changed) //- Create iso surface (if time has changed)

View File

@ -64,30 +64,27 @@ Foam::sampledIsoSurface::sampleOnPoints
// Assume volPointInterpolation for the point field! // Assume volPointInterpolation for the point field!
const auto& volFld = interpolator.psi(); const auto& volFld = interpolator.psi();
tmp<GeometricField<Type, fvPatchField, volMesh>> tvolFld(volFld);
tmp<GeometricField<Type, pointPatchField, pointMesh>> tpointFld;
if (subMeshPtr_) if (subMeshPtr_)
{ {
auto tvolSubFld = subMeshPtr_->interpolate(volFld); // Replace with subset
const auto& volSubFld = tvolSubFld(); tvolFld.reset(subMeshPtr_->interpolate(volFld));
auto tpointFld =
volPointInterpolation::New(volSubFld.mesh()).interpolate(volSubFld);
return surface().interpolate
(
(average_ ? pointAverage(tpointFld())() : volSubFld),
tpointFld()
);
} }
// Interpolated point field
auto tpointFld = tpointFld.reset
volPointInterpolation::New(volFld.mesh()).interpolate(volFld);
return surface().interpolate
( (
(average_ ? pointAverage(tpointFld())() : volFld), volPointInterpolation::New(tvolFld().mesh()).interpolate(tvolFld())
tpointFld()
); );
if (average_)
{
tvolFld.reset(pointAverage(tpointFld()));
}
return surface().interpolate(tvolFld(), tpointFld());
} }

View File

@ -65,8 +65,28 @@ bool Foam::sampledIsoSurfaceTopo::updateGeometry() const
// Clear derived data // Clear derived data
sampledSurface::clearGeom(); sampledSurface::clearGeom();
// Use field from database, or try to read it in
// Handle cell zones as inverse (blocked) selection
if (!ignoreCellsPtr_)
{
ignoreCellsPtr_.reset(new bitSet);
if (-1 != mesh().cellZones().findIndex(zoneNames_))
{
bitSet select(mesh().cellZones().selection(zoneNames_));
if (select.any() && !select.all())
{
// From selection to blocking
select.flip();
*ignoreCellsPtr_ = std::move(select);
}
}
}
// Use field from database, or try to read it in
const auto* cellFldPtr = fvm.findObject<volScalarField>(isoField_); const auto* cellFldPtr = fvm.findObject<volScalarField>(isoField_);
if (debug) if (debug)
@ -111,19 +131,50 @@ bool Foam::sampledIsoSurfaceTopo::updateGeometry() const
auto tpointFld = volPointInterpolation::New(fvm).interpolate(cellFld); auto tpointFld = volPointInterpolation::New(fvm).interpolate(cellFld);
Mesh& mySurface = const_cast<sampledIsoSurfaceTopo&>(*this); // Field reference (assuming non-averaged)
tmp<scalarField> tcellValues(cellFld.primitiveField());
if (average_)
{
// From point field and interpolated cell.
tcellValues = tmp<scalarField>::New(fvm.nCells(), Zero);
auto& cellAvg = tcellValues.ref();
labelField nPointCells(fvm.nCells(), Zero);
for (label pointi = 0; pointi < fvm.nPoints(); ++pointi)
{
const scalar& val = tpointFld().primitiveField()[pointi];
const labelList& pCells = fvm.pointCells(pointi);
for (const label celli : pCells)
{
cellAvg[celli] += val;
++nPointCells[celli];
}
}
forAll(cellAvg, celli)
{
cellAvg[celli] /= nPointCells[celli];
}
}
meshedSurface& mySurface = const_cast<sampledIsoSurfaceTopo&>(*this);
{
isoSurfaceTopo surf isoSurfaceTopo surf
( (
fvm, fvm,
cellFld.primitiveField(), cellFld.primitiveField(),
tpointFld().primitiveField(), tpointFld().primitiveField(),
isoVal_, isoVal_,
isoParams_ isoParams_,
*ignoreCellsPtr_
); );
mySurface.transfer(static_cast<meshedSurface&>(surf)); mySurface.transfer(static_cast<meshedSurface&>(surf));
meshCells_ = std::move(surf.meshCells()); meshCells_.transfer(surf.meshCells());
}
// triangulate uses remapFaces() // triangulate uses remapFaces()
// - this is somewhat less efficient since it recopies the faces // - this is somewhat less efficient since it recopies the faces
@ -141,6 +192,7 @@ bool Foam::sampledIsoSurfaceTopo::updateGeometry() const
Pout<< "isoSurfaceTopo::updateGeometry() : constructed iso:" << nl Pout<< "isoSurfaceTopo::updateGeometry() : constructed iso:" << nl
<< " isoField : " << isoField_ << nl << " isoField : " << isoField_ << nl
<< " isoValue : " << isoVal_ << nl << " isoValue : " << isoVal_ << nl
<< " average : " << Switch(average_) << nl
<< " filter : " << " filter : "
<< isoSurfaceParams::filterNames[isoParams_.filter()] << nl << isoSurfaceParams::filterNames[isoParams_.filter()] << nl
<< " triangulate : " << Switch(triangulate_) << nl << " triangulate : " << Switch(triangulate_) << nl
@ -168,9 +220,12 @@ Foam::sampledIsoSurfaceTopo::sampledIsoSurfaceTopo
isoField_(dict.get<word>("isoField")), isoField_(dict.get<word>("isoField")),
isoVal_(dict.get<scalar>("isoValue")), isoVal_(dict.get<scalar>("isoValue")),
isoParams_(dict), isoParams_(dict),
average_(dict.getOrDefault("average", false)),
triangulate_(dict.getOrDefault("triangulate", false)), triangulate_(dict.getOrDefault("triangulate", false)),
zoneNames_(),
prevTimeIndex_(-1), prevTimeIndex_(-1),
meshCells_() meshCells_(),
ignoreCellsPtr_(nullptr)
{ {
isoParams_.algorithm(isoSurfaceParams::ALGO_TOPO); // Force isoParams_.algorithm(isoSurfaceParams::ALGO_TOPO); // Force
@ -184,6 +239,18 @@ Foam::sampledIsoSurfaceTopo::sampledIsoSurfaceTopo
<< "Cannot triangulate without a regularise filter" << nl << "Cannot triangulate without a regularise filter" << nl
<< exit(FatalIOError); << exit(FatalIOError);
} }
if (!dict.readIfPresent("zones", zoneNames_) && dict.found("zone"))
{
zoneNames_.resize(1);
dict.readEntry("zone", zoneNames_.first());
}
if (-1 != mesh.cellZones().findIndex(zoneNames_))
{
DebugInfo
<< "Restricting to cellZone(s) " << flatOutput(zoneNames_) << endl;
}
} }
@ -208,6 +275,8 @@ bool Foam::sampledIsoSurfaceTopo::expire()
// Clear derived data // Clear derived data
sampledSurface::clearGeom(); sampledSurface::clearGeom();
ignoreCellsPtr_.reset(nullptr);
// Already marked as expired // Already marked as expired
if (prevTimeIndex_ == -1) if (prevTimeIndex_ == -1)
{ {

View File

@ -53,13 +53,14 @@ Usage
type | isoSurfaceTopo | yes | type | isoSurfaceTopo | yes |
isoField | field name for obtaining iso-surface | yes | isoField | field name for obtaining iso-surface | yes |
isoValue | value of iso-surface | yes | isoValue | value of iso-surface | yes |
average | cell values from averaged point values | no | false
bounds | limit with bounding box | no |
zone | limit to cell zone (name or regex) | no |
zones | limit to cell zones (names, regexs) | no |
regularise | filter faces (bool or enum) | no | true regularise | filter faces (bool or enum) | no | true
triangulate | triangulate faces (requires regularise) | no | false triangulate | triangulate faces (requires regularise) | no | false
\endtable \endtable
Note
Does not currently support cell zones.
SourceFiles SourceFiles
sampledIsoSurfaceTopo.C sampledIsoSurfaceTopo.C
sampledIsoSurfaceTopoTemplates.C sampledIsoSurfaceTopoTemplates.C
@ -103,19 +104,32 @@ class sampledIsoSurfaceTopo
//- Parameters (filtering etc) for iso-surface //- Parameters (filtering etc) for iso-surface
isoSurfaceParams isoParams_; isoSurfaceParams isoParams_;
//- Recalculate cell values as average of point values?
bool average_;
//- Whether to triangulate (after filtering) //- Whether to triangulate (after filtering)
bool triangulate_; bool triangulate_;
//- The zone or zones for the iso-surface
wordRes zoneNames_;
// Recreated for every isoSurface // Recreated for every isoSurface
//- Time at last call, also track it surface needs an update //- Time at last call, also track it surface needs an update
mutable label prevTimeIndex_; mutable label prevTimeIndex_;
//- For every triangle/face the original cell in mesh //- For every face the original cell in mesh (direct storage)
mutable labelList meshCells_; mutable labelList meshCells_;
// Mesh subsetting
//- Cached ignore cells for sub-mesh (zoned)
mutable autoPtr<bitSet> ignoreCellsPtr_;
// Private Member Functions // Private Member Functions
//- Create iso surface (if time has changed) //- Create iso surface (if time has changed)

View File

@ -124,18 +124,16 @@ void Foam::sampledCuttingPlane::createGeometry()
&& (-1 != mesh().cellZones().findIndex(zoneNames_)) && (-1 != mesh().cellZones().findIndex(zoneNames_))
) )
{ {
const polyBoundaryMesh& patches = mesh().boundaryMesh(); const label exposedPatchi =
mesh().boundaryMesh().findPatchID(exposedPatchName_);
// Patch to put exposed internal faces into bitSet cellsToSelect(mesh().cellZones().selection(zoneNames_));
const label exposedPatchi = patches.findPatchID(exposedPatchName_);
bitSet cellsToSelect = mesh().cellZones().selection(zoneNames_);
DebugInfo DebugInfo
<< "Allocating subset of size " << "Allocating subset of size "
<< cellsToSelect.count() << cellsToSelect.count()
<< " with exposed faces into patch " << " with exposed faces into patch "
<< patches[exposedPatchi].name() << endl; << exposedPatchi << endl;
// If we will use a fvMeshSubset so can apply bounds as well to make // If we will use a fvMeshSubset so can apply bounds as well to make
@ -161,7 +159,10 @@ void Foam::sampledCuttingPlane::createGeometry()
<< cellsToSelect.count() << endl; << cellsToSelect.count() << endl;
} }
subMeshPtr_.reset(new fvMeshSubset(fvm, cellsToSelect, exposedPatchi)); subMeshPtr_.reset
(
new fvMeshSubset(fvm, cellsToSelect, exposedPatchi)
);
} }
@ -209,11 +210,11 @@ void Foam::sampledCuttingPlane::createGeometry()
} }
} }
// Patch fields
{
volScalarField::Boundary& cellDistanceBf = volScalarField::Boundary& cellDistanceBf =
cellDistance.boundaryFieldRef(); cellDistance.boundaryFieldRef();
// Patch fields
{
forAll(cellDistanceBf, patchi) forAll(cellDistanceBf, patchi)
{ {
if if
@ -387,21 +388,12 @@ Foam::sampledCuttingPlane::sampledCuttingPlane
if (-1 != mesh.cellZones().findIndex(zoneNames_)) if (-1 != mesh.cellZones().findIndex(zoneNames_))
{ {
dict.readEntry("exposedPatchName", exposedPatchName_); dict.readIfPresent("exposedPatchName", exposedPatchName_);
if (-1 == mesh.boundaryMesh().findPatchID(exposedPatchName_))
{
FatalIOErrorInFunction(dict)
<< "Cannot find patch " << exposedPatchName_
<< " in which to put exposed faces." << endl
<< "Valid patches are " << mesh.boundaryMesh().names()
<< exit(FatalError);
}
DebugInfo DebugInfo
<< "Restricting to cellZone(s) " << flatOutput(zoneNames_) << "Restricting to cellZone(s) " << flatOutput(zoneNames_)
<< " with exposed internal faces into patch " << " with exposed internal faces into patch "
<< exposedPatchName_ << endl; << mesh.boundaryMesh().findPatchID(exposedPatchName_) << endl;
} }
} }

View File

@ -55,13 +55,13 @@ Usage
Property | Description | Required | Default Property | Description | Required | Default
type | cuttingPlane | yes | type | cuttingPlane | yes |
planeType | plane description (pointAndNormal etc) | yes | planeType | plane description (pointAndNormal etc) | yes |
mergeTol | tolerance for merging points | no | 1e-6
isoMethod | Iso-algorithm (cell/topo/point) | no | topo isoMethod | Iso-algorithm (cell/topo/point) | no | topo
regularise | Face simplification (enum or bool) | no | true
bounds | limit with bounding box | no | bounds | limit with bounding box | no |
zone | limit to cell zone (name or regex) | no | zone | limit to cell zone (name or regex) | no |
zones | limit to cell zones (names, regexs) | no | zones | limit to cell zones (names, regexs) | no |
exposedPatchName | name for zone subset | partly | exposedPatchName | name for zone subset | optional |
regularise | Face simplification (enum or bool) | no | true
mergeTol | tolerance for merging points | no | 1e-6
\endtable \endtable
Note Note

View File

@ -60,30 +60,27 @@ Foam::sampledCuttingPlane::sampleOnPoints
// Assume volPointInterpolation for the point field! // Assume volPointInterpolation for the point field!
const auto& volFld = interpolator.psi(); const auto& volFld = interpolator.psi();
tmp<GeometricField<Type, fvPatchField, volMesh>> tvolFld(volFld);
tmp<GeometricField<Type, pointPatchField, pointMesh>> tpointFld;
if (subMeshPtr_) if (subMeshPtr_)
{ {
auto tvolSubFld = subMeshPtr_->interpolate(volFld); // Replace with subset
const auto& volSubFld = tvolSubFld(); tvolFld.reset(subMeshPtr_->interpolate(volFld));
auto tpointFld =
volPointInterpolation::New(volSubFld.mesh()).interpolate(volSubFld);
return this->isoSurfaceInterpolate
(
(average_ ? pointAverage(tpointFld())() : volSubFld),
tpointFld()
);
} }
// Interpolated point field
auto tpointFld = tpointFld.reset
volPointInterpolation::New(volFld.mesh()).interpolate(volFld);
return this->isoSurfaceInterpolate
( (
(average_ ? pointAverage(tpointFld())() : volFld), volPointInterpolation::New(tvolFld().mesh()).interpolate(tvolFld())
tpointFld()
); );
if (average_)
{
tvolFld.reset(pointAverage(tpointFld()));
}
return this->isoSurfaceInterpolate(tvolFld(), tpointFld());
} }

View File

@ -58,27 +58,35 @@ bool Foam::sampledInterface::updateGeometry() const
return false; return false;
} }
// Get any subMesh prevTimeIndex_ = fvm.time().timeIndex();
if (!subMeshPtr_ && zoneID_.index() != -1)
// Not really being used...
// Get sub-mesh if any
if
(
!subMeshPtr_
&& (-1 != mesh().cellZones().findIndex(zoneNames_))
)
{ {
const cellZone& cz = mesh().cellZones()[zoneID_.index()]; const label exposedPatchi =
mesh().boundaryMesh().findPatchID(exposedPatchName_);
const polyBoundaryMesh& patches = mesh().boundaryMesh(); bitSet cellsToSelect(mesh().cellZones().selection(zoneNames_));
// Patch to put exposed internal faces into
const label exposedPatchi = patches.findPatchID(exposedPatchName_);
DebugInfo DebugInfo
<< "Allocating subset of size " << cz.size() << "Allocating subset of size "
<< cellsToSelect.count()
<< " with exposed faces into patch " << " with exposed faces into patch "
<< patches[exposedPatchi].name() << endl; << exposedPatchi << endl;
subMeshPtr_.reset(new fvMeshSubset(fvm, cz, exposedPatchi)); subMeshPtr_.reset
(
new fvMeshSubset(fvm, cellsToSelect, exposedPatchi)
);
} }
prevTimeIndex_ = fvm.time().timeIndex();
// Clear any stored topo // Clear any stored topo
surfPtr_.clear(); surfPtr_.clear();
@ -110,29 +118,26 @@ Foam::sampledInterface::sampledInterface
) )
: :
sampledSurface(name, mesh, dict), sampledSurface(name, mesh, dict),
zoneID_(dict.getOrDefault<word>("zone", word::null), mesh.cellZones()), zoneNames_(),
exposedPatchName_(word::null), exposedPatchName_(),
surfPtr_(nullptr), surfPtr_(nullptr),
prevTimeIndex_(-1), prevTimeIndex_(-1),
subMeshPtr_(nullptr) subMeshPtr_(nullptr)
{ {
if (zoneID_.index() != -1) if (!dict.readIfPresent("zones", zoneNames_) && dict.found("zone"))
{ {
dict.readEntry("exposedPatchName", exposedPatchName_); zoneNames_.resize(1);
dict.readEntry("zone", zoneNames_.first());
if (mesh.boundaryMesh().findPatchID(exposedPatchName_) == -1)
{
FatalIOErrorInFunction(dict)
<< "Cannot find patch " << exposedPatchName_
<< " in which to put exposed faces." << endl
<< "Valid patches are " << mesh.boundaryMesh().names()
<< exit(FatalIOError);
} }
if (-1 != mesh.cellZones().findIndex(zoneNames_))
{
dict.readIfPresent("exposedPatchName", exposedPatchName_);
DebugInfo DebugInfo
<< "Restricting to cellZone " << zoneID_.name() << "Restricting to cellZone " << flatOutput(zoneNames_)
<< " with exposed internal faces into patch " << " with exposed internal faces into patch "
<< exposedPatchName_ << endl; << mesh.boundaryMesh().findPatchID(exposedPatchName_) << endl;
} }
} }

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020 DLR Copyright (C) 2020 DLR
Copyright (C) 2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -81,14 +82,15 @@ class sampledInterface
{ {
// Private Data // Private Data
//- Zone name/index (if restricted to zones) //- Restrict to given cell zones
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_;
mutable autoPtr<reconstructionSchemes::interface> surfPtr_; mutable autoPtr<reconstructionSchemes::interface> surfPtr_;
// Recreated for every interface // Recreated for every interface
//- Time at last call, also track if surface needs an update //- Time at last call, also track if surface needs an update