Foam::tmp<Foam::Field<Type> > Foam::sampledIsoSurface::interpolateField ( const interpolation<Type>& interpolator ) const { // Get fields to sample. Assume volPointInterpolation! const GeometricField<Type, fvPatchField, volMesh>& volFld = interpolator.psi(); // Recreate geometry if time has changed updateGeometry(); if (subMeshPtr_.valid()) { tmp<GeometricField<Type, fvPatchField, volMesh> > tvolSubFld = subMeshPtr_().interpolate(volFld); const GeometricField<Type, fvPatchField, volMesh>& volSubFld = tvolSubFld(); tmp<GeometricField<Type, pointPatchField, pointMesh> > tpointSubFld = volPointInterpolation::New(volSubFld.mesh()).interpolate(volSubFld); // Sample. return surface().interpolate ( ( average_ ? pointAverage(tpointSubFld())() : volSubFld ), tpointSubFld() ); } else { tmp<GeometricField<Type, pointPatchField, pointMesh> > tpointFld = volPointInterpolation::New(volFld.mesh()).interpolate(volFld); // Sample. return surface().interpolate ( ( average_ ? pointAverage(tpointFld())() : volFld ), tpointFld() ); } }
void Foam::sampledIsoSurface::getIsoFields() const { const fvMesh& fvm = static_cast<const fvMesh&>(mesh()); // Get volField // ~~~~~~~~~~~~ if (fvm.foundObject<volScalarField>(isoField_)) { if (debug) { Info<< "sampledIsoSurface::getIsoField() : lookup volField " << isoField_ << endl; } storedVolFieldPtr_.clear(); volFieldPtr_ = &fvm.lookupObject<volScalarField>(isoField_); } else { // Bit of a hack. Read field and store. if (debug) { Info<< "sampledIsoSurface::getIsoField() : checking " << isoField_ << " for same time " << fvm.time().timeName() << endl; } if ( storedVolFieldPtr_.empty() || (fvm.time().timeName() != storedVolFieldPtr_().instance()) ) { if (debug) { Info<< "sampledIsoSurface::getIsoField() : reading volField " << isoField_ << " from time " << fvm.time().timeName() << endl; } storedVolFieldPtr_.reset ( new volScalarField ( IOobject ( isoField_, fvm.time().timeName(), fvm, IOobject::MUST_READ, IOobject::NO_WRITE, false ), fvm ) ); volFieldPtr_ = storedVolFieldPtr_.operator->(); } } // Get pointField // ~~~~~~~~~~~~~~ if (!subMeshPtr_.valid()) { word pointFldName = "volPointInterpolate(" + isoField_ + ')'; if (fvm.foundObject<pointScalarField>(pointFldName)) { if (debug) { Info<< "sampledIsoSurface::getIsoField() : lookup pointField " << pointFldName << endl; } pointFieldPtr_ = &fvm.lookupObject<pointScalarField>(pointFldName); } else { // Not in registry. Interpolate. if (debug) { Info<< "sampledIsoSurface::getIsoField() : checking pointField " << pointFldName << " for same time " << fvm.time().timeName() << endl; } if ( storedPointFieldPtr_.empty() || (fvm.time().timeName() != storedPointFieldPtr_().instance()) ) { if (debug) { Info<< "sampledIsoSurface::getIsoField() :" << " interpolating volField " << volFieldPtr_->name() << " to get pointField " << pointFldName << endl; } storedPointFieldPtr_.reset ( volPointInterpolation::New(fvm) .interpolate(*volFieldPtr_).ptr() ); storedPointFieldPtr_->checkOut(); pointFieldPtr_ = storedPointFieldPtr_.operator->(); } } // If averaging redo the volField. Can only be done now since needs the // point field. if (average_) { storedVolFieldPtr_.reset(average(fvm, *pointFieldPtr_).ptr()); volFieldPtr_ = storedVolFieldPtr_.operator->(); } if (debug) { Info<< "sampledIsoSurface::getIsoField() : volField " << volFieldPtr_->name() << " min:" << min(*volFieldPtr_).value() << " max:" << max(*volFieldPtr_).value() << endl; Info<< "sampledIsoSurface::getIsoField() : pointField " << pointFieldPtr_->name() << " min:" << gMin(pointFieldPtr_->internalField()) << " max:" << gMax(pointFieldPtr_->internalField()) << endl; } } else { // Get subMesh variants const fvMesh& subFvm = subMeshPtr_().subMesh(); // Either lookup on the submesh or subset the whole-mesh volField if (subFvm.foundObject<volScalarField>(isoField_)) { if (debug) { Info<< "sampledIsoSurface::getIsoField() :" << " submesh lookup volField " << isoField_ << endl; } storedVolSubFieldPtr_.clear(); volSubFieldPtr_ = &subFvm.lookupObject<volScalarField>(isoField_); } else { if (debug) { Info<< "sampledIsoSurface::getIsoField() : subsetting volField " << isoField_ << endl; } storedVolSubFieldPtr_.reset ( subMeshPtr_().interpolate ( *volFieldPtr_ ).ptr() ); storedVolSubFieldPtr_->checkOut(); volSubFieldPtr_ = storedVolSubFieldPtr_.operator->(); } // Pointfield on submesh word pointFldName = "volPointInterpolate(" + volSubFieldPtr_->name() + ')'; if (subFvm.foundObject<pointScalarField>(pointFldName)) { if (debug) { Info<< "sampledIsoSurface::getIsoField() :" << " submesh lookup pointField " << pointFldName << endl; } storedPointSubFieldPtr_.clear(); pointSubFieldPtr_ = &subFvm.lookupObject<pointScalarField> ( pointFldName ); } else { if (debug) { Info<< "sampledIsoSurface::getIsoField() :" << " interpolating submesh volField " << volSubFieldPtr_->name() << " to get submesh pointField " << pointFldName << endl; } storedPointSubFieldPtr_.reset ( volPointInterpolation::New ( subFvm ).interpolate(*volSubFieldPtr_).ptr() ); storedPointSubFieldPtr_->checkOut(); pointSubFieldPtr_ = storedPointSubFieldPtr_.operator->(); } // If averaging redo the volField. Can only be done now since needs the // point field. if (average_) { storedVolSubFieldPtr_.reset ( average(subFvm, *pointSubFieldPtr_).ptr() ); volSubFieldPtr_ = storedVolSubFieldPtr_.operator->(); } if (debug) { Info<< "sampledIsoSurface::getIsoField() : volSubField " << volSubFieldPtr_->name() << " min:" << min(*volSubFieldPtr_).value() << " max:" << max(*volSubFieldPtr_).value() << endl; Info<< "sampledIsoSurface::getIsoField() : pointSubField " << pointSubFieldPtr_->name() << " min:" << gMin(pointSubFieldPtr_->internalField()) << " max:" << gMax(pointSubFieldPtr_->internalField()) << endl; } } }
bool Foam::sampledIsoSurface::updateGeometry() const { const fvMesh& fvm = static_cast<const fvMesh&>(mesh()); // No update needed if (fvm.time().timeIndex() == prevTimeIndex_) { return false; } // Get any subMesh if (zoneID_.index() != -1 && !subMeshPtr_.valid()) { const polyBoundaryMesh& patches = mesh().boundaryMesh(); // Patch to put exposed internal faces into const label exposedPatchI = patches.findPatchID(exposedPatchName_); if (debug) { Info<< "Allocating subset of size " << mesh().cellZones()[zoneID_.index()].size() << " with exposed faces into patch " << patches[exposedPatchI].name() << endl; } subMeshPtr_.reset ( new fvMeshSubset(fvm) ); subMeshPtr_().setLargeCellSubset ( labelHashSet(mesh().cellZones()[zoneID_.index()]), exposedPatchI ); } prevTimeIndex_ = fvm.time().timeIndex(); getIsoFields(); // Clear any stored topo surfPtr_.clear(); facesPtr_.clear(); // Clear derived data clearGeom(); if (subMeshPtr_.valid()) { surfPtr_.reset ( new isoSurface ( *volSubFieldPtr_, *pointSubFieldPtr_, isoVal_, regularise_, mergeTol_ ) ); } else { surfPtr_.reset ( new isoSurface ( *volFieldPtr_, *pointFieldPtr_, isoVal_, regularise_, mergeTol_ ) ); } if (debug) { Pout<< "sampledIsoSurface::updateGeometry() : constructed iso:" << nl << " regularise : " << regularise_ << nl << " average : " << average_ << nl << " isoField : " << isoField_ << nl << " isoValue : " << isoVal_ << nl; if (subMeshPtr_.valid()) { Pout<< " zone size : " << subMeshPtr_().subMesh().nCells() << nl; } Pout<< " points : " << points().size() << nl << " tris : " << surface().size() << nl << " cut cells : " << surface().meshCells().size() << endl; } return true; }
void Foam::sampledCuttingPlane::createGeometry() { if (debug) { Pout<< "sampledCuttingPlane::createGeometry :updating geometry." << endl; } // Clear any stored topologies facesPtr_.clear(); isoSurfPtr_.ptr(); pointDistance_.clear(); cellDistancePtr_.clear(); // Get any subMesh if (zoneID_.index() != -1 && !subMeshPtr_.valid()) { const polyBoundaryMesh& patches = mesh().boundaryMesh(); // Patch to put exposed internal faces into label exposedPatchI = patches.findPatchID(exposedPatchName_); if (debug) { Info<< "Allocating subset of size " << mesh().cellZones()[zoneID_.index()].size() << " with exposed faces into patch " << patches[exposedPatchI].name() << endl; } const fvMesh& fvm = static_cast<const fvMesh&>(mesh()); subMeshPtr_.reset ( new fvMeshSubset ( IOobject ( "set", fvm.time().timeName(), fvm, IOobject::NO_READ, IOobject::NO_WRITE ), fvm ) ); subMeshPtr_().setLargeCellSubset ( labelHashSet(mesh().cellZones()[zoneID_.index()]), exposedPatchI ); } // Select either the submesh or the underlying mesh const fvMesh& fvm = ( subMeshPtr_.valid() ? subMeshPtr_().subMesh() : static_cast<const fvMesh&>(mesh()) ); // Distance to cell centres // ~~~~~~~~~~~~~~~~~~~~~~~~ cellDistancePtr_.reset ( new volScalarField ( IOobject ( "cellDistance", fvm.time().timeName(), fvm.time(), IOobject::NO_READ, IOobject::NO_WRITE, false ), fvm, dimensionedScalar("zero", dimLength, 0) ) ); volScalarField& cellDistance = cellDistancePtr_(); // Internal field { const pointField& cc = fvm.cellCentres(); scalarField& fld = cellDistance.internalField(); forAll(cc, i) { // Signed distance fld[i] = (cc[i] - plane_.refPoint()) & plane_.normal(); } }
void Foam::sampledIsoSurface::getIsoFields() const { const fvMesh& fvm = static_cast<const fvMesh&>(mesh()); // Get volField // ~~~~~~~~~~~~ if (fvm.foundObject<volScalarField>(isoField_)) { if (debug) { InfoInFunction << "Lookup volField " << isoField_ << endl; } storedVolFieldPtr_.clear(); volFieldPtr_ = &fvm.lookupObject<volScalarField>(isoField_); } else { // Bit of a hack. Read field and store. if (debug) { InfoInFunction << "Checking " << isoField_ << " for same time " << fvm.time().timeName() << endl; } if ( storedVolFieldPtr_.empty() || (fvm.time().timeName() != storedVolFieldPtr_().instance()) ) { if (debug) { InfoInFunction << "Reading volField " << isoField_ << " from time " << fvm.time().timeName() << endl; } IOobject vfHeader ( isoField_, fvm.time().timeName(), fvm, IOobject::MUST_READ, IOobject::NO_WRITE, false ); if (vfHeader.typeHeaderOk<volScalarField>(true)) { storedVolFieldPtr_.reset ( new volScalarField ( vfHeader, fvm ) ); volFieldPtr_ = storedVolFieldPtr_.operator->(); } else { FatalErrorInFunction << "Cannot find isosurface field " << isoField_ << " in database or directory " << vfHeader.path() << exit(FatalError); } } } // Get pointField // ~~~~~~~~~~~~~~ // In case of multiple iso values we don't want to calculate multiple e.g. // "volPointInterpolate(p)" so register it and re-use it. This is the // same as the 'cache' functionality from volPointInterpolate but // unfortunately that one does not guarantee that the field pointer // remain: e.g. some other functionObject might delete the cached version. // (volPointInterpolation::interpolate with cache=false deletes any // registered one or if mesh.changing()) if (!subMeshPtr_.valid()) { const word pointFldName = "volPointInterpolate_" + type() + "(" + isoField_ + ')'; if (fvm.foundObject<pointScalarField>(pointFldName)) { if (debug) { InfoInFunction << "lookup pointField " << pointFldName << endl; } const pointScalarField& pfld = fvm.lookupObject<pointScalarField> ( pointFldName ); if (!pfld.upToDate(*volFieldPtr_)) { if (debug) { InfoInFunction << "updating pointField " << pointFldName << endl; } // Update the interpolated value volPointInterpolation::New(fvm).interpolate ( *volFieldPtr_, const_cast<pointScalarField&>(pfld) ); } pointFieldPtr_ = &pfld; } else { // Not in registry. Interpolate. if (debug) { InfoInFunction << "Checking pointField " << pointFldName << " for same time " << fvm.time().timeName() << endl; } // Interpolate without cache. Note that we're registering it // below so next time round it goes into the condition // above. tmp<pointScalarField> tpfld ( volPointInterpolation::New(fvm).interpolate ( *volFieldPtr_, pointFldName, false ) ); pointFieldPtr_ = tpfld.ptr(); const_cast<pointScalarField*>(pointFieldPtr_)->store(); } // If averaging redo the volField. Can only be done now since needs the // point field. if (average_) { storedVolFieldPtr_.reset ( pointAverage(*pointFieldPtr_).ptr() ); volFieldPtr_ = storedVolFieldPtr_.operator->(); } if (debug) { InfoInFunction << "volField " << volFieldPtr_->name() << " min:" << min(*volFieldPtr_).value() << " max:" << max(*volFieldPtr_).value() << endl; InfoInFunction << "pointField " << pointFieldPtr_->name() << " min:" << gMin(pointFieldPtr_->primitiveField()) << " max:" << gMax(pointFieldPtr_->primitiveField()) << endl; } } else { // Get subMesh variants const fvMesh& subFvm = subMeshPtr_().subMesh(); // Either lookup on the submesh or subset the whole-mesh volField if (subFvm.foundObject<volScalarField>(isoField_)) { if (debug) { InfoInFunction << "Sub-mesh lookup volField " << isoField_ << endl; } storedVolSubFieldPtr_.clear(); volSubFieldPtr_ = &subFvm.lookupObject<volScalarField>(isoField_); } else { if (debug) { InfoInFunction << "Sub-setting volField " << isoField_ << endl; } storedVolSubFieldPtr_.reset ( subMeshPtr_().interpolate ( *volFieldPtr_ ).ptr() ); storedVolSubFieldPtr_->checkOut(); volSubFieldPtr_ = storedVolSubFieldPtr_.operator->(); } // Pointfield on submesh word pointFldName = "volPointInterpolate(" + volSubFieldPtr_->name() + ')'; if (subFvm.foundObject<pointScalarField>(pointFldName)) { if (debug) { InfoInFunction << "Sub-mesh lookup pointField " << pointFldName << endl; } storedPointSubFieldPtr_.clear(); pointSubFieldPtr_ = &subFvm.lookupObject<pointScalarField> ( pointFldName ); } else { if (debug) { InfoInFunction << "Interpolating submesh volField " << volSubFieldPtr_->name() << " to get submesh pointField " << pointFldName << endl; } storedPointSubFieldPtr_.reset ( volPointInterpolation::New ( subFvm ).interpolate(*volSubFieldPtr_).ptr() ); storedPointSubFieldPtr_->checkOut(); pointSubFieldPtr_ = storedPointSubFieldPtr_.operator->(); } // If averaging redo the volField. Can only be done now since needs the // point field. if (average_) { storedVolSubFieldPtr_.reset ( pointAverage(*pointSubFieldPtr_).ptr() ); volSubFieldPtr_ = storedVolSubFieldPtr_.operator->(); } if (debug) { InfoInFunction << "volSubField " << volSubFieldPtr_->name() << " min:" << min(*volSubFieldPtr_).value() << " max:" << max(*volSubFieldPtr_).value() << endl; InfoInFunction << "pointSubField " << pointSubFieldPtr_->name() << " min:" << gMin(pointSubFieldPtr_->primitiveField()) << " max:" << gMax(pointSubFieldPtr_->primitiveField()) << endl; } } }