mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: new sampled faceZones (#1874)
This commit is contained in:
@ -35,6 +35,7 @@ surface/isoSurface/isoSurfaceTopo.C
|
|||||||
surface/thresholdCellFaces/thresholdCellFaces.C
|
surface/thresholdCellFaces/thresholdCellFaces.C
|
||||||
|
|
||||||
sampledSurface/sampledNone/sampledNone.C
|
sampledSurface/sampledNone/sampledNone.C
|
||||||
|
sampledSurface/sampledFaceZone/sampledFaceZone.C
|
||||||
sampledSurface/sampledPatch/sampledPatch.C
|
sampledSurface/sampledPatch/sampledPatch.C
|
||||||
sampledSurface/sampledPatchInternalField/sampledPatchInternalField.C
|
sampledSurface/sampledPatchInternalField/sampledPatchInternalField.C
|
||||||
sampledSurface/sampledPlane/sampledPlane.C
|
sampledSurface/sampledPlane/sampledPlane.C
|
||||||
|
|||||||
402
src/sampling/sampledSurface/sampledFaceZone/sampledFaceZone.C
Normal file
402
src/sampling/sampledSurface/sampledFaceZone/sampledFaceZone.C
Normal file
@ -0,0 +1,402 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "sampledFaceZone.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
#include "polyMesh.H"
|
||||||
|
#include "polyPatch.H"
|
||||||
|
#include "volFields.H"
|
||||||
|
#include "surfaceFields.H"
|
||||||
|
#include "volPointInterpolation.H"
|
||||||
|
#include "uindirectPrimitivePatch.H"
|
||||||
|
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(sampledFaceZone, 0);
|
||||||
|
addNamedToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
sampledSurface,
|
||||||
|
sampledFaceZone,
|
||||||
|
word,
|
||||||
|
faceZone
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::sampledFaceZone::sampledFaceZone
|
||||||
|
(
|
||||||
|
const word& name,
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const UList<wordRe>& zoneNames,
|
||||||
|
const bool triangulate
|
||||||
|
)
|
||||||
|
:
|
||||||
|
sampledSurface(name, mesh),
|
||||||
|
selectionNames_(zoneNames),
|
||||||
|
triangulate_(triangulate),
|
||||||
|
needsUpdate_(true)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::sampledFaceZone::sampledFaceZone
|
||||||
|
(
|
||||||
|
const word& name,
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
sampledSurface(name, mesh, dict),
|
||||||
|
selectionNames_(dict.get<wordRes>("zones")),
|
||||||
|
triangulate_(dict.getOrDefault("triangulate", false)),
|
||||||
|
needsUpdate_(true)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
const Foam::labelList& Foam::sampledFaceZone::zoneIDs() const
|
||||||
|
{
|
||||||
|
if (zoneIds_.empty())
|
||||||
|
{
|
||||||
|
// Zone indices for all matches, already sorted
|
||||||
|
zoneIds_ = mesh().faceZones().indices(selectionNames_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return zoneIds_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::sampledFaceZone::needsUpdate() const
|
||||||
|
{
|
||||||
|
return needsUpdate_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::sampledFaceZone::expire()
|
||||||
|
{
|
||||||
|
// already marked as expired
|
||||||
|
if (needsUpdate_)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sampledSurface::clearGeom();
|
||||||
|
Mesh::clear();
|
||||||
|
|
||||||
|
zoneIds_.clear();
|
||||||
|
|
||||||
|
faceId_.clear();
|
||||||
|
facePatchId_.clear();
|
||||||
|
|
||||||
|
needsUpdate_ = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::sampledFaceZone::update()
|
||||||
|
{
|
||||||
|
if (!needsUpdate_)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Total number of faces selected
|
||||||
|
label numFaces = 0;
|
||||||
|
for (const label zonei : zoneIDs())
|
||||||
|
{
|
||||||
|
numFaces += mesh().faceZones()[zonei].size();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zoneIDs().empty())
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< type() << ' ' << name() << ": "
|
||||||
|
<< " No matching face zone(s): "
|
||||||
|
<< flatOutput(selectionNames_) << nl
|
||||||
|
<< " Known face zones: "
|
||||||
|
<< flatOutput(mesh().faceZones().names()) << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Could also check numFaces
|
||||||
|
|
||||||
|
// The mesh face or local patch face and the patch id
|
||||||
|
faceId_.resize(numFaces);
|
||||||
|
facePatchId_.resize(numFaces);
|
||||||
|
|
||||||
|
IndirectList<face> selectedFaces(mesh().faces(), labelList());
|
||||||
|
labelList& meshFaceIds = selectedFaces.addressing();
|
||||||
|
meshFaceIds.resize(numFaces);
|
||||||
|
|
||||||
|
numFaces = 0;
|
||||||
|
|
||||||
|
forAll(zoneIDs(), idx)
|
||||||
|
{
|
||||||
|
const label zonei = zoneIDs()[idx];
|
||||||
|
const faceZone& fZone = mesh().faceZones()[zonei];
|
||||||
|
|
||||||
|
for (const label meshFacei : fZone)
|
||||||
|
{
|
||||||
|
// Internal faces
|
||||||
|
label faceId = meshFacei;
|
||||||
|
label facePatchId = -1;
|
||||||
|
|
||||||
|
// Boundary faces
|
||||||
|
if (!mesh().isInternalFace(meshFacei))
|
||||||
|
{
|
||||||
|
facePatchId = mesh().boundaryMesh().whichPatch(meshFacei);
|
||||||
|
const polyPatch& pp = mesh().boundaryMesh()[facePatchId];
|
||||||
|
|
||||||
|
if (isA<emptyPolyPatch>(pp))
|
||||||
|
{
|
||||||
|
// Do not sample an empty patch
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto* procPatch = isA<processorPolyPatch>(pp);
|
||||||
|
if (procPatch && !procPatch->owner())
|
||||||
|
{
|
||||||
|
// Do not sample neighbour-side, retain owner-side only
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto* cpp = isA<coupledPolyPatch>(pp);
|
||||||
|
if (cpp)
|
||||||
|
{
|
||||||
|
faceId = (cpp->owner() ? pp.whichFace(meshFacei) : -1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
faceId = meshFacei - pp.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (faceId >= 0)
|
||||||
|
{
|
||||||
|
faceId_[numFaces] = faceId;
|
||||||
|
facePatchId_[numFaces] = facePatchId;
|
||||||
|
meshFaceIds[numFaces] = meshFacei;
|
||||||
|
++numFaces;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shrink to size used
|
||||||
|
faceId_.resize(numFaces);
|
||||||
|
facePatchId_.resize(numFaces);
|
||||||
|
meshFaceIds.resize(numFaces);
|
||||||
|
|
||||||
|
uindirectPrimitivePatch zoneFaces(selectedFaces, mesh().points());
|
||||||
|
|
||||||
|
this->storedPoints() = zoneFaces.localPoints();
|
||||||
|
this->storedFaces() = zoneFaces.localFaces();
|
||||||
|
|
||||||
|
// triangulate - uses remapFaces()
|
||||||
|
if (triangulate_)
|
||||||
|
{
|
||||||
|
Mesh::triangulate();
|
||||||
|
}
|
||||||
|
|
||||||
|
needsUpdate_ = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// remap action on triangulation
|
||||||
|
void Foam::sampledFaceZone::remapFaces(const labelUList& faceMap)
|
||||||
|
{
|
||||||
|
if (!faceMap.empty())
|
||||||
|
{
|
||||||
|
Mesh::remapFaces(faceMap);
|
||||||
|
faceId_ = labelList
|
||||||
|
(
|
||||||
|
labelUIndList(faceId_, faceMap)
|
||||||
|
);
|
||||||
|
facePatchId_ = labelList
|
||||||
|
(
|
||||||
|
labelUIndList(facePatchId_, faceMap)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::scalarField> Foam::sampledFaceZone::sample
|
||||||
|
(
|
||||||
|
const interpolation<scalar>& sampler
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sampleOnFaces(sampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::vectorField> Foam::sampledFaceZone::sample
|
||||||
|
(
|
||||||
|
const interpolation<vector>& sampler
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sampleOnFaces(sampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::sphericalTensorField> Foam::sampledFaceZone::sample
|
||||||
|
(
|
||||||
|
const interpolation<sphericalTensor>& sampler
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sampleOnFaces(sampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::symmTensorField> Foam::sampledFaceZone::sample
|
||||||
|
(
|
||||||
|
const interpolation<symmTensor>& sampler
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sampleOnFaces(sampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::tensorField> Foam::sampledFaceZone::sample
|
||||||
|
(
|
||||||
|
const interpolation<tensor>& sampler
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sampleOnFaces(sampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::sampledFaceZone::withSurfaceFields() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::scalarField> Foam::sampledFaceZone::sample
|
||||||
|
(
|
||||||
|
const surfaceScalarField& sField
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sampleOnFaces(sField);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::vectorField> Foam::sampledFaceZone::sample
|
||||||
|
(
|
||||||
|
const surfaceVectorField& sField
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sampleOnFaces(sField);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::sphericalTensorField> Foam::sampledFaceZone::sample
|
||||||
|
(
|
||||||
|
const surfaceSphericalTensorField& sField
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sampleOnFaces(sField);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::symmTensorField> Foam::sampledFaceZone::sample
|
||||||
|
(
|
||||||
|
const surfaceSymmTensorField& sField
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sampleOnFaces(sField);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::tensorField> Foam::sampledFaceZone::sample
|
||||||
|
(
|
||||||
|
const surfaceTensorField& sField
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sampleOnFaces(sField);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::scalarField> Foam::sampledFaceZone::interpolate
|
||||||
|
(
|
||||||
|
const interpolation<scalar>& interpolator
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sampleOnPoints(interpolator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::vectorField> Foam::sampledFaceZone::interpolate
|
||||||
|
(
|
||||||
|
const interpolation<vector>& interpolator
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sampleOnPoints(interpolator);
|
||||||
|
}
|
||||||
|
|
||||||
|
Foam::tmp<Foam::sphericalTensorField>
|
||||||
|
Foam::sampledFaceZone::interpolate
|
||||||
|
(
|
||||||
|
const interpolation<sphericalTensor>& interpolator
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sampleOnPoints(interpolator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::symmTensorField> Foam::sampledFaceZone::interpolate
|
||||||
|
(
|
||||||
|
const interpolation<symmTensor>& interpolator
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sampleOnPoints(interpolator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::tensorField> Foam::sampledFaceZone::interpolate
|
||||||
|
(
|
||||||
|
const interpolation<tensor>& interpolator
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sampleOnPoints(interpolator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::sampledFaceZone::print(Ostream& os) const
|
||||||
|
{
|
||||||
|
os << "faceZone: " << name() << " :"
|
||||||
|
<< " zones: " << flatOutput(selectionNames_)
|
||||||
|
<< " faces:" << faces().size()
|
||||||
|
<< " points:" << points().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
345
src/sampling/sampledSurface/sampledFaceZone/sampledFaceZone.H
Normal file
345
src/sampling/sampledSurface/sampledFaceZone/sampledFaceZone.H
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::sampledFaceZone
|
||||||
|
|
||||||
|
Description
|
||||||
|
A sampledSurface defined by the cell faces corresponding to a threshold
|
||||||
|
value.
|
||||||
|
|
||||||
|
This is often embedded as part of a sampled surfaces function object.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
Example of function object partial specification:
|
||||||
|
\verbatim
|
||||||
|
surfaces
|
||||||
|
(
|
||||||
|
surface1
|
||||||
|
{
|
||||||
|
type faceZones;
|
||||||
|
zones (zone1 "sides.*");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
Where the sub-entries comprise:
|
||||||
|
\table
|
||||||
|
Property | Description | Required | Default
|
||||||
|
type | faceZones | yes |
|
||||||
|
zones | zone selection as word/regex list | yes |
|
||||||
|
triangulate | triangulate faces | no | false
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
sampledFaceZone.C
|
||||||
|
sampledFaceZoneTemplates.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef sampledFaceZone_H
|
||||||
|
#define sampledFaceZone_H
|
||||||
|
|
||||||
|
#include "sampledSurface.H"
|
||||||
|
#include "MeshedSurfaces.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class sampledFaceZone Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class sampledFaceZone
|
||||||
|
:
|
||||||
|
public meshedSurface,
|
||||||
|
public sampledSurface
|
||||||
|
{
|
||||||
|
//- Mesh storage type
|
||||||
|
typedef meshedSurface Mesh;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Selection (word/regex) of face zones
|
||||||
|
const wordRes selectionNames_;
|
||||||
|
|
||||||
|
//- IDs for selected face zones (sorted)
|
||||||
|
mutable labelList zoneIds_;
|
||||||
|
|
||||||
|
//- Triangulated faces or keep faces as is
|
||||||
|
bool triangulate_;
|
||||||
|
|
||||||
|
//- Track if the surface needs an update
|
||||||
|
mutable bool needsUpdate_;
|
||||||
|
|
||||||
|
//- Local list of face IDs
|
||||||
|
labelList faceId_;
|
||||||
|
|
||||||
|
//- Local list of patch ID per face. Is -1 for internal face
|
||||||
|
labelList facePatchId_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Sample volume/boundary field onto surface faces
|
||||||
|
template<class Type>
|
||||||
|
tmp<Field<Type>> sampleOnFaces
|
||||||
|
(
|
||||||
|
const interpolation<Type>& sampler
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Sample surface field onto surface faces
|
||||||
|
template<class Type>
|
||||||
|
tmp<Field<Type>> sampleOnFaces
|
||||||
|
(
|
||||||
|
const GeometricField<Type, fvsPatchField, surfaceMesh>& sField
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Interpolate volume/boundary field onto surface points
|
||||||
|
template<class Type>
|
||||||
|
tmp<Field<Type>> sampleOnPoints
|
||||||
|
(
|
||||||
|
const interpolation<Type>& interpolator
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
//- Re-map action on triangulation or cleanup
|
||||||
|
virtual void remapFaces(const labelUList& faceMap);
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//- The selected face zones (sorted)
|
||||||
|
const labelList& zoneIDs() const;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("faceZone");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
sampledFaceZone
|
||||||
|
(
|
||||||
|
const word& name,
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const UList<wordRe>& zoneNames,
|
||||||
|
const bool triangulate = false
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from dictionary
|
||||||
|
sampledFaceZone
|
||||||
|
(
|
||||||
|
const word& name,
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const dictionary& dict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~sampledFaceZone() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
//- Points of surface
|
||||||
|
virtual const pointField& points() const
|
||||||
|
{
|
||||||
|
return Mesh::points();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Faces of surface
|
||||||
|
virtual const faceList& faces() const
|
||||||
|
{
|
||||||
|
return Mesh::surfFaces();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Per-face zone/region information
|
||||||
|
virtual const labelList& zoneIds() const
|
||||||
|
{
|
||||||
|
return labelList::null();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Face area vectors (normals)
|
||||||
|
virtual const vectorField& Sf() const
|
||||||
|
{
|
||||||
|
return Mesh::Sf();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Face area magnitudes
|
||||||
|
virtual const scalarField& magSf() const
|
||||||
|
{
|
||||||
|
return Mesh::magSf();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Face centres
|
||||||
|
virtual const vectorField& Cf() const
|
||||||
|
{
|
||||||
|
return Mesh::Cf();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Sample
|
||||||
|
|
||||||
|
//- Sample volume field onto surface faces
|
||||||
|
virtual tmp<scalarField> sample
|
||||||
|
(
|
||||||
|
const interpolation<scalar>& sampler
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Sample volume field onto surface faces
|
||||||
|
virtual tmp<vectorField> sample
|
||||||
|
(
|
||||||
|
const interpolation<vector>& sampler
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Sample volume field onto surface faces
|
||||||
|
virtual tmp<sphericalTensorField> sample
|
||||||
|
(
|
||||||
|
const interpolation<sphericalTensor>& sampler
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Sample volume field onto surface faces
|
||||||
|
virtual tmp<symmTensorField> sample
|
||||||
|
(
|
||||||
|
const interpolation<symmTensor>& sampler
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Sample volume field onto surface faces
|
||||||
|
virtual tmp<tensorField> sample
|
||||||
|
(
|
||||||
|
const interpolation<tensor>& sampler
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
//- Can it sample surface-fields?
|
||||||
|
virtual bool withSurfaceFields() const;
|
||||||
|
|
||||||
|
|
||||||
|
//- Sample surface field on face zone
|
||||||
|
virtual tmp<scalarField> sample
|
||||||
|
(
|
||||||
|
const surfaceScalarField&
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Sample surface field on face zone
|
||||||
|
virtual tmp<vectorField> sample
|
||||||
|
(
|
||||||
|
const surfaceVectorField&
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Sample surface field on face zone
|
||||||
|
virtual tmp<sphericalTensorField> sample
|
||||||
|
(
|
||||||
|
const surfaceSphericalTensorField&
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Sample surface field on face zone
|
||||||
|
virtual tmp<symmTensorField> sample
|
||||||
|
(
|
||||||
|
const surfaceSymmTensorField&
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Sample surface field on face zone
|
||||||
|
virtual tmp<tensorField> sample
|
||||||
|
(
|
||||||
|
const surfaceTensorField&
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Interpolate
|
||||||
|
|
||||||
|
//- Interpolate volume field onto surface points
|
||||||
|
virtual tmp<scalarField> interpolate
|
||||||
|
(
|
||||||
|
const interpolation<scalar>& interpolator
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Interpolate volume field onto surface points
|
||||||
|
virtual tmp<vectorField> interpolate
|
||||||
|
(
|
||||||
|
const interpolation<vector>& interpolator
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Interpolate volume field onto surface points
|
||||||
|
virtual tmp<sphericalTensorField> interpolate
|
||||||
|
(
|
||||||
|
const interpolation<sphericalTensor>& interpolator
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Interpolate volume field onto surface points
|
||||||
|
virtual tmp<symmTensorField> interpolate
|
||||||
|
(
|
||||||
|
const interpolation<symmTensor>& interpolator
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Interpolate volume field onto surface points
|
||||||
|
virtual tmp<tensorField> interpolate
|
||||||
|
(
|
||||||
|
const interpolation<tensor>& interpolator
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
// Output
|
||||||
|
|
||||||
|
//- Print information
|
||||||
|
virtual void print(Ostream& os) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
#include "sampledFaceZoneTemplates.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,153 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "sampledFaceZone.H"
|
||||||
|
#include "volFieldsFwd.H"
|
||||||
|
#include "pointFields.H"
|
||||||
|
#include "volPointInterpolation.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::tmp<Foam::Field<Type>>
|
||||||
|
Foam::sampledFaceZone::sampleOnFaces
|
||||||
|
(
|
||||||
|
const interpolation<Type>& sampler
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const auto& vField = sampler.psi();
|
||||||
|
const labelList& own = mesh().faceOwner();
|
||||||
|
const labelList& nei = mesh().faceNeighbour();
|
||||||
|
|
||||||
|
// One value per face
|
||||||
|
auto tvalues = tmp<Field<Type>>::New(faceId_.size());
|
||||||
|
auto& values = tvalues.ref();
|
||||||
|
|
||||||
|
forAll(faceId_, i)
|
||||||
|
{
|
||||||
|
const label facei = faceId_[i];
|
||||||
|
const label patchi = facePatchId_[i];
|
||||||
|
|
||||||
|
if (patchi != -1)
|
||||||
|
{
|
||||||
|
// Boundary face - face id is the patch-local face id
|
||||||
|
values[i] = vField.boundaryField()[patchi][facei];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Internal face
|
||||||
|
values[i] = 0.5*(vField[own[facei]] + vField[nei[facei]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tvalues;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::tmp<Foam::Field<Type>>
|
||||||
|
Foam::sampledFaceZone::sampleOnFaces
|
||||||
|
(
|
||||||
|
const GeometricField<Type, fvsPatchField, surfaceMesh>& sField
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// One value per face
|
||||||
|
auto tvalues = tmp<Field<Type>>::New(faceId_.size());
|
||||||
|
auto& values = tvalues.ref();
|
||||||
|
|
||||||
|
forAll(faceId_, i)
|
||||||
|
{
|
||||||
|
const label facei = faceId_[i];
|
||||||
|
const label patchi = facePatchId_[i];
|
||||||
|
|
||||||
|
if (patchi != -1)
|
||||||
|
{
|
||||||
|
// Boundary face - face id is the patch-local face id
|
||||||
|
values[i] = sField.boundaryField()[patchi][facei];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Internal face
|
||||||
|
values[i] = sField[facei];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tvalues;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::tmp<Foam::Field<Type>>
|
||||||
|
Foam::sampledFaceZone::sampleOnPoints
|
||||||
|
(
|
||||||
|
const interpolation<Type>& interpolator
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// One value per vertex
|
||||||
|
auto tvalues = tmp<Field<Type>>::New(points().size(), Zero);
|
||||||
|
auto& values = tvalues.ref();
|
||||||
|
|
||||||
|
const labelList& own = mesh().faceOwner();
|
||||||
|
|
||||||
|
bitSet pointDone(points().size());
|
||||||
|
|
||||||
|
forAll(faces(), i)
|
||||||
|
{
|
||||||
|
const face& f = faces()[i];
|
||||||
|
label facei = faceId_[i];
|
||||||
|
const label patchi = facePatchId_[i];
|
||||||
|
|
||||||
|
if (patchi != -1)
|
||||||
|
{
|
||||||
|
// Boundary face. patch-local face id -> mesh face id
|
||||||
|
const polyPatch& pp = mesh().boundaryMesh()[patchi];
|
||||||
|
|
||||||
|
facei += pp.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const label celli = own[facei];
|
||||||
|
|
||||||
|
for (const label pointi : f)
|
||||||
|
{
|
||||||
|
if (pointDone.set(pointi))
|
||||||
|
{
|
||||||
|
values[pointi] = interpolator.interpolate
|
||||||
|
(
|
||||||
|
points()[pointi],
|
||||||
|
celli,
|
||||||
|
facei
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tvalues;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -172,7 +172,7 @@ bool Foam::sampledMeshedSurface::update(const meshSearch& meshSearcher)
|
|||||||
|
|
||||||
List<nearInfo> nearest(fc.size(), nearInfo(GREAT, labelMax));
|
List<nearInfo> nearest(fc.size(), nearInfo(GREAT, labelMax));
|
||||||
|
|
||||||
if (sampleSource_ == cells)
|
if (sampleSource_ == samplingSource::cells)
|
||||||
{
|
{
|
||||||
// Search for nearest cell
|
// Search for nearest cell
|
||||||
|
|
||||||
@ -191,7 +191,7 @@ bool Foam::sampledMeshedSurface::update(const meshSearch& meshSearcher)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sampleSource_ == insideCells)
|
else if (sampleSource_ == samplingSource::insideCells)
|
||||||
{
|
{
|
||||||
// Search for cell containing point
|
// Search for cell containing point
|
||||||
|
|
||||||
@ -212,11 +212,11 @@ bool Foam::sampledMeshedSurface::update(const meshSearch& meshSearcher)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else // samplingSource::boundaryFaces
|
||||||
{
|
{
|
||||||
// Search for nearest boundaryFace
|
// Search for nearest boundary face
|
||||||
|
// on all non-coupled boundary faces
|
||||||
|
|
||||||
//- Search on all non-coupled boundary faces
|
|
||||||
const auto& bndTree = meshSearcher.nonCoupledBoundaryTree();
|
const auto& bndTree = meshSearcher.nonCoupledBoundaryTree();
|
||||||
|
|
||||||
forAll(fc, facei)
|
forAll(fc, facei)
|
||||||
@ -312,7 +312,7 @@ bool Foam::sampledMeshedSurface::update(const meshSearch& meshSearcher)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (sampleSource_ == cells)
|
if (sampleSource_ == samplingSource::cells)
|
||||||
{
|
{
|
||||||
// samplePoints_ : per surface point a location inside the cell
|
// samplePoints_ : per surface point a location inside the cell
|
||||||
// sampleElements_ : per surface point the cell
|
// sampleElements_ : per surface point the cell
|
||||||
@ -359,7 +359,7 @@ bool Foam::sampledMeshedSurface::update(const meshSearch& meshSearcher)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sampleSource_ == insideCells)
|
else if (sampleSource_ == samplingSource::insideCells)
|
||||||
{
|
{
|
||||||
// samplePoints_ : per surface point a location inside the cell
|
// samplePoints_ : per surface point a location inside the cell
|
||||||
// sampleElements_ : per surface point the cell
|
// sampleElements_ : per surface point the cell
|
||||||
@ -374,7 +374,7 @@ bool Foam::sampledMeshedSurface::update(const meshSearch& meshSearcher)
|
|||||||
samplePoints_[pointi] = pt;
|
samplePoints_[pointi] = pt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else // samplingSource::boundaryFaces
|
||||||
{
|
{
|
||||||
// samplePoints_ : per surface point a location on the boundary
|
// samplePoints_ : per surface point a location on the boundary
|
||||||
// sampleElements_ : per surface point the boundary face containing
|
// sampleElements_ : per surface point the boundary face containing
|
||||||
@ -406,6 +406,7 @@ bool Foam::sampledMeshedSurface::update(const meshSearch& meshSearcher)
|
|||||||
// else:
|
// else:
|
||||||
// sampleElements_ : per surface triangle the boundary face
|
// sampleElements_ : per surface triangle the boundary face
|
||||||
// samplePoints_ : n/a
|
// samplePoints_ : n/a
|
||||||
|
|
||||||
sampleElements_.transfer(cellOrFaceLabels);
|
sampleElements_.transfer(cellOrFaceLabels);
|
||||||
samplePoints_.clear();
|
samplePoints_.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,9 +35,9 @@ Description
|
|||||||
|
|
||||||
- 6 different modes:
|
- 6 different modes:
|
||||||
- source=cells, interpolate=false:
|
- source=cells, interpolate=false:
|
||||||
finds per triangle centre the nearest cell centre and uses its value
|
finds per triangle centre the \em nearest cell centre and uses its value
|
||||||
- source=cells, interpolate=true
|
- source=cells, interpolate=true:
|
||||||
finds per triangle centre the nearest cell centre.
|
finds per triangle centre the \em nearest cell centre.
|
||||||
Per surface point checks if this nearest cell is the one containing
|
Per surface point checks if this nearest cell is the one containing
|
||||||
point; otherwise projects the point onto the nearest point on
|
point; otherwise projects the point onto the nearest point on
|
||||||
the boundary of the cell (to make sure interpolateCellPoint
|
the boundary of the cell (to make sure interpolateCellPoint
|
||||||
@ -46,7 +46,7 @@ Description
|
|||||||
- source=insideCells, interpolate=false:
|
- source=insideCells, interpolate=false:
|
||||||
finds per triangle centre the cell containing it and uses its value.
|
finds per triangle centre the cell containing it and uses its value.
|
||||||
Trims triangles outside mesh.
|
Trims triangles outside mesh.
|
||||||
- source=insideCells, interpolate=true
|
- source=insideCells, interpolate=true:
|
||||||
Per surface point interpolate cell containing it.
|
Per surface point interpolate cell containing it.
|
||||||
|
|
||||||
- source=boundaryFaces, interpolate=false:
|
- source=boundaryFaces, interpolate=false:
|
||||||
@ -124,11 +124,11 @@ class sampledMeshedSurface
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//- Types of sampling regions
|
//- Types of sampling regions
|
||||||
enum samplingSource
|
enum class samplingSource
|
||||||
{
|
{
|
||||||
cells,
|
cells, //!< Use nearest cell value
|
||||||
insideCells,
|
insideCells, //!< Face within a cell
|
||||||
boundaryFaces
|
boundaryFaces //!< Use boundary face values
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -287,7 +287,7 @@ public:
|
|||||||
//- Sampling boundary values instead of cell values
|
//- Sampling boundary values instead of cell values
|
||||||
bool onBoundary() const
|
bool onBoundary() const
|
||||||
{
|
{
|
||||||
return sampleSource_ == boundaryFaces;
|
return sampleSource_ == samplingSource::boundaryFaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -16,8 +16,9 @@ runApplication subsetMesh c0 -patch walls -overwrite
|
|||||||
runApplication splitMeshRegions -cellZones -overwrite
|
runApplication splitMeshRegions -cellZones -overwrite
|
||||||
|
|
||||||
# create register face and cell zones
|
# create register face and cell zones
|
||||||
rm log.topoSet
|
rm -f log.topoSet.register
|
||||||
runApplication topoSet -region cabin -dict system/topoSetDictRegister
|
runApplication -s register \
|
||||||
|
topoSet -region cabin -dict system/topoSetDictRegister
|
||||||
|
|
||||||
# set the initial fields
|
# set the initial fields
|
||||||
restore0Dir
|
restore0Dir
|
||||||
|
|||||||
@ -16,8 +16,9 @@ runApplication subsetMesh c0 -patch walls -overwrite
|
|||||||
runApplication splitMeshRegions -cellZones -overwrite
|
runApplication splitMeshRegions -cellZones -overwrite
|
||||||
|
|
||||||
# create register face and cell zones
|
# create register face and cell zones
|
||||||
rm log.topoSet
|
rm -f log.topoSet.register
|
||||||
runApplication topoSet -region cabin -dict system/topoSetDictRegister
|
runApplication -o -s register \
|
||||||
|
topoSet -region cabin -dict system/topoSetDictRegister
|
||||||
|
|
||||||
# set the initial fields
|
# set the initial fields
|
||||||
restore0Dir
|
restore0Dir
|
||||||
|
|||||||
@ -83,6 +83,27 @@ functions
|
|||||||
( 60 "<system>/solverControls.60")
|
( 60 "<system>/solverControls.60")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify values for sampling multiple faceZones
|
||||||
|
inletFaces
|
||||||
|
{
|
||||||
|
type surfaces;
|
||||||
|
libs (sampling);
|
||||||
|
writeControl onEnd;
|
||||||
|
region cabin;
|
||||||
|
surfaceFormat vtk;
|
||||||
|
fields (H2O U);
|
||||||
|
|
||||||
|
surfaces
|
||||||
|
{
|
||||||
|
inletFaces
|
||||||
|
{
|
||||||
|
type faceZone;
|
||||||
|
zones (inletFaces f1Zone);
|
||||||
|
interpolate false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -44,6 +44,28 @@ actions
|
|||||||
type cellSet;
|
type cellSet;
|
||||||
action invert;
|
action invert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
name f0tmp;
|
||||||
|
type faceSet;
|
||||||
|
action new;
|
||||||
|
source patchToFace;
|
||||||
|
patch inlet;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
name inletFaces;
|
||||||
|
type faceZoneSet;
|
||||||
|
action new;
|
||||||
|
source setToFaceZone;
|
||||||
|
faceSet f0tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
name f0tmp;
|
||||||
|
type faceSet;
|
||||||
|
action remove;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user