diff --git a/src/sampling/Make/files b/src/sampling/Make/files index 1ac57449f64626a26f14f11a997f97e0ab46c51c..8dbf6e93945abde3bbc36aa25d6a309aa508b2fc 100644 --- a/src/sampling/Make/files +++ b/src/sampling/Make/files @@ -21,6 +21,12 @@ surface/cuttingPlane/cuttingPlane.C surface/isoSurface/isoSurface.C surface/isoSurface/isoSurfaceCell.C surface/thresholdCellFaces/thresholdCellFaces.C +surface/triSurfaceMesh/discreteSurface.C + +surfMeshSampler/surfMeshSampler/surfMeshSampler.C +surfMeshSampler/surfMeshSamplers/surfMeshSamplers.C +surfMeshSampler/plane/surfMeshPlaneSampler.C +surfMeshSampler/triSurfaceMesh/surfMeshDiscreteSampler.C sampledSurface/sampledPatch/sampledPatch.C sampledSurface/sampledPatchInternalField/sampledPatchInternalField.C @@ -35,6 +41,10 @@ sampledSurface/sampledSurfaces/sampledSurfacesGrouping.C sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.C +/* Proof-of-concept: */ +/* sampledSurface/triSurfaceMesh/sampledDiscreteSurface.C */ + + surfWriters = sampledSurface/writers $(surfWriters)/surfaceWriter.C diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H index aaa66caa13f2ec09cfdf52ee01af1a78524cf66a..7f41fd7795f662d4ea0cdcbac32a395be89376d1 100644 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H +++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H @@ -64,6 +64,9 @@ Description } \endverbatim +See also + Foam::surfMeshSamplers + SourceFiles sampledSurfaces.C diff --git a/src/sampling/sampledSurface/triSurfaceMesh/sampledDiscreteSurface.C b/src/sampling/sampledSurface/triSurfaceMesh/sampledDiscreteSurface.C new file mode 100644 index 0000000000000000000000000000000000000000..3f745dd820f0439b3e3fe454dd41d99dda96de54 --- /dev/null +++ b/src/sampling/sampledSurface/triSurfaceMesh/sampledDiscreteSurface.C @@ -0,0 +1,234 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2016 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 "sampledDiscreteSurface.H" +#include "meshSearch.H" +#include "Tuple2.H" +#include "globalIndex.H" +#include "treeDataCell.H" +#include "treeDataFace.H" +#include "meshTools.H" + +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(sampledDiscreteSurface, 0); + addToRunTimeSelectionTable + ( + sampledSurface, + sampledDiscreteSurface, + word + ); +} + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::sampledDiscreteSurface::sampledDiscreteSurface +( + const word& name, + const polyMesh& mesh, + const word& surfaceName, + const discreteSurface::samplingSource sampleSource +) +: + sampledSurface(name, mesh), + SurfaceSource(mesh, surfaceName, sampleSource) +{} + + +Foam::sampledDiscreteSurface::sampledDiscreteSurface +( + const word& name, + const polyMesh& mesh, + const dictionary& dict +) +: + sampledSurface(name, mesh, dict), + SurfaceSource(mesh, dict) +{} + + +Foam::sampledDiscreteSurface::sampledDiscreteSurface +( + const word& name, + const polyMesh& mesh, + const triSurface& surface, + const word& sampleSourceName +) +: + sampledSurface(name, mesh), + SurfaceSource(name, mesh, surface, sampleSourceName) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::sampledDiscreteSurface::~sampledDiscreteSurface() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::sampledDiscreteSurface::needsUpdate() const +{ + return SurfaceSource::needsUpdate(); +} + + +bool Foam::sampledDiscreteSurface::expire() +{ + if (SurfaceSource::expire()) + { + // merged information etc + sampledSurface::clearGeom(); + + return true; + } + + return false; +} + + +bool Foam::sampledDiscreteSurface::update() +{ + return SurfaceSource::update(); +} + + +bool Foam::sampledDiscreteSurface::update(const treeBoundBox& bb) +{ + return SurfaceSource::update(bb); +} + + +bool Foam::sampledDiscreteSurface::sampleAndStore +( + const objectRegistry& store, + const word& fieldName +) const +{ + return SurfaceSource::sampleAndStore(store, fieldName); +} + + +Foam::tmp<Foam::scalarField> Foam::sampledDiscreteSurface::sample +( + const volScalarField& vField +) const +{ + return SurfaceSource::sampleField(vField); +} + + +Foam::tmp<Foam::vectorField> Foam::sampledDiscreteSurface::sample +( + const volVectorField& vField +) const +{ + return SurfaceSource::sampleField(vField); +} + +Foam::tmp<Foam::sphericalTensorField> Foam::sampledDiscreteSurface::sample +( + const volSphericalTensorField& vField +) const +{ + return SurfaceSource::sampleField(vField); +} + + +Foam::tmp<Foam::symmTensorField> Foam::sampledDiscreteSurface::sample +( + const volSymmTensorField& vField +) const +{ + return SurfaceSource::sampleField(vField); +} + + +Foam::tmp<Foam::tensorField> Foam::sampledDiscreteSurface::sample +( + const volTensorField& vField +) const +{ + return SurfaceSource::sampleField(vField); +} + + +Foam::tmp<Foam::scalarField> Foam::sampledDiscreteSurface::interpolate +( + const interpolation<scalar>& interpolator +) const +{ + return SurfaceSource::interpolateField(interpolator); +} + + +Foam::tmp<Foam::vectorField> Foam::sampledDiscreteSurface::interpolate +( + const interpolation<vector>& interpolator +) const +{ + return SurfaceSource::interpolateField(interpolator); +} + +Foam::tmp<Foam::sphericalTensorField> Foam::sampledDiscreteSurface::interpolate +( + const interpolation<sphericalTensor>& interpolator +) const +{ + return SurfaceSource::interpolateField(interpolator); +} + + +Foam::tmp<Foam::symmTensorField> Foam::sampledDiscreteSurface::interpolate +( + const interpolation<symmTensor>& interpolator +) const +{ + return SurfaceSource::interpolateField(interpolator); +} + + +Foam::tmp<Foam::tensorField> Foam::sampledDiscreteSurface::interpolate +( + const interpolation<tensor>& interpolator +) const +{ + return SurfaceSource::interpolateField(interpolator); +} + + +void Foam::sampledDiscreteSurface::print(Ostream& os) const +{ + os << "sampledDiscreteSurface: " << name() << " :"; + SurfaceSource::print(os); +} + + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/triSurfaceMesh/sampledDiscreteSurface.H b/src/sampling/sampledSurface/triSurfaceMesh/sampledDiscreteSurface.H new file mode 100644 index 0000000000000000000000000000000000000000..605bb0a67fbdb48beb1caf4a90c5482792ae50e6 --- /dev/null +++ b/src/sampling/sampledSurface/triSurfaceMesh/sampledDiscreteSurface.H @@ -0,0 +1,283 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2016 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::sampledDiscreteSurface + +Description + A sampledSurface from a triSurfaceMesh. + It samples on the points/triangles of a triSurfaceMesh. + +See Also + discreteSurface, sampledSurface + +SourceFiles + sampledDiscreteSurface.C + sampledDiscreteSurfaceTemplates.C + +\*---------------------------------------------------------------------------*/ + +#ifndef sampledDiscreteSurface_H +#define sampledDiscreteSurface_H + +#include "sampledSurface.H" +#include "discreteSurface.H" +#include "triSurfaceMesh.H" +#include "MeshedSurface.H" +#include "MeshedSurfacesFwd.H" + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class sampledDiscreteSurface; + +/*---------------------------------------------------------------------------*\ + Class sampledDiscreteSurface Declaration +\*---------------------------------------------------------------------------*/ + +class sampledDiscreteSurface +: + public sampledSurface, + public discreteSurface +{ + //- Private typedefs for convenience + typedef discreteSurface MeshStorage; + typedef discreteSurface SurfaceSource; + + + // Private Member Functions + + //- Sample field on faces + template<class Type> + tmp<Field<Type>> sampleField + ( + const GeometricField<Type, fvPatchField, volMesh>& vField + ) const; + + + template<class Type> + tmp<Field<Type>> + interpolateField(const interpolation<Type>&) const; + + +public: + + //- Runtime type information + TypeName("sampledDiscreteSurface"); + + + // Constructors + + //- Construct from components + sampledDiscreteSurface + ( + const word& name, + const polyMesh& mesh, + const word& surfaceName, + const discreteSurface::samplingSource sampleSource + ); + + //- Construct from dictionary + sampledDiscreteSurface + ( + const word& name, + const polyMesh& mesh, + const dictionary& dict + ); + + //- Construct from triSurface + sampledDiscreteSurface + ( + const word& name, + const polyMesh& mesh, + const triSurface& surface, + const word& sampleSourceName + ); + + + //- Destructor + virtual ~sampledDiscreteSurface(); + + + // 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(); + + //- Update the surface using a bound box to limit the searching. + // For direct use, i.e. not through sample. + // Do nothing (and return false) if no update was needed + bool update(const treeBoundBox&); + + //- Points of surface + virtual const pointField& points() const + { + return MeshStorage::points(); + } + + //- Faces of surface + virtual const faceList& faces() const + { + return MeshStorage::surfFaces(); + } + + //- Const access to per-face zone/region information + virtual const labelList& zoneIds() const + { + return MeshStorage::zoneIds(); + } + + //- Face area vectors + virtual const vectorField& Sf() const + { + return MeshStorage::Sf(); + } + + //- Face area magnitudes + virtual const scalarField& magSf() const + { + return MeshStorage::magSf(); + } + + //- Face centres + virtual const vectorField& Cf() const + { + return MeshStorage::Cf(); + } + + //- If element ids/order of the original surface are kept + bool keepIds() const + { + return MeshStorage::keepIds(); + } + + //- List of element ids/order of the original surface, + // when keepIds is active. + const labelList& originalIds() const + { + return MeshStorage::originalIds(); + } + + //- Sample the volume field onto surface, + // store it (temporarily) onto the given registry + virtual bool sampleAndStore + ( + const objectRegistry& store, + const word& fieldName + ) const; + + + //- Sample field on surface + virtual tmp<scalarField> sample + ( + const volScalarField& + ) const; + + //- Sample field on surface + virtual tmp<vectorField> sample + ( + const volVectorField& + ) const; + + //- Sample field on surface + virtual tmp<sphericalTensorField> sample + ( + const volSphericalTensorField& + ) const; + + //- Sample field on surface + virtual tmp<symmTensorField> sample + ( + const volSymmTensorField& + ) const; + + //- Sample field on surface + virtual tmp<tensorField> sample + ( + const volTensorField& + ) const; + + + //- Interpolate field on surface + virtual tmp<scalarField> interpolate + ( + const interpolation<scalar>& + ) const; + + + //- Interpolate field on surface + virtual tmp<vectorField> interpolate + ( + const interpolation<vector>& + ) const; + + //- Interpolate field on surface + virtual tmp<sphericalTensorField> interpolate + ( + const interpolation<sphericalTensor>& + ) const; + + //- Interpolate field on surface + virtual tmp<symmTensorField> interpolate + ( + const interpolation<symmTensor>& + ) const; + + //- Interpolate field on surface + virtual tmp<tensorField> interpolate + ( + const interpolation<tensor>& + ) const; + + //- Write information + virtual void print(Ostream&) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// #ifdef NoRepository +// #include "sampledDiscreteSurfaceTemplates.C" +// #endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/triSurfaceMesh/sampledDiscreteSurfaceTemplates.C b/src/sampling/sampledSurface/triSurfaceMesh/sampledDiscreteSurfaceTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..f6f67b89fdef69b7e43cf83ed940accbdb1fb82b --- /dev/null +++ b/src/sampling/sampledSurface/triSurfaceMesh/sampledDiscreteSurfaceTemplates.C @@ -0,0 +1,32 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 "sampledDiscreteSurface.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + + + +// ************************************************************************* // diff --git a/src/sampling/surfMeshSampler/plane/surfMeshPlaneSampler.C b/src/sampling/surfMeshSampler/plane/surfMeshPlaneSampler.C new file mode 100644 index 0000000000000000000000000000000000000000..b01b09a3552e1385d42f3e095321b93ea383c7a6 --- /dev/null +++ b/src/sampling/surfMeshSampler/plane/surfMeshPlaneSampler.C @@ -0,0 +1,204 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 "surfMeshPlaneSampler.H" +#include "dictionary.H" +#include "polyMesh.H" +#include "volFields.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(surfMeshPlaneSampler, 0); + addNamedToRunTimeSelectionTable + ( + surfMeshSampler, + surfMeshPlaneSampler, + word, + plane + ); +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::surfMeshPlaneSampler::transferContent() +{ + SurfaceSource& src = static_cast<SurfaceSource&>(*this); + surfMesh& dst = getOrCreateSurfMesh(); + + dst.transfer(src); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::surfMeshPlaneSampler::surfMeshPlaneSampler +( + const word& name, + const polyMesh& mesh, + const plane& planeDesc, + const keyType& zoneKey, + const bool triangulate +) +: + surfMeshSampler(name, mesh), + SurfaceSource(planeDesc), + zoneKey_(zoneKey), + triangulate_(triangulate), + needsUpdate_(true) +{ + if (debug && zoneKey_.size() && mesh.cellZones().findIndex(zoneKey_) < 0) + { + Info<< "cellZone " << zoneKey_ + << " not found - using entire mesh" << endl; + } +} + + +Foam::surfMeshPlaneSampler::surfMeshPlaneSampler +( + const word& name, + const polyMesh& mesh, + const dictionary& dict +) +: + surfMeshSampler(name, mesh, dict), + SurfaceSource(plane(dict)), + zoneKey_(keyType::null), + triangulate_(dict.lookupOrDefault("triangulate", true)), + needsUpdate_(true) +{ + // Make plane relative to the coordinateSystem (Cartesian) + // allow lookup from global coordinate systems + if (dict.found("coordinateSystem")) + { + coordinateSystem cs(mesh, dict.subDict("coordinateSystem")); + + point base = cs.globalPosition(planeDesc().refPoint()); + vector norm = cs.globalVector(planeDesc().normal()); + + // Assign the plane description + static_cast<plane&>(*this) = plane(base, norm); + } + + dict.readIfPresent("zone", zoneKey_); + + if (debug && zoneKey_.size() && mesh.cellZones().findIndex(zoneKey_) < 0) + { + Info<< "cellZone " << zoneKey_ + << " not found - using entire mesh" << endl; + } +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::surfMeshPlaneSampler::~surfMeshPlaneSampler() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::surfMeshPlaneSampler::needsUpdate() const +{ + return needsUpdate_; +} + + +bool Foam::surfMeshPlaneSampler::expire() +{ + // Already marked as expired + if (needsUpdate_) + { + return false; + } + + needsUpdate_ = true; + return true; +} + + +bool Foam::surfMeshPlaneSampler::update() +{ + if (!needsUpdate_) + { + return false; + } + + labelList selectedCells = mesh().cellZones().findMatching(zoneKey_).used(); + if (selectedCells.empty()) + { + reCut(mesh(), triangulate_); + } + else + { + Foam::sort(selectedCells); + reCut(mesh(), triangulate_, selectedCells); + } + + if (debug) + { + print(Pout); + Pout<< endl; + } + + transferContent(); + + needsUpdate_ = false; + return true; +} + + +bool Foam::surfMeshPlaneSampler::sample +( + const word& fieldName +) const +{ + return + ( + sampleType<scalar>(fieldName) + || sampleType<vector>(fieldName) + || sampleType<sphericalTensor>(fieldName) + || sampleType<symmTensor>(fieldName) + || sampleType<tensor>(fieldName) + ); +} + + +void Foam::surfMeshPlaneSampler::print(Ostream& os) const +{ + os << "surfMeshPlaneSampler: " << name() << " :" + << " base:" << cuttingPlane::refPoint() + << " normal:" << cuttingPlane::normal() + << " triangulate:" << triangulate_ + << " faces:" << SurfaceSource::surfFaces().size() + << " points:" << SurfaceSource::points().size(); +} + + +// ************************************************************************* // diff --git a/src/sampling/surfMeshSampler/plane/surfMeshPlaneSampler.H b/src/sampling/surfMeshSampler/plane/surfMeshPlaneSampler.H new file mode 100644 index 0000000000000000000000000000000000000000..5fe1f4deacb2af8ea4389015f7b1a8735fa1a753 --- /dev/null +++ b/src/sampling/surfMeshSampler/plane/surfMeshPlaneSampler.H @@ -0,0 +1,166 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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::surfMeshPlaneSampler + +Description + Sampling surfFields onto a surfMesh based on a plane. + The cuttingPlane algorithm 'cuts' the mesh. + The plane is triangulated by default. + +Note + Does not actually cut until update() called. + +SourceFiles + surfMeshPlaneSampler.C + surfMeshPlaneSamplerTemplates.C + +\*---------------------------------------------------------------------------*/ + +#ifndef surfMeshPlaneSampler_H +#define surfMeshPlaneSampler_H + +#include "surfMeshSampler.H" +#include "cuttingPlane.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class surfMeshPlaneSampler Declaration +\*---------------------------------------------------------------------------*/ + +class surfMeshPlaneSampler +: + public surfMeshSampler, + private cuttingPlane +{ + // Private typedefs for convenience + typedef cuttingPlane SurfaceSource; + + // Private data + + //- If restricted to zones, name of this zone or a regular expression + keyType zoneKey_; + + //- Triangulated faces or keep faces as is + const bool triangulate_; + + //- Track if the surface needs an update + mutable bool needsUpdate_; + + + // Private Member Functions + + //- Transfer mesh content from SurfaceSource to surfMesh + void transferContent(); + + + //- Sample field on surface. + template<class Type> + bool sampleType + ( + const word& fieldName + ) const; + + + //- Sample field on surface + template<class Type> + tmp<Field<Type>> sampleField + ( + const GeometricField<Type, fvPatchField, volMesh>& vField + ) const; + + +public: + + //- Runtime type information + TypeName("surfMeshPlaneSampler"); + + + // Constructors + + //- Construct from components + surfMeshPlaneSampler + ( + const word& name, + const polyMesh& mesh, + const plane& planeDesc, + const keyType& zoneKey = word::null, + const bool triangulate = true + ); + + //- Construct from dictionary + surfMeshPlaneSampler + ( + const word& name, + const polyMesh& mesh, + const dictionary& dict + ); + + + //- Destructor + virtual ~surfMeshPlaneSampler(); + + + // 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(); + + //- Sample the volume field onto surface + virtual bool sample(const word& fieldName) const; + + + //- Write + virtual void print(Ostream&) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "surfMeshPlaneSamplerTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/sampling/surfMeshSampler/plane/surfMeshPlaneSamplerTemplates.C b/src/sampling/surfMeshSampler/plane/surfMeshPlaneSamplerTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..e84d56545eb8e3588c2945cea93e1ea844f98415 --- /dev/null +++ b/src/sampling/surfMeshSampler/plane/surfMeshPlaneSamplerTemplates.C @@ -0,0 +1,63 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 "surfMeshPlaneSampler.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class Type> +bool Foam::surfMeshPlaneSampler::sampleType +( + const word& fieldName +) const +{ + typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType; + + if (!mesh().foundObject<VolFieldType>(fieldName)) + { + return false; + } + + const VolFieldType& fld = mesh().lookupObject<VolFieldType>(fieldName); + + getOrCreateSurfField<Type>(fld).field() + = SurfaceSource::sample<Type>(fld); + + return true; +} + + +template<class Type> +Foam::tmp<Foam::Field<Type>> +Foam::surfMeshPlaneSampler::sampleField +( + const GeometricField<Type, fvPatchField, volMesh>& vField +) const +{ + return SurfaceSource::sample<Type>(vField); +} + + +// ************************************************************************* // diff --git a/src/sampling/surfMeshSampler/surfMeshSampler/surfMeshSampler.C b/src/sampling/surfMeshSampler/surfMeshSampler/surfMeshSampler.C new file mode 100644 index 0000000000000000000000000000000000000000..a26a3e1623c8b311d4dc5f486a865dc98e36ad16 --- /dev/null +++ b/src/sampling/surfMeshSampler/surfMeshSampler/surfMeshSampler.C @@ -0,0 +1,224 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 "surfMeshSampler.H" +#include "MeshedSurfaces.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(surfMeshSampler, 0); + defineRunTimeSelectionTable(surfMeshSampler, word); +} + + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +Foam::surfMesh& +Foam::surfMeshSampler::getOrCreateSurfMesh() const +{ + if (!mesh().foundObject<surfMesh>(name())) + { + surfMesh* ptr = new surfMesh + ( + IOobject + ( + name(), + mesh().time().timeName(), + mesh(), + IOobject::NO_READ, + IOobject::NO_WRITE + ), + xferCopy(pointField()), // initially no points + xferCopy(faceList()), // initially no faces + name() + ); + ptr->setWriteOption(IOobject::NO_WRITE); + + mesh().objectRegistry::store(ptr); + } + + return const_cast<surfMesh&>(surface()); +} + + +// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * // + +Foam::autoPtr<Foam::surfMeshSampler> +Foam::surfMeshSampler::New +( + const word& name, + const polyMesh& mesh, + const dictionary& dict +) +{ + const word sampleType(dict.lookup("type")); + + wordConstructorTable::iterator cstrIter = + wordConstructorTablePtr_->find(sampleType); + + if (cstrIter == wordConstructorTablePtr_->end()) + { + FatalErrorInFunction + << "Unknown sample type " + << sampleType << nl << nl + << "Valid sample types : " << endl + << wordConstructorTablePtr_->sortedToc() + << exit(FatalError); + } + + return autoPtr<surfMeshSampler>(cstrIter()(name, mesh, dict)); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::surfMeshSampler::surfMeshSampler +( + const word& name, + const polyMesh& mesh +) +: + name_(name), + mesh_(mesh) +{} + + +Foam::surfMeshSampler::surfMeshSampler +( + const word& name, + const polyMesh& mesh, + const dictionary& dict +) +: + name_(name), + mesh_(mesh) +{ + dict.readIfPresent("name", name_); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::surfMeshSampler::~surfMeshSampler() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::surfMeshSampler::create() const +{ + getOrCreateSurfMesh(); +} + + +const Foam::surfMesh& Foam::surfMeshSampler::surface() const +{ + return mesh().lookupObject<surfMesh>(name()); +} + + +// Demonstration of using separate tmp registry +// Foam::label Foam::surfMeshSampler::sample +// ( +// const objectRegistry& store, +// const UList<word>& fields +// ) const +// { +// label count = 0; +// forAll(fields, fieldi) +// { +// const word& fieldName = fields[fieldi]; +// bool ok = +// ( +// sampleAndStore(store, fieldName) +// && +// ( +// transferField<scalar>(store, fieldName) +// || transferField<vector>(store, fieldName) +// || transferField<sphericalTensor>(store, fieldName) +// || transferField<symmTensor>(store, fieldName) +// || transferField<tensor>(store, fieldName) +// ) +// ); +// +// if (ok) +// { +// ++count; +// } +// } +// +// return count; +// } + + +Foam::label Foam::surfMeshSampler::sample +( + const UList<word>& fields +) const +{ + label count = 0; + forAll(fields, fieldi) + { + if (sample(fields[fieldi])) + { + ++count; + } + } + + return count; +} + + +Foam::label Foam::surfMeshSampler::write(const wordReList& select) const +{ + label count = + ( + writeFields<scalar>(select) + + writeFields<vector>(select) + + writeFields<sphericalTensor>(select) + + writeFields<symmTensor>(select) + + writeFields<tensor>(select) + ); + + if (count) + { + surface().write(); + } + + return count; +} + + + +void Foam::surfMeshSampler::print(Ostream& os) const +{ + os << type(); +} + + +// ************************************************************************* // diff --git a/src/sampling/surfMeshSampler/surfMeshSampler/surfMeshSampler.H b/src/sampling/surfMeshSampler/surfMeshSampler/surfMeshSampler.H new file mode 100644 index 0000000000000000000000000000000000000000..010429e390695e558f84812c2e21af28349fcde4 --- /dev/null +++ b/src/sampling/surfMeshSampler/surfMeshSampler/surfMeshSampler.H @@ -0,0 +1,285 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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::surfMeshSampler + +Group + grpUtilitiesFunctionObjects + +Description + An abstract class for surfMesh with sampling. + +SourceFiles + surfMeshSampler.C + surfMeshSamplerTemplates.C + +\*---------------------------------------------------------------------------*/ + +#ifndef surfMeshSampler_H +#define surfMeshSampler_H + +#include "surfMesh.H" +#include "surfFields.H" + +#include "pointField.H" +#include "word.H" +#include "labelList.H" +#include "faceList.H" +#include "typeInfo.H" +#include "runTimeSelectionTables.H" +#include "autoPtr.H" +#include "volFieldsFwd.H" +#include "surfaceFieldsFwd.H" +#include "polyMesh.H" +#include "coordinateSystems.H" +#include "interpolation.H" +#include "error.H" +#include "IOobjectList.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class surfMeshSampler; + +/*---------------------------------------------------------------------------*\ + Class surfMeshSampler Declaration +\*---------------------------------------------------------------------------*/ + +class surfMeshSampler +{ + // Private data + + //- Name for surfMesh lookup + word name_; + + //- Mesh reference + const polyMesh& mesh_; + + + // Private Member Functions + + // Service methods + + +protected: + + // Protected Member Functions + + //- Get existing or create new surfMesh + surfMesh& getOrCreateSurfMesh() const; + + //- Get existing or create new surfField. + // Create with same name and dimensions as the 'parent' volField. + template<class Type> + DimensionedField<Type, surfGeoMesh>& + getOrCreateSurfField + ( + const GeometricField<Type, fvPatchField, volMesh>& vField + ) const; + + + // //- Transfer field from object registry to surfField + // template<class Type> + // bool transferField + // ( + // const objectRegistry& store, + // const word& fieldName + // ) const; + + + //- Write the given fields + template<class Type> + label writeFields(const wordReList& select) const; + +public: + + //- Runtime type information + TypeName("surfMeshSampler"); + + + //- Declare run-time constructor selection table + declareRunTimeSelectionTable + ( + autoPtr, + surfMeshSampler, + word, + ( + const word& name, + const polyMesh& mesh, + const dictionary& dict + ), + (name, mesh, dict) + ); + + + // iNew helper class + + //- Class used for the PtrLists read-construction + class iNew + { + //- Reference to the volume mesh + const polyMesh& mesh_; + + public: + + iNew(const polyMesh& mesh) + : + mesh_(mesh) + {} + + autoPtr<surfMeshSampler> operator()(Istream& is) const + { + word name(is); + dictionary dict(is); + + return surfMeshSampler::New(name, mesh_, dict); + } + }; + + + // Constructors + + //- Construct from name, mesh + surfMeshSampler + ( + const word& name, + const polyMesh& mesh + ); + + //- Construct from dictionary + surfMeshSampler + ( + const word& name, + const polyMesh& mesh, + const dictionary& dict + ); + + + //- Clone + autoPtr<surfMeshSampler> clone() const + { + NotImplemented; + return autoPtr<surfMeshSampler>(nullptr); + } + + + + // Selectors + + //- Return a reference to the selected surface + static autoPtr<surfMeshSampler> New + ( + const word& name, + const polyMesh& mesh, + const dictionary& dict + ); + + + //- Destructor + virtual ~surfMeshSampler(); + + + // Member Functions + + // Access + + //- Access to the underlying mesh + const polyMesh& mesh() const + { + return mesh_; + } + + //- Name of surface + const word& name() const + { + return name_; + } + + + //- Create surfMesh if required. + void create() const; + + //- Return existing surfMesh. + virtual const surfMesh& surface() const; + + + //- Does the surface need an update? + virtual bool needsUpdate() const = 0; + + //- 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() = 0; + + //- Update the surface as required. + // Do nothing (and return false) if no update was needed + virtual bool update() = 0; + + + // Edit + + //- Rename + virtual void rename(const word& newName) + { + name_ = newName; + } + + + // Execute + + //- Sample from specified volume field to surface + virtual bool sample(const word& fieldName) const = 0; + + //- Sample from volume fields to specified surface fields. + virtual label sample(const UList<word>& fields) const; + + + // Write + + //- Write specified fields + virtual label write(const wordReList& fieldSelection) const; + + //- Write + virtual void print(Ostream&) const; + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "surfMeshSamplerTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/sampling/surfMeshSampler/surfMeshSampler/surfMeshSamplerTemplates.C b/src/sampling/surfMeshSampler/surfMeshSampler/surfMeshSamplerTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..a195865f81f7ba25ef93694476b0996ceaa7f07d --- /dev/null +++ b/src/sampling/surfMeshSampler/surfMeshSampler/surfMeshSamplerTemplates.C @@ -0,0 +1,125 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 "surfMeshSampler.H" +#include "dimensionedType.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class Type> +Foam::DimensionedField<Type, Foam::surfGeoMesh>& +Foam::surfMeshSampler::getOrCreateSurfField +( + const GeometricField<Type, fvPatchField, volMesh>& vField +) const +{ + typedef DimensionedField<Type, surfGeoMesh> SurfFieldType; + + const surfMesh& surf = surface(); + const word& fieldName = vField.name(); + + SurfFieldType* ptr = surf.lookupObjectRefPtr<SurfFieldType>(fieldName); + if (!ptr) + { + ptr = new SurfFieldType + ( + IOobject + ( + fieldName, + surf.time().timeName(), + surf, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + surf, + dimensioned<Type>("0", vField.dimensions(), Zero) + ); + ptr->writeOpt() = IOobject::NO_WRITE; + + surf.store(ptr); + } + + return *ptr; +} + + +// // Older code for transferring an IOField to a surfField between +// // different registries +// template<class Type> +// bool Foam::surfMeshSampler::transferField +// ( +// const objectRegistry& store, +// const word& fieldName +// ) const +// { +// typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType; +// typedef DimensionedField<Type, surfGeoMesh> SurfFieldType; +// typedef IOField<Type> TmpFieldType; +// +// // foundObject includes a type check +// bool ok = +// ( +// mesh_.foundObject<VolFieldType>(fieldName) +// && store.foundObject<TmpFieldType>(fieldName) +// ); +// +// if (ok) +// { +// SurfFieldType& sfield = getOrCreateSurfField +// ( +// mesh_.lookupObject<VolFieldType>(fieldName) +// ); +// +// TmpFieldType& iofield = +// store.lookupObjectRef<TmpFieldType>(fieldName); +// +// sfield.transfer(iofield); +// store.checkOut(iofield); +// } +// +// return ok; +// } + + +template<class Type> +Foam::label Foam::surfMeshSampler::writeFields +( + const wordReList& select +) const +{ + typedef DimensionedField<Type, surfGeoMesh> SurfFieldType; + const surfMesh& s = surface(); + + wordList names = s.sortedNames<SurfFieldType>(select); + forAll(names, namei) + { + s.lookupObject<SurfFieldType>(names[namei]).write(); + } + + return names.size(); +} + + +// ************************************************************************* // diff --git a/src/sampling/surfMeshSampler/surfMeshSamplers/surfMeshSamplers.C b/src/sampling/surfMeshSampler/surfMeshSamplers/surfMeshSamplers.C new file mode 100644 index 0000000000000000000000000000000000000000..38deded0516ea7b33925949573a539461b858b3e --- /dev/null +++ b/src/sampling/surfMeshSampler/surfMeshSamplers/surfMeshSamplers.C @@ -0,0 +1,421 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 "surfMeshSamplers.H" +#include "volFields.H" +#include "dictionary.H" +#include "Time.H" +#include "IOmanip.H" +#include "volPointInterpolation.H" +#include "PatchTools.H" +#include "mapPolyMesh.H" +#include "wordReListMatcher.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(surfMeshSamplers, 0); + addToRunTimeSelectionTable + ( + functionObject, + surfMeshSamplers, + dictionary + ); +} + + +bool Foam::surfMeshSamplers::verbose_ = false; + +void Foam::surfMeshSamplers::checkOutNames +( + const objectRegistry& registry, + const UList<word>& names +) +{ + objectRegistry& reg = const_cast<objectRegistry&>(registry); + + forAll(names, namei) + { + objectRegistry::iterator iter = reg.find(names[namei]); + if (iter != reg.end()) + { + registry.checkOut(*iter()); + } + } +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +// //- Temporary object registry for passing around values +// const objectRegistry& tmpRegistry() const; +// +// //- Temporary object registry for passing around values +// const objectRegistry& tmpRegistry(const word& subName) const; + +// const Foam::objectRegistry& +// Foam::surfMeshSamplers::tmpRegistry() const +// { +// // Sub-registry for sampling, choose name for fewer collisions +// return mesh_.thisDb().subRegistry +// ( +// "$tmp$" + type() + "$" + name(), +// true, +// false +// ); +// } +// +// +// const Foam::objectRegistry& +// Foam::surfMeshSamplers::tmpRegistry(const word& subName) const +// { +// return tmpRegistry().subRegistry(subName, true, false); +// } + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::surfMeshSamplers::surfMeshSamplers +( + const word& name, + const Time& runTime, + const dictionary& dict +) +: + functionObjects::regionFunctionObject(name, runTime, dict), + PtrList<surfMeshSampler>(), + mesh_(refCast<const fvMesh>(obr_)), + fieldSelection_() +{ + read(dict); +} + + +Foam::surfMeshSamplers::surfMeshSamplers +( + const word& name, + const objectRegistry& obr, + const dictionary& dict +) +: + functionObjects::regionFunctionObject(name, obr, dict), + PtrList<surfMeshSampler>(), + mesh_(refCast<const fvMesh>(obr)), + fieldSelection_(), + derivedNames_() +{ + read(dict); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::surfMeshSamplers::~surfMeshSamplers() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::surfMeshSamplers::verbose(const bool verbosity) +{ + verbose_ = verbosity; +} + + +bool Foam::surfMeshSamplers::execute() +{ + if (size()) + { + const objectRegistry& db = mesh_.thisDb(); + + // Manage derived names + DynamicList<word> added(derivedNames_.size()); + DynamicList<word> cleanup(derivedNames_.size()); + + forAll(derivedNames_, namei) + { + const word& derivedName = derivedNames_[namei]; + + if (derivedName == "rhoU") + { + added.append(derivedName); + + if (!db.foundObject<volVectorField>(derivedName)) + { + cleanup.append(derivedName); + + db.store + ( + new volVectorField + ( + derivedName, + // rhoU = rho * U + ( + mesh_.lookupObject<volScalarField>("rho") + * mesh_.lookupObject<volVectorField>("U") + ) + ) + ); + } + } + else if (derivedName == "pTotal") + { + added.append(derivedName); + + if (!db.foundObject<volScalarField>(derivedName)) + { + cleanup.append(derivedName); + + db.store + ( + new volScalarField + ( + derivedName, + // pTotal = p + U^2 / 2 + ( + mesh_.lookupObject<volScalarField>("p") + + 0.5 + * mesh_.lookupObject<volScalarField>("rho") + * magSqr(mesh_.lookupObject<volVectorField>("U")) + ) + ) + ); + } + } + else + { + WarningInFunction + << "unknown derived name: " << derivedName << nl + << "Use one of 'rhoU', 'pTotal'" << nl + << endl; + } + } + + // The acceptable fields + wordHashSet acceptable(added); + acceptable.insert(acceptType<scalar>()); + acceptable.insert(acceptType<vector>()); + acceptable.insert(acceptType<sphericalTensor>()); + acceptable.insert(acceptType<symmTensor>()); + acceptable.insert(acceptType<tensor>()); + + const wordList fields = acceptable.sortedToc(); + if (!fields.empty()) + { + forAll(*this, surfI) + { + surfMeshSampler& s = operator[](surfI); + + // Potentially monitor the update for writing geometry? + if (s.needsUpdate()) + { + s.update(); + } + + s.sample(fields); + } + } + + checkOutNames(db, cleanup); + } + + return true; +} + + +bool Foam::surfMeshSamplers::write() +{ + // Write sampled fields (on surface) + // + // Doesn't bother checking which fields have been generated here + // or elsewhere + + // This could be more efficient + wordReList select(fieldSelection_.size() + derivedNames_.size()); + + label nElem = 0; + forAll(fieldSelection_, i) + { + select[nElem++] = fieldSelection_[i]; + } + forAll(derivedNames_, i) + { + select[nElem++] = derivedNames_[i]; + } + + // avoid duplicate entries + select = wordReListMatcher::uniq(select); + + forAll(*this, surfI) + { + const surfMeshSampler& s = operator[](surfI); + s.write(select); + } + + return true; +} + + +bool Foam::surfMeshSamplers::read(const dictionary& dict) +{ + derivedNames_.clear(); + + const bool createOnRead = + dict.lookupOrDefault<Switch>("createOnRead", false); + + if (dict.found("surfaces")) + { + fieldSelection_ = wordReListMatcher::uniq + ( + wordReList(dict.lookup("fields")) + ); + Info<< type() << " fields: " << fieldSelection_ << nl; + + if (dict.readIfPresent("derived", derivedNames_)) + { + Info<< type() << " derived: " << derivedNames_ << nl; + } + + PtrList<surfMeshSampler> newList + ( + dict.lookup("surfaces"), + surfMeshSampler::iNew(mesh_) + ); + transfer(newList); + + // Ensure all surfaces and merge information are expired + expire(); + + // Need to initialize corresponding surfMesh for others in the chain. + // This can simply be a zero-sized placeholder, or the real surface with + // faces. + if (this->size()) + { + Info<< "Reading surface description:" << nl; + forAll(*this, surfI) + { + surfMeshSampler& s = operator[](surfI); + + Info<< " " << s.name() << nl; + if (createOnRead) + { + s.update(); + } + else + { + s.create(); + } + } + Info<< endl; + } + } + + return true; +} + + +void Foam::surfMeshSamplers::updateMesh(const mapPolyMesh& mpm) +{ + if (&mpm.mesh() == &mesh_) + { + expire(); + } + + // pointMesh and interpolation will have been reset in mesh.update +} + + +void Foam::surfMeshSamplers::movePoints(const polyMesh& m) +{ + if (&m == &mesh_) + { + expire(); + } +} + + +void Foam::surfMeshSamplers::readUpdate(const polyMesh::readUpdateState state) +{ + if (state != polyMesh::UNCHANGED) + { + expire(); + } +} + + +bool Foam::surfMeshSamplers::needsUpdate() const +{ + forAll(*this, surfI) + { + if (operator[](surfI).needsUpdate()) + { + return true; + } + } + + return false; +} + + +bool Foam::surfMeshSamplers::expire() +{ + bool justExpired = false; + + forAll(*this, surfI) + { + if (operator[](surfI).expire()) + { + justExpired = true; + } + } + + // True if any surfaces just expired + return justExpired; +} + + +bool Foam::surfMeshSamplers::update() +{ + if (!needsUpdate()) + { + return false; + } + + bool updated = false; + forAll(*this, surfI) + { + if (operator[](surfI).update()) + { + updated = true; + } + } + + return updated; +} + + +// ************************************************************************* // diff --git a/src/sampling/surfMeshSampler/surfMeshSamplers/surfMeshSamplers.H b/src/sampling/surfMeshSampler/surfMeshSamplers/surfMeshSamplers.H new file mode 100644 index 0000000000000000000000000000000000000000..b7f7fc8b5e2a326c05e8b3625df640b22fe20b2f --- /dev/null +++ b/src/sampling/surfMeshSampler/surfMeshSamplers/surfMeshSamplers.H @@ -0,0 +1,228 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +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::surfMeshSamplers + +Description + Set of surfaces to sample into a surfMesh/surfField. + + The execute() method is used to sample, and the write() method to write. + It is fairly common to use for sampling only and have the write disabled. + + \verbatim + surfaces + { + type surfMeshes; + libs ("libsampling.so"); + + // Sample at every time-step + executeControl timeStep; + executeInterval 1; + + // Disable writing (or write at same frequency as fields) + writeControl none; + writeInterval 1; + + // Fields to be sampled + fields (p U); + + // Optional: pre-defined derived fields to be sampled + derived (rhoU pTotal); + + // Optional: create surface immediately on read + // The default is to create a placeholder without any faces. + createOnRead false; + + surfaces + ( + f0surf + { + type sampledTriSurfaceMesh; + surface f0surf.obj; + source cells; + } + ); + } + \endverbatim + + +See also + Foam::sampledSurfaces + +SourceFiles + surfMeshSamplers.C + +\*---------------------------------------------------------------------------*/ + +#ifndef surfMeshSamplers_H +#define surfMeshSamplers_H + +#include "regionFunctionObject.H" +#include "surfMeshSampler.H" +#include "volFieldsFwd.H" +#include "surfaceFieldsFwd.H" +#include "wordReList.H" +#include "IOobjectList.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of classes +class Time; +class fvMesh; +class dictionary; + +/*---------------------------------------------------------------------------*\ + Class surfMeshSamplers Declaration +\*---------------------------------------------------------------------------*/ + +class surfMeshSamplers +: + public functionObjects::regionFunctionObject, + public PtrList<surfMeshSampler> +{ + // Static data members + + //- output verbosity + static bool verbose_; + + + // Private data + + //- Const reference to fvMesh + const fvMesh& mesh_; + + + // Read from dictonary + + //- Names of fields to sample + wordReList fieldSelection_; + + //- Names of derived fields to create and sample + wordList derivedNames_; + + + // Private Member Functions + + //- Remove items by name from objectRegistry + static void checkOutNames + ( + const objectRegistry& registry, + const UList<word>& names + ); + + + //- Filter acceptable fields types + template<class Type> + wordList acceptType() const; + + + //- Disallow default bitwise copy construct and assignment + surfMeshSamplers(const surfMeshSamplers&) = delete; + void operator=(const surfMeshSamplers&) = delete; + + +public: + + //- Runtime type information + TypeName("surfMeshes"); + + + // Constructors + + //- Construct from Time and dictionary + surfMeshSamplers + ( + const word& name, + const Time& time, + const dictionary& dict + ); + + //- Construct for given objectRegistry and dictionary + surfMeshSamplers + ( + const word& name, + const objectRegistry&, + const dictionary& + ); + + + //- Destructor + virtual ~surfMeshSamplers(); + + + // Member Functions + + //- Do any of the surfaces need an update? + virtual bool needsUpdate() const; + + //- Mark the surfaces as needing an update. + // May also free up unneeded data. + // Return false if all surfaces were already marked as expired. + virtual bool expire(); + + //- Update the surfaces as required and merge surface points (parallel). + // Return false if no surfaces required an update. + virtual bool update(); + + //- set verbosity level + void verbose(const bool verbosity = true); + + //- Read the surfMeshSamplers dictionary + virtual bool read(const dictionary&); + + //- Execute, does sampling + virtual bool execute(); + + //- Write sampled values + virtual bool write(); + + //- Update for changes of mesh - expires the surfaces + virtual void updateMesh(const mapPolyMesh&); + + //- Update for mesh point-motion - expires the surfaces + virtual void movePoints(const polyMesh&); + + //- Update for changes of mesh due to readUpdate - expires the surfaces + virtual void readUpdate(const polyMesh::readUpdateState state); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "surfMeshSamplersTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/sampling/surfMeshSampler/surfMeshSamplers/surfMeshSamplersTemplates.C b/src/sampling/surfMeshSampler/surfMeshSamplers/surfMeshSamplersTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..6eedaabed0343ea3532cb8caa088b711005132fc --- /dev/null +++ b/src/sampling/surfMeshSampler/surfMeshSamplers/surfMeshSamplersTemplates.C @@ -0,0 +1,66 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 "surfMeshSamplers.H" +#include "volFields.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class Type> +Foam::wordList +Foam::surfMeshSamplers::acceptType() const +{ + typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType; + + return mesh_.names<VolFieldType>(fieldSelection_); +} + +#if 0 +template<class Type> +Foam::wordList +Foam::surfMeshSamplers::acceptType +( + const IOobjectList& objects, + bool fromFiles +) const +{ + typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType; + + if (fromFiles_) + { + // This should actually be in the caller: + // IOobjectList objects1 = objects.lookup(fieldSelection_); + + return objects.names(VolFieldType::typeName, fieldSelection_); + } + else + { + return mesh_.names<VolFieldType>(fieldSelection_); + } +} +#endif + + +// ************************************************************************* // diff --git a/src/sampling/surfMeshSampler/triSurfaceMesh/surfMeshDiscreteSampler.C b/src/sampling/surfMeshSampler/triSurfaceMesh/surfMeshDiscreteSampler.C new file mode 100644 index 0000000000000000000000000000000000000000..bb82b29effcf64766c1feb82d56879a2c9e904d1 --- /dev/null +++ b/src/sampling/surfMeshSampler/triSurfaceMesh/surfMeshDiscreteSampler.C @@ -0,0 +1,160 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 "surfMeshDiscreteSampler.H" +#include "MeshedSurfaces.H" + +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(surfMeshDiscreteSampler, 0); + + // Add under name "sampledTriSurfaceMesh" + // for symmetry with normal sampledSurface + addNamedToRunTimeSelectionTable + ( + surfMeshSampler, + surfMeshDiscreteSampler, + word, + sampledTriSurfaceMesh + ); +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::surfMeshDiscreteSampler::transferContent() +{ + SurfaceSource& src = static_cast<SurfaceSource&>(*this); + surfMesh& dst = getOrCreateSurfMesh(); + + dst.transfer(src); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::surfMeshDiscreteSampler::surfMeshDiscreteSampler +( + const word& name, + const polyMesh& mesh, + const word& surfaceName, + const discreteSurface::samplingSource sampleSource +) +: + surfMeshSampler(name, mesh), + SurfaceSource(mesh, surfaceName, sampleSource, false) // no interpolate +{} + + +Foam::surfMeshDiscreteSampler::surfMeshDiscreteSampler +( + const word& name, + const polyMesh& mesh, + const dictionary& dict +) +: + surfMeshSampler(name, mesh), + SurfaceSource(mesh, dict, false) // no interpolate +{} + + +Foam::surfMeshDiscreteSampler::surfMeshDiscreteSampler +( + const word& name, + const polyMesh& mesh, + const triSurface& surface, + const word& sampleSourceName +) +: + surfMeshSampler(name, mesh), + SurfaceSource(name, mesh, surface, sampleSourceName, false) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::surfMeshDiscreteSampler::~surfMeshDiscreteSampler() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::surfMeshDiscreteSampler::needsUpdate() const +{ + return SurfaceSource::needsUpdate(); +} + + +bool Foam::surfMeshDiscreteSampler::expire() +{ + return SurfaceSource::expire(); +} + + +bool Foam::surfMeshDiscreteSampler::update() +{ + if (SurfaceSource::update()) + { + transferContent(); + return true; + } + + return false; +} + + +bool Foam::surfMeshDiscreteSampler::update(const treeBoundBox& bb) +{ + if (SurfaceSource::update(bb)) + { + transferContent(); + return true; + } + + return false; +} + + +bool Foam::surfMeshDiscreteSampler::sample +( + const word& fieldName +) const +{ + return + ( + sampleType<scalar>(fieldName) + || sampleType<vector>(fieldName) + || sampleType<sphericalTensor>(fieldName) + || sampleType<symmTensor>(fieldName) + || sampleType<tensor>(fieldName) + ); +} + + +// ************************************************************************* // diff --git a/src/sampling/surfMeshSampler/triSurfaceMesh/surfMeshDiscreteSampler.H b/src/sampling/surfMeshSampler/triSurfaceMesh/surfMeshDiscreteSampler.H new file mode 100644 index 0000000000000000000000000000000000000000..f2a3d643829fb71b186545184b417c7e2020d035 --- /dev/null +++ b/src/sampling/surfMeshSampler/triSurfaceMesh/surfMeshDiscreteSampler.H @@ -0,0 +1,153 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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::surfMeshDiscreteSampler + +Description + Sampling surfFields onto a surfMesh based on a triSurfaceMesh. + +See Also + discreteSurface, surfMeshSampler + +SourceFiles + surfMeshDiscreteSampler.C + +\*---------------------------------------------------------------------------*/ + +#ifndef surfMeshDiscreteSampler_H +#define surfMeshDiscreteSampler_H + +#include "surfMeshSampler.H" +#include "discreteSurface.H" +#include "triSurfaceMesh.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class surfMeshDiscreteSampler; + +/*---------------------------------------------------------------------------*\ + Class surfMeshDiscreteSampler Declaration +\*---------------------------------------------------------------------------*/ + +class surfMeshDiscreteSampler +: + public surfMeshSampler, + private discreteSurface +{ + // Private typedefs for convenience + typedef discreteSurface SurfaceSource; + + + // Private Member Functions + + //- Transfer mesh content from SurfaceSource to surfMesh + void transferContent(); + +public: + + //- Runtime type information + TypeName("surfMeshDiscreteSampler"); + + + // Constructors + + //- Construct from components + surfMeshDiscreteSampler + ( + const word& name, + const polyMesh& mesh, + const word& surfaceName, + const discreteSurface::samplingSource sampleSource + ); + + //- Construct from dictionary + surfMeshDiscreteSampler + ( + const word& name, + const polyMesh& mesh, + const dictionary& dict + ); + + //- Construct from triSurface + surfMeshDiscreteSampler + ( + const word& name, + const polyMesh& mesh, + const triSurface& surface, + const word& sampleSourceName + ); + + + //- Destructor + virtual ~surfMeshDiscreteSampler(); + + + // 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(); + + //- Update the surface using a bound box to limit the searching. + // For direct use, i.e. not through sample. + // Do nothing (and return false) if no update was needed + bool update(const treeBoundBox&); + + + //- Sample the volume field onto surface + virtual bool sample(const word& fieldName) const; + + //- Sample field on surface. + template<class Type> + bool sampleType(const word& fieldName) const; + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "surfMeshDiscreteSamplerTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/sampling/surfMeshSampler/triSurfaceMesh/surfMeshDiscreteSamplerTemplates.C b/src/sampling/surfMeshSampler/triSurfaceMesh/surfMeshDiscreteSamplerTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..34d78f4984c95de5da146c40686388cfc9d33ca0 --- /dev/null +++ b/src/sampling/surfMeshSampler/triSurfaceMesh/surfMeshDiscreteSamplerTemplates.C @@ -0,0 +1,97 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 "surfMeshDiscreteSampler.H" +#include "dimensionedType.H" +#include "error.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class Type> +bool Foam::surfMeshDiscreteSampler::sampleType +( + const word& fieldName +) const +{ + typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType; + + const polyMesh& mesh = SurfaceSource::mesh(); + + if (!mesh.foundObject<VolFieldType>(fieldName)) + { + return false; + } + + const VolFieldType& fld = mesh.lookupObject<VolFieldType>(fieldName); + + getOrCreateSurfField<Type>(fld).field() + = SurfaceSource::sampleField(fld); + + return true; +} + + +// template<class Type> +// Foam::tmp<Foam::DimensionedField<Type, Foam::surfGeoMesh>> +// Foam::surfMeshDiscreteSampler::sampleField +// ( +// const GeometricField<Type, fvPatchField, volMesh>& fld +// ) const +// { +// typedef DimensionedField<Type, surfGeoMesh> SurfFieldType; +// +// tmp<Field<Type>> tfield = SurfaceSource::sampleField(fld); +// SurfFieldType& result = getOrCreateSurfField<Type>(fld); +// +// // need to verify if this will be needed (in the future) +// const surfMesh& s = surface(); +// if (result.size() != s.size()) +// { +// // maybe resampling changed the surfMesh, +// // but the existing surfField wasn't updated +// +// result.setSize(s.size(), Zero); +// } +// +// if (result.size() != sampleElements().size()) +// { +// FatalErrorInFunction +// << "mismatch in field/mesh sizes " +// << result.name() << nl +// << " field has " << result.size() +// << " but sampleElements has " << sampleElements().size() << nl +// << endl +// << exit(FatalError); +// +// Info<< "WARNING: " +// << endl; +// } +// +// result = tfield; +// return result; +// } + + +// ************************************************************************* // diff --git a/src/sampling/surface/triSurfaceMesh/discreteSurface.C b/src/sampling/surface/triSurfaceMesh/discreteSurface.C new file mode 100644 index 0000000000000000000000000000000000000000..b6bc9d87d85d9b1c7fedd136b3a6af111a840516 --- /dev/null +++ b/src/sampling/surface/triSurfaceMesh/discreteSurface.C @@ -0,0 +1,868 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2016 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 "discreteSurface.H" +#include "meshSearch.H" +#include "Tuple2.H" +#include "globalIndex.H" +#include "treeDataCell.H" +#include "treeDataFace.H" +#include "meshTools.H" + +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(discreteSurface, 0); + + template<> + const char* NamedEnum<discreteSurface::samplingSource, 3>::names[] = + { + "cells", + "insideCells", + "boundaryFaces" + }; + + const NamedEnum<discreteSurface::samplingSource, 3> + discreteSurface::samplingSourceNames_; + + + //- Private class for finding nearest + // Comprising: + // - global index + // - sqr(distance) + typedef Tuple2<scalar, label> nearInfo; + + class nearestEqOp + { + public: + + void operator()(nearInfo& x, const nearInfo& y) const + { + if (y.first() < x.first()) + { + x = y; + } + } + }; +} + + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +void Foam::discreteSurface::setZoneMap +( + const surfZoneList& zoneLst, + labelList& zoneIds +) +{ + label sz = 0; + forAll(zoneLst, zonei) + { + const surfZone& zn = zoneLst[zonei]; + sz += zn.size(); + } + + zoneIds.setSize(sz); + forAll(zoneLst, zonei) + { + const surfZone& zn = zoneLst[zonei]; + + // Assign sub-zone Ids + SubList<label>(zoneIds, zn.size(), zn.start()) = zonei; + } +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +const Foam::indexedOctree<Foam::treeDataFace>& +Foam::discreteSurface::nonCoupledboundaryTree() const +{ + // Variant of meshSearch::boundaryTree() that only does non-coupled + // boundary faces. + + if (!boundaryTreePtr_.valid()) + { + // all non-coupled boundary faces (not just walls) + const polyBoundaryMesh& patches = mesh().boundaryMesh(); + + labelList bndFaces(mesh().nFaces()-mesh().nInternalFaces()); + label bndI = 0; + forAll(patches, patchi) + { + const polyPatch& pp = patches[patchi]; + if (!pp.coupled()) + { + forAll(pp, i) + { + bndFaces[bndI++] = pp.start()+i; + } + } + } + bndFaces.setSize(bndI); + + + treeBoundBox overallBb(mesh().points()); + Random rndGen(123456); + // Extend slightly and make 3D + overallBb = overallBb.extend(rndGen, 1e-4); + overallBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + overallBb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + + boundaryTreePtr_.reset + ( + new indexedOctree<treeDataFace> + ( + treeDataFace // all information needed to search faces + ( + false, // do not cache bb + mesh(), + bndFaces // boundary faces only + ), + overallBb, // overall search domain + 8, // maxLevel + 10, // leafsize + 3.0 // duplicity + ) + ); + } + + return boundaryTreePtr_(); +} + + +bool Foam::discreteSurface::update(const meshSearch& meshSearcher) +{ + // Find the cells the triangles of the surface are in. + // Does approximation by looking at the face centres only + const pointField& fc = surface_.faceCentres(); + + List<nearInfo> nearest(fc.size()); + + // Global numbering for cells/faces - only used to uniquely identify local + // elements + globalIndex globalCells(onBoundary() ? mesh().nFaces() : mesh().nCells()); + + forAll(nearest, i) + { + nearest[i].first() = GREAT; + nearest[i].second() = labelMax; + } + + if (sampleSource_ == cells) + { + // Search for nearest cell + + const indexedOctree<treeDataCell>& cellTree = meshSearcher.cellTree(); + + forAll(fc, triI) + { + pointIndexHit nearInfo = cellTree.findNearest + ( + fc[triI], + sqr(GREAT) + ); + if (nearInfo.hit()) + { + nearest[triI].first() = magSqr(nearInfo.hitPoint()-fc[triI]); + nearest[triI].second() = globalCells.toGlobal(nearInfo.index()); + } + } + } + else if (sampleSource_ == insideCells) + { + // Search for cell containing point + + const indexedOctree<treeDataCell>& cellTree = meshSearcher.cellTree(); + + forAll(fc, triI) + { + if (cellTree.bb().contains(fc[triI])) + { + const label index = cellTree.findInside(fc[triI]); + if (index != -1) + { + nearest[triI].first() = 0.0; + nearest[triI].second() = globalCells.toGlobal(index); + } + } + } + } + else + { + // Search for nearest boundaryFace + + ////- Search on all (including coupled) boundary faces + //const indexedOctree<treeDataFace>& bTree = meshSearcher.boundaryTree() + //- Search on all non-coupled boundary faces + const indexedOctree<treeDataFace>& bTree = nonCoupledboundaryTree(); + + forAll(fc, triI) + { + pointIndexHit nearInfo = bTree.findNearest + ( + fc[triI], + sqr(GREAT) + ); + if (nearInfo.hit()) + { + nearest[triI].first() = magSqr(nearInfo.hitPoint()-fc[triI]); + nearest[triI].second() = globalCells.toGlobal + ( + bTree.shapes().faceLabels()[nearInfo.index()] + ); + } + } + } + + + // See which processor has the nearest. Mark and subset + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Pstream::listCombineGather(nearest, nearestEqOp()); + Pstream::listCombineScatter(nearest); + + labelList cellOrFaceLabels(fc.size(), -1); + + label nFound = 0; + forAll(nearest, triI) + { + if (nearest[triI].second() == labelMax) + { + // Not found on any processor. How to map? + } + else if (globalCells.isLocal(nearest[triI].second())) + { + cellOrFaceLabels[triI] = globalCells.toLocal + ( + nearest[triI].second() + ); + nFound++; + } + } + + + if (debug) + { + Pout<< "Local out of faces:" << cellOrFaceLabels.size() + << " keeping:" << nFound << endl; + } + + // Now subset the surface. Do not use triSurface::subsetMesh since requires + // original surface to be in compact numbering. + + const triSurface& s = surface_; + + // Compact to original triangle + labelList faceMap(s.size()); + // Compact to original points + labelList pointMap(s.points().size()); + // From original point to compact points + labelList reversePointMap(s.points().size(), -1); + + // Handle region-wise sorting (makes things slightly more complicated) + zoneIds_.setSize(s.size(), -1); + + // Better not to use triSurface::sortedZones here, + // since we'll sort ourselves + + // Get zone/region sizes used, store under the original region Id + Map<label> zoneSizes; + + // Recover region names from the input surface + Map<word> zoneNames; + { + const geometricSurfacePatchList& patches = s.patches(); + + forAll(patches, patchi) + { + zoneNames.set + ( + patchi, + ( + patches[patchi].name().empty() + ? Foam::name("patch%d", patchi) + : patches[patchi].name() + ) + ); + + zoneSizes.set(patchi, 0); + } + } + + + { + label newPointi = 0; + label newFacei = 0; + + forAll(s, facei) + { + if (cellOrFaceLabels[facei] != -1) + { + const triSurface::FaceType& f = s[facei]; + const label regionid = f.region(); + + Map<label>::iterator fnd = zoneSizes.find(regionid); + if (fnd != zoneSizes.end()) + { + fnd()++; + } + else + { + // This shouldn't happen + zoneSizes.insert(regionid, 1); + zoneNames.set + ( + regionid, + Foam::name("patch%d", regionid) + ); + } + + // Store new faces compact + faceMap[newFacei] = facei; + zoneIds_[newFacei] = regionid; + ++newFacei; + + // Renumber face points + forAll(f, fp) + { + const label labI = f[fp]; + + if (reversePointMap[labI] == -1) + { + pointMap[newPointi] = labI; + reversePointMap[labI] = newPointi++; + } + } + } + } + + // Trim + faceMap.setSize(newFacei); + zoneIds_.setSize(newFacei); + pointMap.setSize(newPointi); + } + + + // Assign start/size (and name) to the newZones + // re-use the lookup to map (zoneId => zoneI) + surfZoneList zoneLst(zoneSizes.size()); + label start = 0; + label zoneI = 0; + forAllIter(Map<label>, zoneSizes, iter) + { + // No negative regionids, so Map<label> sorts properly + const label regionid = iter.key(); + + word name; + Map<word>::const_iterator fnd = zoneNames.find(regionid); + if (fnd != zoneNames.end()) + { + name = fnd(); + } + if (name.empty()) + { + name = ::Foam::name("patch%d", regionid); + } + + zoneLst[zoneI] = surfZone + ( + name, + 0, // initialize with zero size + start, + zoneI + ); + + // Adjust start for the next zone and save (zoneId => zoneI) mapping + start += iter(); + iter() = zoneI++; + } + + + // At this stage: + // - faceMap to map the (unsorted) compact to original triangle + // - zoneIds for the next sorting + // - zoneSizes contains region -> count information + + // Rebuild the faceMap for the sorted order + labelList sortedFaceMap(faceMap.size()); + + forAll(zoneIds_, facei) + { + label zonei = zoneIds_[facei]; + label sortedFacei = zoneLst[zonei].start() + zoneLst[zonei].size()++; + sortedFaceMap[sortedFacei] = faceMap[facei]; + } + + // zoneIds are now simply flat values + setZoneMap(zoneLst, zoneIds_); + + // Replace the faceMap with the properly sorted face map + faceMap.transfer(sortedFaceMap); + + if (keepIds_) + { + originalIds_ = faceMap; + } + + // Subset cellOrFaceLabels (for compact faces) + cellOrFaceLabels = UIndirectList<label>(cellOrFaceLabels, faceMap)(); + + // Store any face per point (without using pointFaces()) + labelList pointToFace(pointMap.size()); + + // Create faces and points for subsetted surface + faceList& surfFaces = this->storedFaces(); + surfFaces.setSize(faceMap.size()); + + this->storedZones().transfer(zoneLst); + + forAll(faceMap, facei) + { + const labelledTri& origF = s[faceMap[facei]]; + face& f = surfFaces[facei]; + + f = triFace + ( + reversePointMap[origF[0]], + reversePointMap[origF[1]], + reversePointMap[origF[2]] + ); + + forAll(f, fp) + { + pointToFace[f[fp]] = facei; + } + } + + this->storedPoints() = pointField(s.points(), pointMap); + + if (debug) + { + print(Pout); + Pout<< endl; + } + + + // Collect the samplePoints and sampleElements + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + if (interpolate()) + { + samplePoints_.setSize(pointMap.size()); + sampleElements_.setSize(pointMap.size(), -1); + + if (sampleSource_ == cells) + { + // samplePoints_ : per surface point a location inside the cell + // sampleElements_ : per surface point the cell + + forAll(points(), pointi) + { + const point& pt = points()[pointi]; + label celli = cellOrFaceLabels[pointToFace[pointi]]; + sampleElements_[pointi] = celli; + + // Check if point inside cell + if + ( + mesh().pointInCell + ( + pt, + sampleElements_[pointi], + meshSearcher.decompMode() + ) + ) + { + samplePoints_[pointi] = pt; + } + else + { + // Find nearest point on faces of cell + const cell& cFaces = mesh().cells()[celli]; + + scalar minDistSqr = VGREAT; + + forAll(cFaces, i) + { + const face& f = mesh().faces()[cFaces[i]]; + pointHit info = f.nearestPoint(pt, mesh().points()); + if (info.distance() < minDistSqr) + { + minDistSqr = info.distance(); + samplePoints_[pointi] = info.rawPoint(); + } + } + } + } + } + else if (sampleSource_ == insideCells) + { + // samplePoints_ : per surface point a location inside the cell + // sampleElements_ : per surface point the cell + + forAll(points(), pointi) + { + const point& pt = points()[pointi]; + label celli = cellOrFaceLabels[pointToFace[pointi]]; + sampleElements_[pointi] = celli; + samplePoints_[pointi] = pt; + } + } + else + { + // samplePoints_ : per surface point a location on the boundary + // sampleElements_ : per surface point the boundary face containing + // the location + + forAll(points(), pointi) + { + const point& pt = points()[pointi]; + label facei = cellOrFaceLabels[pointToFace[pointi]]; + sampleElements_[pointi] = facei; + samplePoints_[pointi] = mesh().faces()[facei].nearestPoint + ( + pt, + mesh().points() + ).rawPoint(); + } + } + } + else + { + // if sampleSource_ == cells: + // sampleElements_ : per surface triangle the cell + // samplePoints_ : n/a + // if sampleSource_ == insideCells: + // sampleElements_ : -1 or per surface triangle the cell + // samplePoints_ : n/a + // else: + // sampleElements_ : per surface triangle the boundary face + // samplePoints_ : n/a + sampleElements_.transfer(cellOrFaceLabels); + samplePoints_.clear(); + } + + + if (debug) + { + this->clearOut(); + OFstream str(mesh().time().path()/"surfaceToMesh.obj"); + Info<< "Dumping correspondence from local surface (points or faces)" + << " to mesh (cells or faces) to " << str.name() << endl; + + const vectorField& centres = + ( + onBoundary() + ? mesh().faceCentres() + : mesh().cellCentres() + ); + + if (interpolate()) + { + label vertI = 0; + forAll(samplePoints_, pointi) + { + meshTools::writeOBJ(str, points()[pointi]); + vertI++; + + meshTools::writeOBJ(str, samplePoints_[pointi]); + vertI++; + + label elemi = sampleElements_[pointi]; + meshTools::writeOBJ(str, centres[elemi]); + vertI++; + str << "l " << vertI-2 << ' ' << vertI-1 << ' ' << vertI << nl; + } + } + else + { + label vertI = 0; + forAll(sampleElements_, triI) + { + meshTools::writeOBJ(str, faceCentres()[triI]); + vertI++; + + label elemi = sampleElements_[triI]; + meshTools::writeOBJ(str, centres[elemi]); + vertI++; + str << "l " << vertI-1 << ' ' << vertI << nl; + } + } + } + + needsUpdate_ = false; + return true; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::discreteSurface::discreteSurface +( + const polyMesh& mesh, + const word& surfaceName, + const samplingSource sampleSource, + const bool allowInterpolate +) +: + MeshStorage(), + mesh_(mesh), + allowInterpolate_(allowInterpolate), + interpolate_(false), + surface_ + ( + IOobject + ( + surfaceName, + mesh.time().constant(), // instance + "triSurface", // local + mesh, // registry + IOobject::MUST_READ, + IOobject::NO_WRITE, + false + ) + ), + sampleSource_(sampleSource), + needsUpdate_(true), + keepIds_(false), + originalIds_(), + zoneIds_(), + sampleElements_(0), + samplePoints_(0) +{} + + +Foam::discreteSurface::discreteSurface +( + const polyMesh& mesh, + const dictionary& dict, + const bool allowInterpolate +) +: + MeshStorage(), + mesh_(mesh), + allowInterpolate_(allowInterpolate), + interpolate_ + ( + allowInterpolate + && dict.lookupOrDefault<Switch>("interpolate", false) + ), + surface_ + ( + IOobject + ( + dict.lookup("surface"), + mesh.time().constant(), // instance + "triSurface", // local + mesh, // registry + IOobject::MUST_READ, + IOobject::NO_WRITE, + false + ) + ), + sampleSource_(samplingSourceNames_[dict.lookup("source")]), + needsUpdate_(true), + keepIds_(dict.lookupOrDefault<Switch>("keepIds", false)), + originalIds_(), + zoneIds_(), + sampleElements_(0), + samplePoints_(0) +{} + + +Foam::discreteSurface::discreteSurface +( + const word& name, + const polyMesh& mesh, + const triSurface& surface, + const word& sampleSourceName, + const bool allowInterpolate +) +: + MeshStorage(), + mesh_(mesh), + allowInterpolate_(allowInterpolate), + interpolate_(false), + surface_ + ( + IOobject + ( + name, + mesh.time().constant(), // instance + "triSurface", // local + mesh, // registry + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + surface + ), + sampleSource_(samplingSourceNames_[sampleSourceName]), + needsUpdate_(true), + keepIds_(false), + originalIds_(), + zoneIds_(), + sampleElements_(0), + samplePoints_(0) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::discreteSurface::~discreteSurface() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::discreteSurface::interpolate() const +{ + return interpolate_; +} + +bool Foam::discreteSurface::interpolate(bool b) +{ + if (interpolate_ == b) + { + return false; + } + + if (b && !allowInterpolate_) + { + return false; + } + + // Value changed, old sampling information is invalid + interpolate_ = b; + expire(); + + return true; +} + + +bool Foam::discreteSurface::needsUpdate() const +{ + return needsUpdate_; +} + + +bool Foam::discreteSurface::expire() +{ + // already marked as expired + if (needsUpdate_) + { + return false; + } + + MeshStorage::clear(); + zoneIds_.clear(); + + originalIds_.clear(); + boundaryTreePtr_.clear(); + sampleElements_.clear(); + samplePoints_.clear(); + + needsUpdate_ = true; + return true; +} + + +bool Foam::discreteSurface::update() +{ + if (!needsUpdate_) + { + return false; + } + + // Calculate surface and mesh overlap bounding box + treeBoundBox bb + ( + surface_.triSurface::points(), + surface_.triSurface::meshPoints() + ); + bb.min() = max(bb.min(), mesh().bounds().min()); + bb.max() = min(bb.max(), mesh().bounds().max()); + + // Extend a bit + const vector span(bb.span()); + + bb.min() -= 0.5*span; + bb.max() += 0.5*span; + + bb.inflate(1e-6); + + // Mesh search engine, no triangulation of faces. + meshSearch meshSearcher(mesh(), bb, polyMesh::FACE_PLANES); + + return update(meshSearcher); +} + + +bool Foam::discreteSurface::update(const treeBoundBox& bb) +{ + if (!needsUpdate_) + { + return false; + } + + // Mesh search engine on subset, no triangulation of faces. + meshSearch meshSearcher(mesh(), bb, polyMesh::FACE_PLANES); + + return update(meshSearcher); +} + + +bool Foam::discreteSurface::sampleAndStore +( + const objectRegistry& store, + const word& fieldName +) const +{ + return + ( + sampleType<scalar>(store, fieldName) + || sampleType<vector>(store, fieldName) + || sampleType<sphericalTensor>(store, fieldName) + || sampleType<symmTensor>(store, fieldName) + || sampleType<tensor>(store, fieldName) + ); +} + + +void Foam::discreteSurface::print(Ostream& os) const +{ + os << "discreteSurface: " + << " surface:" << surface_.objectRegistry::name() + << " faces:" << this->surfFaces().size() + << " points:" << this->points().size() + << " zoneids:" << this->zoneIds().size(); +} + + +// ************************************************************************* // diff --git a/src/sampling/surface/triSurfaceMesh/discreteSurface.H b/src/sampling/surface/triSurfaceMesh/discreteSurface.H new file mode 100644 index 0000000000000000000000000000000000000000..5114a0974d5d1e62f3c7a9f1c8e05bc38453e1a3 --- /dev/null +++ b/src/sampling/surface/triSurfaceMesh/discreteSurface.H @@ -0,0 +1,341 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\/ M anipulation | Copyright (C) 2016 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::discreteSurface + +Description + The basis for sampling from triSurfaceMesh. + It samples on the points/triangles of the triSurface. + + - it either samples cells or (non-coupled) boundary faces + + - 6 different modes: + - source=cells, interpolate=false: + finds per triangle centre the nearest cell centre and uses its value + - source=cells, interpolate=true + finds per triangle centre the nearest cell centre. + Per surface point checks if this nearest cell is the one containing + point; otherwise projects the point onto the nearest point on + the boundary of the cell (to make sure interpolateCellPoint + gets a valid location) + + - source=insideCells, interpolate=false: + finds per triangle centre the cell containing it and uses its value. + Trims triangles outside mesh. + - source=insideCells, interpolate=true + Per surface point interpolate cell containing it. + + - source=boundaryFaces, interpolate=false: + finds per triangle centre the nearest point on the boundary + (uncoupled faces only) and uses the value (or 0 if the nearest + is on an empty boundary) + - source=boundaryFaces, interpolate=true: + finds per triangle centre the nearest point on the boundary + (uncoupled faces only). + Per surface point projects the point onto this boundary face + (to make sure interpolateCellPoint gets a valid location) + + - since it finds a nearest per triangle each triangle is guaranteed + to be on one processor only. So after stitching (by sampledSurfaces) + the original surface should be complete. + +SourceFiles + discreteSurface.C + discreteSurfaceTemplates.C + +\*---------------------------------------------------------------------------*/ + +#ifndef discreteSurface_H +#define discreteSurface_H + +#include "sampledSurface.H" +#include "triSurfaceMesh.H" +#include "MeshedSurface.H" +#include "MeshedSurfacesFwd.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class treeDataFace; +class meshSearch; + +/*---------------------------------------------------------------------------*\ + Class discreteSurface Declaration +\*---------------------------------------------------------------------------*/ + +class discreteSurface +: + public meshedSurface +{ +public: + //- Types of communications + enum samplingSource + { + cells, + insideCells, + boundaryFaces + }; + +private: + + //- Private typedefs for convenience + typedef meshedSurface MeshStorage; + + + // Private data + + static const NamedEnum<samplingSource, 3> samplingSourceNames_; + + //- Reference to mesh + const polyMesh& mesh_; + + //- Do we allow interpolation? + const bool allowInterpolate_; + + //- Do we intend to interpolate the information? + bool interpolate_; + + //- Surface to sample on + const triSurfaceMesh surface_; + + //- Whether to sample internal cell values or boundary values + const samplingSource sampleSource_; + + //- Track if the surface needs an update + mutable bool needsUpdate_; + + //- Retain element ids/order of original surface + bool keepIds_; + + //- List of element ids/order of the original surface, + // when keepIds is active. + labelList originalIds_; + + //- Search tree for all non-coupled boundary faces + mutable autoPtr<indexedOctree<treeDataFace>> boundaryTreePtr_; + + //- For compatibility with the meshSurf interface + labelList zoneIds_; + + //- From local surface triangle to mesh cell/face. + labelList sampleElements_; + + //- Local points to sample per point + pointField samplePoints_; + + + // Private Member Functions + + //- Get tree of all non-coupled boundary faces + const indexedOctree<treeDataFace>& nonCoupledboundaryTree() const; + + bool update(const meshSearch& meshSearcher); + + + //- Sample the volume field onto surface, + // store it (temporarily) onto the given registry + template<class Type> + bool sampleType + ( + const objectRegistry& store, + const word& fieldName + ) const; + + +public: + + //- Runtime type information + TypeName("discreteSurface"); + + + // Constructors + + //- Construct from components + discreteSurface + ( + const polyMesh& mesh, + const word& surfaceName, + const samplingSource sampleSource, + const bool allowInterpolate = true + ); + + //- Construct from dictionary + discreteSurface + ( + const polyMesh& mesh, + const dictionary& dict, + const bool allowInterpolate = true + ); + + //- Construct from triSurface + discreteSurface + ( + const word& name, + const polyMesh& mesh, + const triSurface& surface, + const word& sampleSourceName, + const bool allowInterpolate = true + ); + + + //- Destructor + virtual ~discreteSurface(); + + + // Member Functions + + //- Set new zoneIds list based on the surfZoneList information + static void setZoneMap(const surfZoneList&, labelList& zoneIds); + + + // Access + + //- Access to the underlying mesh + const polyMesh& mesh() const + { + return mesh_; + } + + //- Interpolation requested for surface + bool interpolate() const; + + //- Change interpolation request for surface. + // Return false if the value did not change. + // Use with caution. + bool interpolate(bool b); + + + //- 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(); + + //- Update the surface using a bound box to limit the searching. + // For direct use, i.e. not through sample. + // Do nothing (and return false) if no update was needed + bool update(const treeBoundBox&); + + + //- Const access to per-face zone/region information + virtual const labelList& zoneIds() const + { + return zoneIds_; + } + + //- If element ids/order of the original surface are kept + bool keepIds() const + { + return keepIds_; + } + + //- List of element ids/order of the original surface, + // when keepIds is active. + const labelList& originalIds() const + { + return originalIds_; + } + + + //- Sampling boundary values instead of cell values + bool onBoundary() const + { + return sampleSource_ == boundaryFaces; + } + + + //- From local surface face to mesh cell/face. + const labelList& sampleElements() const + { + return sampleElements_; + } + + //- Local points to sample per point + const pointField& samplePoints() const + { + return samplePoints_; + } + + + //- Sample the volume field onto surface, + // store it (temporarily) onto the given registry + virtual bool sampleAndStore + ( + const objectRegistry& store, + const word& fieldName + ) const; + + + //- Sample field on surface. The tmp field is 'valid' on success. + template<class Type> + tmp<Field<Type>> sampleType + ( + const word& fieldName + ) const; + + + //- Sample field on surface + template<class Type> + tmp<Field<Type>> sampleField + ( + const GeometricField<Type, fvPatchField, volMesh>& + ) const; + + + //- Interpolate field on surface + template<class Type> + tmp<Field<Type>> interpolateField + ( + const interpolation<Type>& + ) const; + + + //- Write information + virtual void print(Ostream&) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "discreteSurfaceTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/sampling/surface/triSurfaceMesh/discreteSurfaceTemplates.C b/src/sampling/surface/triSurfaceMesh/discreteSurfaceTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..c046d1e4886c6ea34e8b0cf5091217f68ab687fe --- /dev/null +++ b/src/sampling/surface/triSurfaceMesh/discreteSurfaceTemplates.C @@ -0,0 +1,231 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 "discreteSurface.H" +#include "surfFields.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class Type> +bool Foam::discreteSurface::sampleType +( + const objectRegistry& obr, + const word& fieldName +) const +{ + typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType; + typedef DimensionedField<Type, surfGeoMesh> SurfFieldType; + typedef IOField<Type> TmpFieldType; + + if (!mesh().foundObject<VolFieldType>(fieldName)) + { + return false; + } + + const VolFieldType& fld = mesh().lookupObject<VolFieldType>(fieldName); + tmp<Field<Type>> tfield = sampleField(fld); + + // The rest could be moved into a separate helper + if (isA<surfMesh>(obr)) + { + const surfMesh& surf = dynamicCast<const surfMesh>(obr); + + SurfFieldType* ptr = surf.lookupObjectRefPtr<SurfFieldType>(fieldName); + if (!ptr) + { + // Doesn't exist or the wrong type + ptr = new SurfFieldType + ( + IOobject + ( + fieldName, + surf.time().timeName(), + surf, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + surf, + dimensioned<Type>("0", fld.dimensions(), Zero) + ); + ptr->writeOpt() = IOobject::NO_WRITE; + + surf.store(ptr); + } + + ptr->field() = tfield; + } + else + { + TmpFieldType* ptr = obr.lookupObjectRefPtr<TmpFieldType>(fieldName); + if (!ptr) + { + // Doesn't exist or the wrong type + ptr = new TmpFieldType + ( + IOobject + ( + fieldName, + obr.time().timeName(), + obr, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + tfield().size() + ); + ptr->writeOpt() = IOobject::NO_WRITE; + + obr.store(ptr); + } + + *ptr = tfield; + } + + return true; +} + + +template<class Type> +Foam::tmp<Foam::Field<Type>> +Foam::discreteSurface::sampleType +( + const word& fieldName +) const +{ + typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType; + + if (mesh().foundObject<VolFieldType>(fieldName)) + { + const VolFieldType& fld = mesh().lookupObject<VolFieldType>(fieldName); + return sampleField(fld); + } + else + { + return tmp<Field<Type>>(); + } +} + + +template<class Type> +Foam::tmp<Foam::Field<Type>> +Foam::discreteSurface::sampleField +( + const GeometricField<Type, fvPatchField, volMesh>& vField +) const +{ + // One value per face + tmp<Field<Type>> tvalues(new Field<Type>(sampleElements_.size())); + Field<Type>& values = tvalues.ref(); + + if (!onBoundary()) + { + // Sample cells + + forAll(sampleElements_, triI) + { + values[triI] = vField[sampleElements_[triI]]; + } + } + else + { + // Sample boundary faces + + const polyBoundaryMesh& pbm = mesh().boundaryMesh(); + const label nBnd = mesh().nFaces()-mesh().nInternalFaces(); + + // Create flat boundary field + + Field<Type> bVals(nBnd, Zero); + + forAll(vField.boundaryField(), patchi) + { + label bFacei = pbm[patchi].start() - mesh().nInternalFaces(); + + SubList<Type> + ( + bVals, + vField.boundaryField()[patchi].size(), + bFacei + ) = vField.boundaryField()[patchi]; + } + + // Sample in flat boundary field + + forAll(sampleElements_, triI) + { + label facei = sampleElements_[triI]; + values[triI] = bVals[facei-mesh().nInternalFaces()]; + } + } + + return tvalues; +} + + +template<class Type> +Foam::tmp<Foam::Field<Type>> +Foam::discreteSurface::interpolateField +( + const interpolation<Type>& interpolator +) const +{ + // One value per vertex + tmp<Field<Type>> tvalues(new Field<Type>(sampleElements_.size())); + Field<Type>& values = tvalues.ref(); + + if (!onBoundary()) + { + // Sample cells. + + forAll(sampleElements_, pointi) + { + values[pointi] = interpolator.interpolate + ( + samplePoints_[pointi], + sampleElements_[pointi] + ); + } + } + else + { + // Sample boundary faces. + + forAll(samplePoints_, pointi) + { + label facei = sampleElements_[pointi]; + + values[pointi] = interpolator.interpolate + ( + samplePoints_[pointi], + mesh().faceOwner()[facei], + facei + ); + } + } + + return tvalues; +} + + +// ************************************************************************* //