diff --git a/src/sampling/Make/files b/src/sampling/Make/files index 72b78a465667c85aa76eb5a30aa5dc4c86c8c971..f7d9f7d4b490c37da7dc6ae0e3dd02ba12c13d86 100644 --- a/src/sampling/Make/files +++ b/src/sampling/Make/files @@ -43,6 +43,7 @@ sampledSurface/sampledPatchInternalField/sampledPatchInternalField.C sampledSurface/sampledPlane/sampledPlane.C sampledSurface/isoSurface/sampledIsoSurface.C sampledSurface/isoSurface/sampledIsoSurfaceCell.C +sampledSurface/isoSurface/sampledIsoSurfacePoint.C sampledSurface/isoSurface/sampledIsoSurfaceTopo.C sampledSurface/distanceSurface/sampledDistanceSurface.C sampledSurface/sampledCuttingPlane/sampledCuttingPlane.C diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.C b/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.C index 37a7618967aba80f933fc89500d0255970f5abb3..bd12eed92cb0417e32568ee31e364437dda92eaa 100644 --- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.C +++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.C @@ -27,12 +27,12 @@ License \*---------------------------------------------------------------------------*/ #include "sampledIsoSurface.H" -#include "isoSurfacePoint.H" #include "dictionary.H" #include "fvMesh.H" #include "volFields.H" #include "volPointInterpolation.H" #include "addToRunTimeSelectionTable.H" +#include "PtrList.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -46,13 +46,6 @@ namespace Foam word, isoSurface ); - addNamedToRunTimeSelectionTable - ( - sampledSurface, - sampledIsoSurface, - word, - isoSurfacePoint - ); } // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -312,6 +305,111 @@ void Foam::sampledIsoSurface::getIsoFields() const } +void Foam::sampledIsoSurface::combineSurfaces +( + PtrList<isoSurfaceBase>& isoSurfPtrs +) +{ + isoSurfacePtr_.reset(nullptr); + + // Already checked previously for ALGO_POINT, but do it again + // - ALGO_POINT still needs fields (for interpolate) + // The others can do straight transfer + if + ( + isoParams_.algorithm() == isoSurfaceParams::ALGO_POINT + && isoSurfPtrs.size() == 1 + ) + { + // Shift from list to autoPtr + isoSurfacePtr_.reset(isoSurfPtrs.release(0)); + } + else if (isoSurfPtrs.size() == 1) + { + autoPtr<isoSurfaceBase> ptr(isoSurfPtrs.release(0)); + auto& surf = *ptr; + + surface_.transfer(static_cast<meshedSurface&>(surf)); + meshCells_.transfer(surf.meshCells()); + } + else + { + // Combine faces with point offsets + // + // Note: use points().size() from surface, not nPoints() + // since there may be uncompacted dangling nodes + + label nFaces = 0, nPoints = 0; + + for (const auto& surf : isoSurfPtrs) + { + nFaces += surf.size(); + nPoints += surf.points().size(); + } + + faceList newFaces(nFaces); + pointField newPoints(nPoints); + meshCells_.resize(nFaces); + + surfZoneList newZones(isoSurfPtrs.size()); + + nFaces = 0; + nPoints = 0; + forAll(isoSurfPtrs, surfi) + { + autoPtr<isoSurfaceBase> ptr(isoSurfPtrs.release(surfi)); + auto& surf = *ptr; + + SubList<face> subFaces(newFaces, surf.size(), nFaces); + SubList<point> subPoints(newPoints, surf.points().size(), nPoints); + SubList<label> subCells(meshCells_, surf.size(), nFaces); + + newZones[surfi] = surfZone + ( + surfZoneIdentifier::defaultName(surfi), + subFaces.size(), // size + nFaces, // start + surfi // index + ); + + subFaces = surf.surfFaces(); + subPoints = surf.points(); + subCells = surf.meshCells(); + + if (nPoints) + { + for (face& f : subFaces) + { + for (label& pointi : f) + { + pointi += nPoints; + } + } + } + + nFaces += subFaces.size(); + nPoints += subPoints.size(); + } + + meshedSurface combined + ( + std::move(newPoints), + std::move(newFaces), + newZones + ); + + surface_.transfer(combined); + } + + // Addressing into the full mesh + if (subMeshPtr_ && meshCells_.size()) + { + meshCells_ = + UIndirectList<label>(subMeshPtr_->cellMap(), meshCells_); + } +} + + bool Foam::sampledIsoSurface::updateGeometry() const { const fvMesh& fvm = static_cast<const fvMesh&>(mesh()); @@ -332,34 +430,76 @@ bool Foam::sampledIsoSurface::updateGeometry() const // Clear derived data sampledSurface::clearGeom(); + const bool hasCellZones = + (-1 != mesh().cellZones().findIndex(zoneNames_)); - // Get sub-mesh if any + // Geometry if ( - !subMeshPtr_ - && (-1 != mesh().cellZones().findIndex(zoneNames_)) + simpleSubMesh_ + && isoParams_.algorithm() != isoSurfaceParams::ALGO_POINT ) { - const label exposedPatchi = - mesh().boundaryMesh().findPatchID(exposedPatchName_); + subMeshPtr_.reset(nullptr); - DebugInfo - << "Allocating subset of size " - << mesh().cellZones().selection(zoneNames_).count() - << " with exposed faces into patch " - << exposedPatchi << endl; + // Handle cell zones as inverse (blocked) selection + if (!ignoreCellsPtr_) + { + ignoreCellsPtr_.reset(new bitSet); - subMeshPtr_.reset - ( - new fvMeshSubset + if (hasCellZones) + { + bitSet select(mesh().cellZones().selection(zoneNames_)); + + if (select.any() && !select.all()) + { + // From selection to blocking + select.flip(); + + *ignoreCellsPtr_ = std::move(select); + } + } + } + } + else + { + // A standard subMesh treatment + + if (ignoreCellsPtr_) + { + ignoreCellsPtr_->clearStorage(); + } + else + { + ignoreCellsPtr_.reset(new bitSet); + } + + // Get sub-mesh if any + if (!subMeshPtr_ && hasCellZones) + { + const label exposedPatchi = + mesh().boundaryMesh().findPatchID(exposedPatchName_); + + DebugInfo + << "Allocating subset of size " + << mesh().cellZones().selection(zoneNames_).count() + << " with exposed faces into patch " + << exposedPatchi << endl; + + subMeshPtr_.reset ( - fvm, - mesh().cellZones().selection(zoneNames_), - exposedPatchi - ) - ); + new fvMeshSubset + ( + fvm, + mesh().cellZones().selection(zoneNames_), + exposedPatchi + ) + ); + } } + + // The fields getIsoFields(); refPtr<volScalarField> tvolFld(*volFieldPtr_); @@ -371,23 +511,53 @@ bool Foam::sampledIsoSurface::updateGeometry() const tpointFld.cref(*pointSubFieldPtr_); } - isoSurfacePtr_.reset - ( - new isoSurfacePoint + + // Create surfaces for each iso level + + PtrList<isoSurfaceBase> isoSurfPtrs(isoValues_.size()); + + forAll(isoValues_, surfi) + { + isoSurfPtrs.set ( - tvolFld(), - tpointFld(), - isoVal_, - isoParams_ - ) - ); + surfi, + isoSurfaceBase::New + ( + isoParams_, + tvolFld(), + tpointFld().primitiveField(), + isoValues_[surfi], + *ignoreCellsPtr_ + ) + ); + } + + // And flatten + const_cast<sampledIsoSurface&>(*this) + .combineSurfaces(isoSurfPtrs); + // triangulate uses remapFaces() + // - this is somewhat less efficient since it recopies the faces + // that we just created, but we probably don't want to do this + // too often anyhow. + if + ( + triangulate_ + && surface_.size() + && (isoParams_.algorithm() == isoSurfaceParams::ALGO_TOPO) + ) + { + labelList faceMap; + surface_.triangulate(faceMap); + meshCells_ = UIndirectList<label>(meshCells_, faceMap)(); + } + if (debug) { - Pout<< "isoSurfacePoint::updateGeometry() : constructed iso:" << nl - << " isoField : " << isoField_ << nl - << " isoValue : " << isoVal_ << nl + Pout<< "isoSurface::updateGeometry() : constructed iso:" << nl + << " field : " << isoField_ << nl + << " value : " << flatOutput(isoValues_) << nl << " average : " << Switch(average_) << nl << " filter : " << Switch(bool(isoParams_.filter())) << nl @@ -411,6 +581,7 @@ bool Foam::sampledIsoSurface::updateGeometry() const Foam::sampledIsoSurface::sampledIsoSurface ( + const isoSurfaceParams& params, const word& name, const polyMesh& mesh, const dictionary& dict @@ -418,33 +589,103 @@ Foam::sampledIsoSurface::sampledIsoSurface : sampledSurface(name, mesh, dict), isoField_(dict.get<word>("isoField")), - isoVal_(dict.get<scalar>("isoValue")), - isoParams_(dict), + isoValues_(), + isoParams_(dict, params), average_(dict.getOrDefault("average", false)), + triangulate_(dict.getOrDefault("triangulate", false)), + simpleSubMesh_(dict.getOrDefault("simpleSubMesh", false)), zoneNames_(), exposedPatchName_(), prevTimeIndex_(-1), + surface_(), meshCells_(), isoSurfacePtr_(nullptr), + + subMeshPtr_(nullptr), + ignoreCellsPtr_(nullptr), + storedVolFieldPtr_(nullptr), volFieldPtr_(nullptr), pointFieldPtr_(nullptr), - subMeshPtr_(nullptr), + storedVolSubFieldPtr_(nullptr), volSubFieldPtr_(nullptr), pointSubFieldPtr_(nullptr) { - isoParams_.algorithm(isoSurfaceParams::ALGO_POINT); // Force + if (params.algorithm() != isoSurfaceParams::ALGO_DEFAULT) + { + // Forced use of specified algorithm (ignore dictionary entry) + isoParams_.algorithm(params.algorithm()); + } + + // The isoValues or isoValue + + if (!dict.readIfPresent("isoValues", isoValues_)) + { + isoValues_.resize(1); + dict.readEntry("isoValue", isoValues_.first()); + } - if (!sampledSurface::interpolate()) + if (isoValues_.empty()) { FatalIOErrorInFunction(dict) - << "Non-interpolated iso surface not supported since triangles" - << " span across cells." << nl + << "No isoValue or isoValues specified." << nl << exit(FatalIOError); } + if (isoValues_.size() > 1) + { + const label nOrig = isoValues_.size(); + + inplaceUniqueSort(isoValues_); + + if (nOrig != isoValues_.size()) + { + IOWarningInFunction(dict) + << "Removed non-unique isoValues" << nl; + } + } + + if (isoParams_.algorithm() == isoSurfaceParams::ALGO_POINT) + { + // Not possible for ALGO_POINT + simpleSubMesh_ = false; + + if (!sampledSurface::interpolate()) + { + FatalIOErrorInFunction(dict) + << "Non-interpolated iso-surface (point) not supported" + << " since triangles span across cells." << nl + << exit(FatalIOError); + } + + if (isoValues_.size() > 1) + { + FatalIOErrorInFunction(dict) + << "Multiple values on iso-surface (point) not supported" + << " since needs original interpolators." << nl + << exit(FatalIOError); + } + } + + if (isoParams_.algorithm() == isoSurfaceParams::ALGO_TOPO) + { + if + ( + triangulate_ + && (isoParams_.filter() == isoSurfaceParams::filterType::NONE) + ) + { + FatalIOErrorInFunction(dict) + << "Cannot triangulate without a regularise filter" << nl + << exit(FatalIOError); + } + } + + + // Zones + if (!dict.readIfPresent("zones", zoneNames_) && dict.found("zone")) { zoneNames_.resize(1); @@ -463,6 +704,17 @@ Foam::sampledIsoSurface::sampledIsoSurface } +Foam::sampledIsoSurface::sampledIsoSurface +( + const word& name, + const polyMesh& mesh, + const dictionary& dict +) +: + sampledIsoSurface(isoSurfaceParams(), name, mesh, dict) +{} + + // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::sampledIsoSurface::~sampledIsoSurface() @@ -610,7 +862,7 @@ void Foam::sampledIsoSurface::print(Ostream& os) const { os << "isoSurfacePoint: " << name() << " :" << " field :" << isoField_ - << " value :" << isoVal_; + << " value :" << flatOutput(isoValues_); } diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.H b/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.H index 24990814693d61ec0c89fbb5fee2892fddc32cd1..b78aa1dcbbdaadd0ee2f1fd978623f2a06fc1267 100644 --- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.H +++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.H @@ -28,8 +28,7 @@ Class Foam::sampledIsoSurface Description - A sampledSurface defined by a surface of iso value using a - \em point algorithm (always triangulated!). + A sampledSurface defined by a surface of iso value. It only recalculates the iso-surface if time changes. To be used in sampleSurfaces / functionObjects. @@ -40,9 +39,10 @@ Usage { surface1 { - type isoSurfacePoint; + type isoSurface; isoField T; isoValue 373; + isoMethod topo; } } \endverbatim @@ -50,18 +50,26 @@ Usage Where the sub-entries comprise: \table Property | Description | Required | Default - type | isoSurfacePoint / isoSurface | yes | + type | isoSurface | yes | isoField | field name for obtaining iso-surface | yes | isoValue | value of iso-surface | yes | + isoValues| values for iso-surfaces | yes | + isoMethod | Iso-algorithm (cell/topo/point) | no | topo 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 | + simpleSubMesh | Simple sub-meshing in algorithm itself | no | false exposedPatchName | name for zone subset | optional | regularise | point snapping (bool or enum) | no | true + triangulate | triangulate faces (if regularise) | no | false mergeTol | tolerance for merging points | no | 1e-6 \endtable + Some options are limited to particular algorithms. + - triangulate is topo-only + - simpleSubMesh and multiple isoValues are not available for point. + SourceFiles sampledIsoSurface.C sampledIsoSurfaceTemplates.C @@ -71,9 +79,9 @@ SourceFiles #ifndef sampledIsoSurface_H #define sampledIsoSurface_H -#include "isoSurfacePoint.H" #include "sampledSurface.H" #include "fvMeshSubset.H" +#include "isoSurfaceBase.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -93,8 +101,8 @@ class sampledIsoSurface //- Field to get isoSurface of const word isoField_; - //- Iso value - const scalar isoVal_; + //- The iso-value(s) + List<scalar> isoValues_; //- Parameters (filtering etc) for iso-surface isoSurfaceParams isoParams_; @@ -102,6 +110,12 @@ class sampledIsoSurface //- Whether to recalculate cell values as average of point values bool average_; + //- Whether to triangulate ALGO_TOPO (after filtering) + bool triangulate_; + + //- Use simple sub-meshing in algorithm itself + bool simpleSubMesh_; + //- The zone or zones for the iso-surface wordRes zoneNames_; @@ -121,7 +135,16 @@ class sampledIsoSurface mutable labelList meshCells_; //- Extracted iso-surface, for interpolators - mutable autoPtr<isoSurfacePoint> isoSurfacePtr_; + mutable autoPtr<isoSurfaceBase> isoSurfacePtr_; + + + // Mesh Subsetting + + //- Cached subMesh for (pre-)subset of cell zones + mutable autoPtr<fvMeshSubset> subMeshPtr_; + + //- Cached ignore cells for (post-)subset of cell zones + mutable autoPtr<bitSet> ignoreCellsPtr_; // Fields @@ -133,10 +156,8 @@ class sampledIsoSurface //- Cached pointfield mutable const pointScalarField* pointFieldPtr_; - // And on subsetted mesh - //- Cached submesh - mutable autoPtr<fvMeshSubset> subMeshPtr_; + // And on (pre-)subsetted mesh //- Cached volfield mutable autoPtr<volScalarField> storedVolSubFieldPtr_; @@ -151,6 +172,9 @@ class sampledIsoSurface //- Get fields needed to recreate iso surface. void getIsoFields() const; + //- Collect iso-surfaces into a single surface (No point merging) + void combineSurfaces(PtrList<isoSurfaceBase>& isoSurfPtrs); + //- Create iso surface (if time has changed) // Do nothing (and return false) if no update was needed bool updateGeometry() const; @@ -196,6 +220,15 @@ public: // Constructors + //- Construct from dictionary + sampledIsoSurface + ( + const isoSurfaceParams& params, + const word& name, + const polyMesh& mesh, + const dictionary& dict + ); + //- Construct from dictionary sampledIsoSurface ( diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.C b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.C index cc83106d317365c6bc473455055a1667d36f795a..d28cd2997208fce674efbb61926257678b51c105 100644 --- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.C +++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.C @@ -5,8 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2016-2020 OpenCFD Ltd. + Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,19 +26,13 @@ License \*---------------------------------------------------------------------------*/ #include "sampledIsoSurfaceCell.H" -#include "isoSurfaceCell.H" -#include "dictionary.H" -#include "fvMesh.H" -#include "volFields.H" -#include "volPointInterpolation.H" #include "addToRunTimeSelectionTable.H" -#include "fvMesh.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { - defineTypeNameAndDebug(sampledIsoSurfaceCell, 0); + defineTypeName(sampledIsoSurfaceCell); addNamedToRunTimeSelectionTable ( sampledSurface, @@ -49,161 +42,6 @@ namespace Foam ); } -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -bool Foam::sampledIsoSurfaceCell::updateGeometry() const -{ - const fvMesh& fvm = static_cast<const fvMesh&>(mesh()); - - // No update needed - if (fvm.time().timeIndex() == prevTimeIndex_) - { - return false; - } - - prevTimeIndex_ = fvm.time().timeIndex(); - - // Clear any previously stored topologies - surface_.clear(); - meshCells_.clear(); - isoSurfacePtr_.reset(nullptr); - - // Clear derived data - sampledSurface::clearGeom(); - - - // 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_); - - if (debug) - { - if (cellFldPtr) - { - InfoInFunction << "Lookup " << isoField_ << endl; - } - else - { - InfoInFunction - << "Reading " << isoField_ - << " from time " << fvm.time().timeName() - << endl; - } - } - - // For holding the volScalarField read in. - autoPtr<volScalarField> fieldReadPtr; - - if (!cellFldPtr) - { - // Bit of a hack. Read field and store. - - fieldReadPtr = autoPtr<volScalarField>::New - ( - IOobject - ( - isoField_, - fvm.time().timeName(), - fvm, - IOobject::MUST_READ, - IOobject::NO_WRITE, - false - ), - fvm - ); - } - - const volScalarField& cellFld = - (fieldReadPtr ? *fieldReadPtr : *cellFldPtr); - - auto tpointFld = volPointInterpolation::New(fvm).interpolate(cellFld); - - // 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]; - } - } - - { - isoSurfaceCell surf - ( - fvm, - tcellValues(), // A primitiveField - tpointFld().primitiveField(), - isoVal_, - isoParams_, - *ignoreCellsPtr_ - ); - - surface_.transfer(static_cast<meshedSurface&>(surf)); - meshCells_.transfer(surf.meshCells()); - } - - // if (subMeshPtr_ && meshCells_.size()) - // { - // // With the correct addressing into the full mesh - // meshCells_ = - // UIndirectList<label>(subMeshPtr_->cellMap(), meshCells_); - // } - - if (debug) - { - Pout<< "isoSurfaceCell::updateGeometry() : constructed iso:" << nl - << " isoField : " << isoField_ << nl - << " isoValue : " << isoVal_ << nl - << " average : " << Switch(average_) << nl - << " filter : " - << Switch(bool(isoParams_.filter())) << nl - << " bounds : " << isoParams_.getClipBounds() << nl - << " points : " << points().size() << nl - << " faces : " << surface().size() << nl - << " cut cells : " << meshCells().size() << endl; - } - - return true; -} - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // @@ -214,185 +52,14 @@ Foam::sampledIsoSurfaceCell::sampledIsoSurfaceCell const dictionary& dict ) : - sampledSurface(name, mesh, dict), - isoField_(dict.get<word>("isoField")), - isoVal_(dict.get<scalar>("isoValue")), - isoParams_(dict), - average_(dict.getOrDefault("average", true)), - zoneNames_(), - prevTimeIndex_(-1), - surface_(), - meshCells_(), - isoSurfacePtr_(nullptr) -{ - 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; - } -} - - -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - -Foam::sampledIsoSurfaceCell::~sampledIsoSurfaceCell() + sampledIsoSurface + ( + isoSurfaceParams(isoSurfaceParams::ALGO_CELL), + name, + mesh, + dict + ) {} -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -bool Foam::sampledIsoSurfaceCell::needsUpdate() const -{ - const fvMesh& fvm = static_cast<const fvMesh&>(mesh()); - - return fvm.time().timeIndex() != prevTimeIndex_; -} - - -bool Foam::sampledIsoSurfaceCell::expire() -{ - surface_.clear(); - meshCells_.clear(); - isoSurfacePtr_.reset(nullptr); - - // Clear derived data - sampledSurface::clearGeom(); - - ignoreCellsPtr_.reset(nullptr); - - // Already marked as expired - if (prevTimeIndex_ == -1) - { - return false; - } - - // Force update - prevTimeIndex_ = -1; - return true; -} - - -bool Foam::sampledIsoSurfaceCell::update() -{ - return updateGeometry(); -} - - -Foam::tmp<Foam::scalarField> -Foam::sampledIsoSurfaceCell::sample -( - const interpolation<scalar>& sampler -) const -{ - return sampleOnFaces(sampler); -} - - -Foam::tmp<Foam::vectorField> -Foam::sampledIsoSurfaceCell::sample -( - const interpolation<vector>& sampler -) const -{ - return sampleOnFaces(sampler); -} - - -Foam::tmp<Foam::sphericalTensorField> -Foam::sampledIsoSurfaceCell::sample -( - const interpolation<sphericalTensor>& sampler -) const -{ - return sampleOnFaces(sampler); -} - - -Foam::tmp<Foam::symmTensorField> -Foam::sampledIsoSurfaceCell::sample -( - const interpolation<symmTensor>& sampler -) const -{ - return sampleOnFaces(sampler); -} - - -Foam::tmp<Foam::tensorField> -Foam::sampledIsoSurfaceCell::sample -( - const interpolation<tensor>& sampler -) const -{ - return sampleOnFaces(sampler); -} - - -Foam::tmp<Foam::scalarField> -Foam::sampledIsoSurfaceCell::interpolate -( - const interpolation<scalar>& interpolator -) const -{ - return sampleOnPoints(interpolator); -} - - -Foam::tmp<Foam::vectorField> -Foam::sampledIsoSurfaceCell::interpolate -( - const interpolation<vector>& interpolator -) const -{ - return sampleOnPoints(interpolator); -} - -Foam::tmp<Foam::sphericalTensorField> -Foam::sampledIsoSurfaceCell::interpolate -( - const interpolation<sphericalTensor>& interpolator -) const -{ - return sampleOnPoints(interpolator); -} - - -Foam::tmp<Foam::symmTensorField> -Foam::sampledIsoSurfaceCell::interpolate -( - const interpolation<symmTensor>& interpolator -) const -{ - return sampleOnPoints(interpolator); -} - - -Foam::tmp<Foam::tensorField> -Foam::sampledIsoSurfaceCell::interpolate -( - const interpolation<tensor>& interpolator -) const -{ - return sampleOnPoints(interpolator); -} - - -void Foam::sampledIsoSurfaceCell::print(Ostream& os) const -{ - os << "isoSurfaceCell: " << name() << " :" - << " field:" << isoField_ - << " value:" << isoVal_; - //<< " faces:" << faces().size() // possibly no geom yet - //<< " points:" << points().size(); -} - - // ************************************************************************* // diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.H b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.H index a71aa0fee3da9f174984a546008138fc9b26144a..2841566f4c43c7a0937f52e16b0bd2e664ee0c3f 100644 --- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.H +++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.H @@ -63,17 +63,13 @@ Usage SourceFiles sampledIsoSurfaceCell.C - sampledIsoSurfaceCellTemplates.C \*---------------------------------------------------------------------------*/ #ifndef sampledIsoSurfaceCell_H #define sampledIsoSurfaceCell_H -#include "sampledSurface.H" -#include "MeshedSurface.H" -#include "MeshedSurfacesFwd.H" -#include "isoSurfaceCell.H" +#include "sampledIsoSurface.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -86,94 +82,12 @@ namespace Foam class sampledIsoSurfaceCell : - public sampledSurface + public sampledIsoSurface { - // Private typedefs for convenience - typedef meshedSurface Mesh; - - - // Private Data - - //- Field to get isoSurface of - const word isoField_; - - //- Iso value - const scalar isoVal_; - - //- Parameters (filtering etc) for iso-surface - isoSurfaceParams isoParams_; - - //- Recalculate cell values as average of point values - bool average_; - - //- The zone or zones for the iso-surface - wordRes zoneNames_; - - - // Sampling geometry. Directly stored or via an iso-surface (ALGO_POINT) - - //- Time at last call, also track if surface needs an update - mutable label prevTimeIndex_; - - //- The extracted surface (direct storage) - mutable meshedSurface surface_; - - //- For every face the original cell in mesh (direct storage) - mutable labelList meshCells_; - - //- Extracted iso-surface, for interpolators - mutable autoPtr<isoSurfaceCell> isoSurfacePtr_; - - - // Mesh subsetting - - //- Cached ignore cells for sub-mesh (zoned) - mutable autoPtr<bitSet> ignoreCellsPtr_; - - - // Private Member Functions - - //- Create iso surface (if time has changed) - // Do nothing (and return false) if no update was needed - bool updateGeometry() const; - - //- Sample volume field onto surface faces - template<class Type> - tmp<Field<Type>> sampleOnFaces - ( - const interpolation<Type>& sampler - ) const; - - //- Interpolate volume field onto surface points - template<class Type> - tmp<Field<Type>> sampleOnPoints - ( - const interpolation<Type>& interpolator - ) const; - - //- Use isoSurfacePtr_ for point interpolation - template<class Type> - tmp<Field<Type>> sampleOnIsoSurfacePoints - ( - const interpolation<Type>& interpolator - ) const; - - -protected: - - // Protected Member Functions - - //- Is currently backed by an isoSurfacePtr_ - bool hasIsoSurface() const - { - return bool(isoSurfacePtr_); - } - - public: //- Runtime type information - TypeName("sampledIsoSurfaceCell"); + TypeNameNoDebug("sampledIsoSurfaceCell"); // Constructors @@ -188,147 +102,7 @@ public: //- Destructor - virtual ~sampledIsoSurfaceCell(); - - - // Member Functions - - //- Does the surface need an update? - virtual bool needsUpdate() const; - - //- Mark the surface as needing an update. - // May also free up unneeded data. - // Return false if surface was already marked as expired. - virtual bool expire(); - - //- Update the surface as required. - // Do nothing (and return false) if no update was needed - virtual bool update(); - - //- The currently created surface geometry - const meshedSurface& surface() const - { - if (isoSurfacePtr_) - { - return *isoSurfacePtr_; - } - return surface_; - } - - //- For each face, the original cell in mesh - const labelList& meshCells() const - { - if (isoSurfacePtr_) - { - return isoSurfacePtr_->meshCells(); - } - return meshCells_; - } - - //- Points of surface - virtual const pointField& points() const - { - return surface().points(); - } - - //- Faces of surface - virtual const faceList& faces() const - { - return surface().surfFaces(); - } - - //- Per-face zone/region information - virtual const labelList& zoneIds() const - { - return labelList::null(); - } - - //- Face area magnitudes - virtual const vectorField& Sf() const - { - return surface().Sf(); - } - - //- Face area magnitudes - virtual const scalarField& magSf() const - { - return surface().magSf(); - } - - //- Face centres - virtual const vectorField& Cf() const - { - return surface().Cf(); - } - - - // Sample - - //- Sample volume field onto surface faces - virtual tmp<scalarField> sample - ( - const interpolation<scalar>& sampler - ) const; - - //- Sample volume field onto surface faces - virtual tmp<vectorField> sample - ( - const interpolation<vector>& sampler - ) const; - - //- Sample volume field onto surface faces - virtual tmp<sphericalTensorField> sample - ( - const interpolation<sphericalTensor>& sampler - ) const; - - //- Sample volume field onto surface faces - virtual tmp<symmTensorField> sample - ( - const interpolation<symmTensor>& sampler - ) const; - - //- Sample volume field onto surface faces - virtual tmp<tensorField> sample - ( - const interpolation<tensor>& sampler - ) const; - - - // Interpolate - - //- Interpolate volume field onto surface points - virtual tmp<scalarField> interpolate - ( - const interpolation<scalar>& interpolator - ) const; - - //- Interpolate volume field onto surface points - virtual tmp<vectorField> interpolate - ( - const interpolation<vector>& interpolator - ) const; - - //- Interpolate volume field onto surface points - virtual tmp<sphericalTensorField> interpolate - ( - const interpolation<sphericalTensor>& interpolator - ) const; - - //- Interpolate volume field onto surface points - virtual tmp<symmTensorField> interpolate - ( - const interpolation<symmTensor>& interpolator - ) const; - - //- Interpolate volume field onto surface points - virtual tmp<tensorField> interpolate - ( - const interpolation<tensor>& interpolator - ) const; - - //- Write - virtual void print(Ostream& os) const; + virtual ~sampledIsoSurfaceCell() = default; }; @@ -338,12 +112,6 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -#ifdef NoRepository - #include "sampledIsoSurfaceCellTemplates.C" -#endif - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - #endif // ************************************************************************* // diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCellTemplates.C b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCellTemplates.C index 70a5910e37cbc1954ed5900e62ac056d6f8bf558..7cec1b4541d1553571d30afa2aac3b841f6c3d51 100644 --- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCellTemplates.C +++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCellTemplates.C @@ -1,120 +1 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | www.openfoam.com - \\/ M anipulation | -------------------------------------------------------------------------------- - Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2018-2020 OpenCFD Ltd. -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "sampledIsoSurfaceCell.H" -#include "volFieldsFwd.H" -#include "pointFields.H" -#include "volPointInterpolation.H" - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -template<class Type> -Foam::tmp<Foam::Field<Type>> -Foam::sampledIsoSurfaceCell::sampleOnFaces -( - const interpolation<Type>& sampler -) const -{ - updateGeometry(); // Recreate geometry if time has changed - - return sampledSurface::sampleOnFaces - ( - sampler, - meshCells(), - surface(), - points() - ); -} - - -template<class Type> -Foam::tmp<Foam::Field<Type>> -Foam::sampledIsoSurfaceCell::sampleOnPoints -( - const interpolation<Type>& interpolator -) const -{ - updateGeometry(); // Recreate geometry if time has changed - - if (isoSurfacePtr_) - { - return this->sampleOnIsoSurfacePoints(interpolator); - } - - return sampledSurface::sampleOnPoints - ( - interpolator, - meshCells(), - faces(), - points() - ); -} - - -template<class Type> -Foam::tmp<Foam::Field<Type>> -Foam::sampledIsoSurfaceCell::sampleOnIsoSurfacePoints -( - const interpolation<Type>& interpolator -) const -{ - if (!isoSurfacePtr_) - { - FatalErrorInFunction - << "cannot call without an iso-surface" << nl - << exit(FatalError); - } - - // Assume volPointInterpolation for the point field! - const auto& volFld = interpolator.psi(); - - tmp<GeometricField<Type, fvPatchField, volMesh>> tvolFld(volFld); - tmp<GeometricField<Type, pointPatchField, pointMesh>> tpointFld; - - // if (subMeshPtr_) - // { - // // Replace with subset - // tvolFld.reset(subMeshPtr_->interpolate(volFld)); - // } - - // Interpolated point field - tpointFld.reset - ( - volPointInterpolation::New(tvolFld().mesh()).interpolate(tvolFld()) - ); - - if (average_) - { - tvolFld.reset(pointAverage(tpointFld())); - } - - return isoSurfacePtr_->interpolate(tvolFld(), tpointFld()); -} - - -// ************************************************************************* // +#warning File removed - left for old dependency check only diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfacePoint.C b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfacePoint.C new file mode 100644 index 0000000000000000000000000000000000000000..a96ce68e17d16e1f3d1871e5ec411eca8fcf904f --- /dev/null +++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfacePoint.C @@ -0,0 +1,64 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "sampledIsoSurfacePoint.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeName(sampledIsoSurfacePoint); + addNamedToRunTimeSelectionTable + ( + sampledSurface, + sampledIsoSurfacePoint, + word, + isoSurfacePoint + ); +} + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::sampledIsoSurfacePoint::sampledIsoSurfacePoint +( + const word& name, + const polyMesh& mesh, + const dictionary& dict +) +: + sampledIsoSurface + ( + isoSurfaceParams(isoSurfaceParams::ALGO_POINT), + name, + mesh, + dict + ) +{} + + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfacePoint.H b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfacePoint.H new file mode 100644 index 0000000000000000000000000000000000000000..e1ec6f3e29af46e637358df330434da76209b70d --- /dev/null +++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfacePoint.H @@ -0,0 +1,116 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::sampledIsoSurfacePoint + +Description + A sampledSurface defined by a surface of iso value using a + \em point algorithm (always triangulated!). + It only recalculates the iso-surface if time changes. + To be used in sampleSurfaces / functionObjects. + +Usage + Example of function object partial specification: + \verbatim + surfaces + { + surface1 + { + type isoSurfacePoint; + isoField T; + isoValue 373; + } + } + \endverbatim + + Where the sub-entries comprise: + \table + Property | Description | Required | Default + type | isoSurfacePoint | yes | + isoField | field name for obtaining 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 | point snapping | yes | + mergeTol | tolerance for merging points | no | 1e-6 + \endtable + +SourceFiles + sampledIsoSurfacePoint.C + +\*---------------------------------------------------------------------------*/ + +#ifndef sampledIsoSurfacePoint_H +#define sampledIsoSurfacePoint_H + +#include "sampledIsoSurface.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class sampledIsoSurfacePoint Declaration +\*---------------------------------------------------------------------------*/ + +class sampledIsoSurfacePoint +: + public sampledIsoSurface +{ +public: + + //- Runtime type information + TypeNameNoDebug("sampledIsoSurfacePoint"); + + + // Constructors + + //- Construct from dictionary + sampledIsoSurfacePoint + ( + const word& name, + const polyMesh& mesh, + const dictionary& dict + ); + + + //- Destructor + virtual ~sampledIsoSurfacePoint() = default; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTopo.C b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTopo.C index a0a46a568ff75f03a52e444614b7e1ba3a39a324..eb02955bca8ec0478a2fab72c84fd07834eaae29 100644 --- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTopo.C +++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTopo.C @@ -5,8 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018 OpenFOAM Foundation - Copyright (C) 2018-2020 OpenCFD Ltd. + Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,18 +26,13 @@ License \*---------------------------------------------------------------------------*/ #include "sampledIsoSurfaceTopo.H" -#include "isoSurfaceTopo.H" -#include "dictionary.H" -#include "fvMesh.H" -#include "volFields.H" -#include "volPointInterpolation.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { - defineTypeNameAndDebug(sampledIsoSurfaceTopo, 0); + defineTypeName(sampledIsoSurfaceTopo); addNamedToRunTimeSelectionTable ( sampledSurface, @@ -48,175 +42,6 @@ namespace Foam ); } -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -bool Foam::sampledIsoSurfaceTopo::updateGeometry() const -{ - const fvMesh& fvm = static_cast<const fvMesh&>(mesh()); - - // No update needed - if (fvm.time().timeIndex() == prevTimeIndex_) - { - return false; - } - - prevTimeIndex_ = fvm.time().timeIndex(); - - // Clear any previously stored topologies - surface_.clear(); - meshCells_.clear(); - isoSurfacePtr_.reset(nullptr); - - // Clear derived data - sampledSurface::clearGeom(); - - - // 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_); - - if (debug) - { - if (cellFldPtr) - { - InfoInFunction << "Lookup " << isoField_ << endl; - } - else - { - InfoInFunction - << "Reading " << isoField_ - << " from time " << fvm.time().timeName() - << endl; - } - } - - // For holding the volScalarField read in. - autoPtr<volScalarField> fieldReadPtr; - - if (!cellFldPtr) - { - // Bit of a hack. Read field and store. - - fieldReadPtr = autoPtr<volScalarField>::New - ( - IOobject - ( - isoField_, - fvm.time().timeName(), - fvm, - IOobject::MUST_READ, - IOobject::NO_WRITE, - false - ), - fvm - ); - } - - const volScalarField& cellFld = - (fieldReadPtr ? *fieldReadPtr : *cellFldPtr); - - auto tpointFld = volPointInterpolation::New(fvm).interpolate(cellFld); - - // 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]; - } - } - - { - isoSurfaceTopo surf - ( - fvm, - cellFld.primitiveField(), - tpointFld().primitiveField(), - isoVal_, - isoParams_, - *ignoreCellsPtr_ - ); - - surface_.transfer(static_cast<meshedSurface&>(surf)); - meshCells_.transfer(surf.meshCells()); - } - - // if (subMeshPtr_ && meshCells_.size()) - // { - // // With the correct addressing into the full mesh - // meshCells_ = - // UIndirectList<label>(subMeshPtr_->cellMap(), meshCells_); - // } - - - // triangulate uses remapFaces() - // - this is somewhat less efficient since it recopies the faces - // that we just created, but we probably don't want to do this - // too often anyhow. - if (triangulate_ && surface_.size()) - { - labelList faceMap; - surface_.triangulate(faceMap); - meshCells_ = UIndirectList<label>(meshCells_, faceMap)(); - } - - if (debug) - { - Pout<< "isoSurfaceTopo::updateGeometry() : constructed iso:" << nl - << " isoField : " << isoField_ << nl - << " isoValue : " << isoVal_ << nl - << " average : " << Switch(average_) << nl - << " filter : " - << isoSurfaceParams::filterNames[isoParams_.filter()] << nl - << " triangulate : " << Switch(triangulate_) << nl - << " bounds : " << isoParams_.getClipBounds() << nl - << " points : " << points().size() << nl - << " faces : " << surface().size() << nl - << " cut cells : " << meshCells().size() << endl; - } - - return true; -} - - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::sampledIsoSurfaceTopo::sampledIsoSurfaceTopo @@ -226,197 +51,14 @@ Foam::sampledIsoSurfaceTopo::sampledIsoSurfaceTopo const dictionary& dict ) : - sampledSurface(name, mesh, dict), - isoField_(dict.get<word>("isoField")), - isoVal_(dict.get<scalar>("isoValue")), - isoParams_(dict), - average_(dict.getOrDefault("average", false)), - triangulate_(dict.getOrDefault("triangulate", false)), - zoneNames_(), - prevTimeIndex_(-1), - surface_(), - meshCells_(), - isoSurfacePtr_(nullptr) -{ - isoParams_.algorithm(isoSurfaceParams::ALGO_TOPO); // Force - - if + sampledIsoSurface ( - triangulate_ - && (isoParams_.filter() == isoSurfaceParams::filterType::NONE) + isoSurfaceParams(isoSurfaceParams::ALGO_TOPO), + name, + mesh, + dict ) - { - FatalIOErrorInFunction(dict) - << "Cannot triangulate without a regularise filter" << nl - << 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; - } -} - - -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - -Foam::sampledIsoSurfaceTopo::~sampledIsoSurfaceTopo() {} -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -bool Foam::sampledIsoSurfaceTopo::needsUpdate() const -{ - const fvMesh& fvm = static_cast<const fvMesh&>(mesh()); - - return fvm.time().timeIndex() != prevTimeIndex_; -} - - -bool Foam::sampledIsoSurfaceTopo::expire() -{ - surface_.clear(); - meshCells_.clear(); - isoSurfacePtr_.reset(nullptr); - - // Clear derived data - sampledSurface::clearGeom(); - - ignoreCellsPtr_.reset(nullptr); - - // Already marked as expired - if (prevTimeIndex_ == -1) - { - return false; - } - - // Force update - prevTimeIndex_ = -1; - return true; -} - - -bool Foam::sampledIsoSurfaceTopo::update() -{ - return updateGeometry(); -} - - -Foam::tmp<Foam::scalarField> -Foam::sampledIsoSurfaceTopo::sample -( - const interpolation<scalar>& sampler -) const -{ - return sampleOnFaces(sampler); -} - - -Foam::tmp<Foam::vectorField> -Foam::sampledIsoSurfaceTopo::sample -( - const interpolation<vector>& sampler -) const -{ - return sampleOnFaces(sampler); -} - - -Foam::tmp<Foam::sphericalTensorField> -Foam::sampledIsoSurfaceTopo::sample -( - const interpolation<sphericalTensor>& sampler -) const -{ - return sampleOnFaces(sampler); -} - - -Foam::tmp<Foam::symmTensorField> -Foam::sampledIsoSurfaceTopo::sample -( - const interpolation<symmTensor>& sampler -) const -{ - return sampleOnFaces(sampler); -} - - -Foam::tmp<Foam::tensorField> -Foam::sampledIsoSurfaceTopo::sample -( - const interpolation<tensor>& sampler -) const -{ - return sampleOnFaces(sampler); -} - - -Foam::tmp<Foam::scalarField> -Foam::sampledIsoSurfaceTopo::interpolate -( - const interpolation<scalar>& interpolator -) const -{ - return sampleOnPoints(interpolator); -} - - -Foam::tmp<Foam::vectorField> -Foam::sampledIsoSurfaceTopo::interpolate -( - const interpolation<vector>& interpolator -) const -{ - return sampleOnPoints(interpolator); -} - -Foam::tmp<Foam::sphericalTensorField> -Foam::sampledIsoSurfaceTopo::interpolate -( - const interpolation<sphericalTensor>& interpolator -) const -{ - return sampleOnPoints(interpolator); -} - - -Foam::tmp<Foam::symmTensorField> -Foam::sampledIsoSurfaceTopo::interpolate -( - const interpolation<symmTensor>& interpolator -) const -{ - return sampleOnPoints(interpolator); -} - - -Foam::tmp<Foam::tensorField> -Foam::sampledIsoSurfaceTopo::interpolate -( - const interpolation<tensor>& interpolator -) const -{ - return sampleOnPoints(interpolator); -} - - -void Foam::sampledIsoSurfaceTopo::print(Ostream& os) const -{ - os << "isoSurfaceTopo: " << name() << " :" - << " field:" << isoField_ - << " value:" << isoVal_; - //<< " faces:" << faces().size() // possibly no geom yet - //<< " points:" << points().size(); -} - - // ************************************************************************* // diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTopo.H b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTopo.H index 71d10aa7cf050ab8c7c935a39dfd5e0275e8226a..5eca51e7ad9fe4716600f1b710da78d785ad4b63 100644 --- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTopo.H +++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTopo.H @@ -63,17 +63,13 @@ Usage SourceFiles sampledIsoSurfaceTopo.C - sampledIsoSurfaceTopoTemplates.C \*---------------------------------------------------------------------------*/ #ifndef sampledIsoSurfaceTopo_H #define sampledIsoSurfaceTopo_H -#include "sampledSurface.H" -#include "MeshedSurface.H" -#include "MeshedSurfacesFwd.H" -#include "isoSurfaceTopo.H" +#include "sampledIsoSurface.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -86,97 +82,12 @@ namespace Foam class sampledIsoSurfaceTopo : - public sampledSurface + public sampledIsoSurface { - // Private typedefs for convenience - typedef meshedSurface Mesh; - - - // Private Data - - //- Field to get isoSurface of - const word isoField_; - - //- Iso value - const scalar isoVal_; - - //- Parameters (filtering etc) for iso-surface - isoSurfaceParams isoParams_; - - //- Recalculate cell values as average of point values? - bool average_; - - //- Whether to triangulate (after filtering) - bool triangulate_; - - //- The zone or zones for the iso-surface - wordRes zoneNames_; - - - // Sampling geometry. Directly stored or via an iso-surface (ALGO_POINT) - - //- Time at last call, also track it surface needs an update - mutable label prevTimeIndex_; - - //- The extracted surface (direct storage) - mutable meshedSurface surface_; - - //- For every face the original cell in mesh (direct storage) - mutable labelList meshCells_; - - //- Extracted iso-surface, for interpolators - mutable autoPtr<isoSurfaceTopo> isoSurfacePtr_; - - - // Mesh subsetting - - //- Cached ignore cells for sub-mesh (zoned) - mutable autoPtr<bitSet> ignoreCellsPtr_; - - - // Private Member Functions - - //- Create iso surface (if time has changed) - // Do nothing (and return false) if no update was needed - bool updateGeometry() const; - - //- Sample volume field onto surface faces - template<class Type> - tmp<Field<Type>> sampleOnFaces - ( - const interpolation<Type>& sampler - ) const; - - //- Interpolate volume field onto surface points - template<class Type> - tmp<Field<Type>> sampleOnPoints - ( - const interpolation<Type>& interpolator - ) const; - - //- Use isoSurfacePtr_ for point interpolation - template<class Type> - tmp<Field<Type>> sampleOnIsoSurfacePoints - ( - const interpolation<Type>& interpolator - ) const; - - -protected: - - // Protected Member Functions - - //- Is currently backed by an isoSurfacePtr_ - bool hasIsoSurface() const - { - return bool(isoSurfacePtr_); - } - - public: //- Runtime type information - TypeName("sampledIsoSurfaceTopo"); + TypeNameNoDebug("sampledIsoSurfaceTopo"); // Constructors @@ -191,147 +102,7 @@ public: //- Destructor - virtual ~sampledIsoSurfaceTopo(); - - - // Member Functions - - //- Does the surface need an update? - virtual bool needsUpdate() const; - - //- Mark the surface as needing an update. - // May also free up unneeded data. - // Return false if surface was already marked as expired. - virtual bool expire(); - - //- Update the surface as required. - // Do nothing (and return false) if no update was needed - virtual bool update(); - - //- The currently created surface geometry - const meshedSurface& surface() const - { - if (isoSurfacePtr_) - { - return *isoSurfacePtr_; - } - return surface_; - } - - //- For each face, the original cell in mesh - const labelList& meshCells() const - { - if (isoSurfacePtr_) - { - return isoSurfacePtr_->meshCells(); - } - return meshCells_; - } - - //- Points of surface - virtual const pointField& points() const - { - return surface().points(); - } - - //- Faces of surface - virtual const faceList& faces() const - { - return surface().surfFaces(); - } - - //- Per-face zone/region information - virtual const labelList& zoneIds() const - { - return labelList::null(); - } - - //- Face area magnitudes - virtual const vectorField& Sf() const - { - return surface().Sf(); - } - - //- Face area magnitudes - virtual const scalarField& magSf() const - { - return surface().magSf(); - } - - //- Face centres - virtual const vectorField& Cf() const - { - return surface().Cf(); - } - - - // Sample - - //- Sample volume field onto surface faces - virtual tmp<scalarField> sample - ( - const interpolation<scalar>& sampler - ) const; - - //- Sample volume field onto surface faces - virtual tmp<vectorField> sample - ( - const interpolation<vector>& sampler - ) const; - - //- Sample volume field onto surface faces - virtual tmp<sphericalTensorField> sample - ( - const interpolation<sphericalTensor>& sampler - ) const; - - //- Sample volume field onto surface faces - virtual tmp<symmTensorField> sample - ( - const interpolation<symmTensor>& sampler - ) const; - - //- Sample volume field onto surface faces - virtual tmp<tensorField> sample - ( - const interpolation<tensor>& sampler - ) const; - - - // Interpolate - - //- Interpolate volume field onto surface points - virtual tmp<scalarField> interpolate - ( - const interpolation<scalar>& interpolator - ) const; - - //- Interpolate volume field onto surface points - virtual tmp<vectorField> interpolate - ( - const interpolation<vector>& interpolator - ) const; - - //- Interpolate volume field onto surface points - virtual tmp<sphericalTensorField> interpolate - ( - const interpolation<sphericalTensor>& interpolator - ) const; - - //- Interpolate volume field onto surface points - virtual tmp<symmTensorField> interpolate - ( - const interpolation<symmTensor>& interpolator - ) const; - - //- Interpolate volume field onto surface points - virtual tmp<tensorField> interpolate - ( - const interpolation<tensor>& interpolator - ) const; - - //- Write - virtual void print(Ostream& os) const; + virtual ~sampledIsoSurfaceTopo() = default; }; @@ -341,12 +112,6 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -#ifdef NoRepository - #include "sampledIsoSurfaceTopoTemplates.C" -#endif - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - #endif // ************************************************************************* // diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTopoTemplates.C b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTopoTemplates.C index c797acc319e69347a4e66be728fc96d780c177b9..7cec1b4541d1553571d30afa2aac3b841f6c3d51 100644 --- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTopoTemplates.C +++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTopoTemplates.C @@ -1,120 +1 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | www.openfoam.com - \\/ M anipulation | -------------------------------------------------------------------------------- - Copyright (C) 2018 OpenFOAM Foundation - Copyright (C) 2018-2020 OpenCFD Ltd. -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "sampledIsoSurfaceTopo.H" -#include "volFieldsFwd.H" -#include "pointFields.H" -#include "volPointInterpolation.H" - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -template<class Type> -Foam::tmp<Foam::Field<Type>> -Foam::sampledIsoSurfaceTopo::sampleOnFaces -( - const interpolation<Type>& sampler -) const -{ - updateGeometry(); // Recreate geometry if time has changed - - return sampledSurface::sampleOnFaces - ( - sampler, - meshCells(), - faces(), - points() - ); -} - - -template<class Type> -Foam::tmp<Foam::Field<Type>> -Foam::sampledIsoSurfaceTopo::sampleOnPoints -( - const interpolation<Type>& interpolator -) const -{ - updateGeometry(); // Recreate geometry if time has changed - - if (isoSurfacePtr_) - { - return this->sampleOnIsoSurfacePoints(interpolator); - } - - return sampledSurface::sampleOnPoints - ( - interpolator, - meshCells(), - faces(), - points() - ); -} - - -template<class Type> -Foam::tmp<Foam::Field<Type>> -Foam::sampledIsoSurfaceTopo::sampleOnIsoSurfacePoints -( - const interpolation<Type>& interpolator -) const -{ - if (!isoSurfacePtr_) - { - FatalErrorInFunction - << "cannot call without an iso-surface" << nl - << exit(FatalError); - } - - // Assume volPointInterpolation for the point field! - const auto& volFld = interpolator.psi(); - - tmp<GeometricField<Type, fvPatchField, volMesh>> tvolFld(volFld); - tmp<GeometricField<Type, pointPatchField, pointMesh>> tpointFld; - - // if (subMeshPtr_) - // { - // // Replace with subset - // tvolFld.reset(subMeshPtr_->interpolate(volFld)); - // } - - // Interpolated point field - tpointFld.reset - ( - volPointInterpolation::New(tvolFld().mesh()).interpolate(tvolFld()) - ); - - if (average_) - { - tvolFld.reset(pointAverage(tpointFld())); - } - - return isoSurfacePtr_->interpolate(tvolFld(), tpointFld()); -} - - -// ************************************************************************* // +#warning File removed - left for old dependency check only diff --git a/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.C b/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.C index da0db8af05b6d44e77d2ac839f701ce0905c7d85..b3d0982fe2e2ec73efaf7718097a75f5188954eb 100644 --- a/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.C +++ b/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.C @@ -28,13 +28,11 @@ License #include "sampledCuttingPlane.H" #include "dictionary.H" +#include "fvMesh.H" #include "volFields.H" #include "volPointInterpolation.H" #include "addToRunTimeSelectionTable.H" -#include "fvMesh.H" -#include "isoSurfaceCell.H" -#include "isoSurfacePoint.H" -#include "isoSurfaceTopo.H" +#include "PtrList.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -189,6 +187,111 @@ void Foam::sampledCuttingPlane::setDistanceFields(const plane& pln) } +void Foam::sampledCuttingPlane::combineSurfaces +( + PtrList<isoSurfaceBase>& isoSurfPtrs +) +{ + isoSurfacePtr_.reset(nullptr); + + // Already checked previously for ALGO_POINT, but do it again + // - ALGO_POINT still needs fields (for interpolate) + // The others can do straight transfer + if + ( + isoParams_.algorithm() == isoSurfaceParams::ALGO_POINT + && isoSurfPtrs.size() == 1 + ) + { + // Shift ownership from list to autoPtr + isoSurfacePtr_.reset(isoSurfPtrs.release(0)); + } + else if (isoSurfPtrs.size() == 1) + { + autoPtr<isoSurfaceBase> ptr(isoSurfPtrs.release(0)); + auto& surf = *ptr; + + surface_.transfer(static_cast<meshedSurface&>(surf)); + meshCells_.transfer(surf.meshCells()); + } + else + { + // Combine faces with point offsets + // + // Note: use points().size() from surface, not nPoints() + // since there may be uncompacted dangling nodes + + label nFaces = 0, nPoints = 0; + + for (const auto& surf : isoSurfPtrs) + { + nFaces += surf.size(); + nPoints += surf.points().size(); + } + + faceList newFaces(nFaces); + pointField newPoints(nPoints); + meshCells_.resize(nFaces); + + surfZoneList newZones(isoSurfPtrs.size()); + + nFaces = 0; + nPoints = 0; + forAll(isoSurfPtrs, surfi) + { + autoPtr<isoSurfaceBase> ptr(isoSurfPtrs.release(surfi)); + auto& surf = *ptr; + + SubList<face> subFaces(newFaces, surf.size(), nFaces); + SubList<point> subPoints(newPoints, surf.points().size(), nPoints); + SubList<label> subCells(meshCells_, surf.size(), nFaces); + + newZones[surfi] = surfZone + ( + surfZoneIdentifier::defaultName(surfi), + subFaces.size(), // size + nFaces, // start + surfi // index + ); + + subFaces = surf.surfFaces(); + subPoints = surf.points(); + subCells = surf.meshCells(); + + if (nPoints) + { + for (face& f : subFaces) + { + for (label& pointi : f) + { + pointi += nPoints; + } + } + } + + nFaces += subFaces.size(); + nPoints += subPoints.size(); + } + + meshedSurface combined + ( + std::move(newPoints), + std::move(newFaces), + newZones + ); + + surface_.transfer(combined); + } + + // Addressing into the full mesh + if (subMeshPtr_ && meshCells_.size()) + { + meshCells_ = + UIndirectList<label>(subMeshPtr_->cellMap(), meshCells_); + } +} + + void Foam::sampledCuttingPlane::createGeometry() { if (debug) @@ -209,54 +312,94 @@ void Foam::sampledCuttingPlane::createGeometry() pointDistance_.clear(); cellDistancePtr_.clear(); + const bool hasCellZones = + (-1 != mesh().cellZones().findIndex(zoneNames_)); + const fvMesh& fvm = static_cast<const fvMesh&>(this->mesh()); - // Get sub-mesh if any + // Geometry if ( - !subMeshPtr_ - && (-1 != mesh().cellZones().findIndex(zoneNames_)) + simpleSubMesh_ + && isoParams_.algorithm() != isoSurfaceParams::ALGO_POINT ) { - const label exposedPatchi = - mesh().boundaryMesh().findPatchID(exposedPatchName_); + subMeshPtr_.reset(nullptr); - bitSet cellsToSelect(mesh().cellZones().selection(zoneNames_)); + // Handle cell zones as inverse (blocked) selection + if (!ignoreCellsPtr_) + { + ignoreCellsPtr_.reset(new bitSet); - DebugInfo - << "Allocating subset of size " - << cellsToSelect.count() - << " with exposed faces into patch " - << exposedPatchi << endl; + if (hasCellZones) + { + bitSet select(mesh().cellZones().selection(zoneNames_)); + if (select.any() && !select.all()) + { + // From selection to blocking + select.flip(); - // If we will use a fvMeshSubset so can apply bounds as well to make - // the initial selection smaller. + *ignoreCellsPtr_ = std::move(select); + } + } + } + } + else + { + // A standard subMesh treatment - const boundBox& clipBb = isoParams_.getClipBounds(); - if (clipBb.valid() && cellsToSelect.any()) + if (ignoreCellsPtr_) + { + ignoreCellsPtr_->clearStorage(); + } + else { - const auto& cellCentres = fvm.C(); + ignoreCellsPtr_.reset(new bitSet); + } + + // Get sub-mesh if any + if (!subMeshPtr_ && hasCellZones) + { + const label exposedPatchi = + mesh().boundaryMesh().findPatchID(exposedPatchName_); + + bitSet cellsToSelect(mesh().cellZones().selection(zoneNames_)); + + DebugInfo + << "Allocating subset of size " + << cellsToSelect.count() << " with exposed faces into patch " + << exposedPatchi << endl; + + + // If we will use a fvMeshSubset so can apply bounds as well to make + // the initial selection smaller. - for (const label celli : cellsToSelect) + const boundBox& clipBb = isoParams_.getClipBounds(); + if (clipBb.valid() && cellsToSelect.any()) { - const point& cc = cellCentres[celli]; + const auto& cellCentres = fvm.C(); - if (!clipBb.contains(cc)) + for (const label celli : cellsToSelect) { - cellsToSelect.unset(celli); + const point& cc = cellCentres[celli]; + + if (!clipBb.contains(cc)) + { + cellsToSelect.unset(celli); + } } + + DebugInfo + << "Bounded subset of size " + << cellsToSelect.count() << endl; } - DebugInfo - << "Bounded subset of size " - << cellsToSelect.count() << endl; + subMeshPtr_.reset + ( + new fvMeshSubset(fvm, cellsToSelect, exposedPatchi) + ); } - - subMeshPtr_.reset - ( - new fvMeshSubset(fvm, cellsToSelect, exposedPatchi) - ); } @@ -291,7 +434,6 @@ void Foam::sampledCuttingPlane::createGeometry() dimensionedScalar(dimLength, Zero) ) ); - const volScalarField& cellDistance = cellDistancePtr_(); setDistanceFields(plane_); @@ -321,35 +463,35 @@ void Foam::sampledCuttingPlane::createGeometry() } - isoSurfacePtr_.reset - ( - isoSurfaceBase::New - ( - isoParams_, - cellDistance, - pointDistance_, - scalar(0) - // nothing ignored: ignoreCells - ) - ); + // Create surfaces for each offset - // ALGO_POINT uses cell field and point field - // The others can do straight transfer - if (isoParams_.algorithm() != isoSurfaceParams::ALGO_POINT) - { - surface_.transfer(static_cast<meshedSurface&>(*isoSurfacePtr_)); - meshCells_.transfer(isoSurfacePtr_->meshCells()); + PtrList<isoSurfaceBase> isoSurfPtrs(offsets_.size()); - isoSurfacePtr_.reset(nullptr); - cellDistancePtr_.reset(nullptr); - pointDistance_.clear(); + forAll(offsets_, surfi) + { + isoSurfPtrs.set + ( + surfi, + isoSurfaceBase::New + ( + isoParams_, + cellDistance, + pointDistance_, + offsets_[surfi], + *ignoreCellsPtr_ + ) + ); } - if (subMeshPtr_ && meshCells_.size()) + // And flatten + combineSurfaces(isoSurfPtrs); + + + // Discard fields if not required by an iso-surface + if (!isoSurfacePtr_) { - // With the correct addressing into the full mesh - meshCells_ = - UIndirectList<label>(subMeshPtr_->cellMap(), meshCells_); + cellDistancePtr_.reset(nullptr); + pointDistance_.clear(); } if (debug) @@ -371,6 +513,7 @@ Foam::sampledCuttingPlane::sampledCuttingPlane : sampledSurface(name, mesh, dict), plane_(dict), + offsets_(), isoParams_ ( dict, @@ -378,15 +521,59 @@ Foam::sampledCuttingPlane::sampledCuttingPlane isoSurfaceParams::filterType::DIAGCELL ), average_(dict.getOrDefault("average", false)), + simpleSubMesh_(dict.getOrDefault("simpleSubMesh", false)), zoneNames_(), exposedPatchName_(), needsUpdate_(true), - subMeshPtr_(nullptr), - cellDistancePtr_(nullptr), + surface_(), meshCells_(), - isoSurfacePtr_(nullptr) + isoSurfacePtr_(nullptr), + + subMeshPtr_(nullptr), + ignoreCellsPtr_(nullptr), + cellDistancePtr_(nullptr), + pointDistance_() { + dict.readIfPresent("offsets", offsets_); + + if (offsets_.empty()) + { + offsets_.resize(1); + offsets_.first() = Zero; + } + + if (offsets_.size() > 1) + { + const label nOrig = offsets_.size(); + + inplaceUniqueSort(offsets_); + + if (nOrig != offsets_.size()) + { + IOWarningInFunction(dict) + << "Removed non-unique offsets" << nl; + } + } + + if (isoParams_.algorithm() == isoSurfaceParams::ALGO_POINT) + { + // Not possible for ALGO_POINT + simpleSubMesh_ = false; + + // Not possible for ALGO_POINT + if (offsets_.size() > 1) + { + FatalIOErrorInFunction(dict) + << "Multiple offsets with iso-surface (point) not supported" + << " since needs original interpolators." << nl + << exit(FatalIOError); + } + } + + + // Zones + if (!dict.readIfPresent("zones", zoneNames_) && dict.found("zone")) { zoneNames_.resize(1); @@ -563,6 +750,7 @@ void Foam::sampledCuttingPlane::print(Ostream& os) const { os << "sampledCuttingPlane: " << name() << " :" << " plane:" << plane_ + << " offsets:" << flatOutput(offsets_) << " faces:" << faces().size() << " points:" << points().size(); } diff --git a/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.H b/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.H index 6aafff5d48b57a4e647bb304000a1eaf84813aae..c35d5a74726cad9f688fa40c92b05245f1480e68 100644 --- a/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.H +++ b/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.H @@ -55,6 +55,7 @@ Usage Property | Description | Required | Default type | cuttingPlane | yes | planeType | plane description (pointAndNormal etc) | yes | + offsets | Offsets of the origin in the normal direction | no | (0) isoMethod | Iso-algorithm (cell/topo/point) | no | topo bounds | limit with bounding box | no | zone | limit to cell zone (name or regex) | no | @@ -101,12 +102,18 @@ class sampledCuttingPlane //- Plane const plane plane_; + //- The offsets to the plane - defaults to (0). + List<scalar> offsets_; + //- Parameters (filtering etc) for iso-surface isoSurfaceParams isoParams_; //- Whether to recalculate cell values as average of point values bool average_; + //- Use simple sub-meshing in algorithm itself + bool simpleSubMesh_; + //- The zone or zones in which cutting is to occur wordRes zoneNames_; @@ -117,16 +124,6 @@ class sampledCuttingPlane mutable bool needsUpdate_; - //- Mesh subset (optional: only used with zones) - autoPtr<fvMeshSubset> subMeshPtr_; - - //- Distance to cell centres - autoPtr<volScalarField> cellDistancePtr_; - - //- Distance to points - scalarField pointDistance_; - - // Sampling geometry. Directly stored or via an iso-surface (ALGO_POINT) //- The extracted surface (direct storage) @@ -139,6 +136,24 @@ class sampledCuttingPlane autoPtr<isoSurfaceBase> isoSurfacePtr_; + // Mesh Subsetting + + //- Cached subMesh for (pre-)subset of cell zones + mutable autoPtr<fvMeshSubset> subMeshPtr_; + + //- Cached ignore cells for (post-)subset of cell zones + mutable autoPtr<bitSet> ignoreCellsPtr_; + + + // Fields + + //- Distance to cell centres + autoPtr<volScalarField> cellDistancePtr_; + + //- Distance to points + scalarField pointDistance_; + + // Private Member Functions //- Check and warn if bounding box does not intersect mesh or plane @@ -151,6 +166,9 @@ class sampledCuttingPlane //- Fill cellDistance, pointDistance fields for the specified plane void setDistanceFields(const plane& pln); + //- Collect iso-surfaces into a single surface (No point merging) + void combineSurfaces(PtrList<isoSurfaceBase>& isoSurfPtrs); + //- Create iso surface void createGeometry();