mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
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:
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user