ENH: support dictionary or list entry for sampled surfaces

- support for optional 'enabled' keyword to selectively disable a
  single sampled surface.

ENH: add sampledSurface::withSurfaceFields() method

- can be used to distinguish which samplers support surface fields.
  Currently this is only sampledPatch
This commit is contained in:
Mark Olesen
2019-01-22 07:59:57 +01:00
parent 89438778aa
commit 6b8f56efea
11 changed files with 269 additions and 95 deletions

View File

@ -265,6 +265,12 @@ Foam::tmp<Foam::tensorField> Foam::sampledPatch::sample
} }
bool Foam::sampledPatch::withSurfaceFields() const
{
return true;
}
Foam::tmp<Foam::scalarField> Foam::sampledPatch::sample Foam::tmp<Foam::scalarField> Foam::sampledPatch::sample
( (
const surfaceScalarField& sField const surfaceScalarField& sField

View File

@ -272,6 +272,10 @@ public:
) const; ) const;
//- Can it sample surface-fields?
virtual bool withSurfaceFields() const;
//- Sample boundary of surface field on surface //- Sample boundary of surface field on surface
virtual tmp<scalarField> sample virtual tmp<scalarField> sample
( (

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2018-2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -82,6 +82,7 @@ Foam::sampledSurface::sampledSurface(const word& name, std::nullptr_t)
: :
name_(name), name_(name),
mesh_(NullObjectRef<polyMesh>()), mesh_(NullObjectRef<polyMesh>()),
enabled_(true),
interpolate_(false), interpolate_(false),
area_(-1) area_(-1)
{} {}
@ -96,6 +97,7 @@ Foam::sampledSurface::sampledSurface
: :
name_(name), name_(name),
mesh_(mesh), mesh_(mesh),
enabled_(true),
interpolate_(interpolate), interpolate_(interpolate),
area_(-1) area_(-1)
{} {}
@ -108,13 +110,12 @@ Foam::sampledSurface::sampledSurface
const dictionary& dict const dictionary& dict
) )
: :
name_(name), name_(dict.lookupOrDefault<word>("name", name)),
mesh_(mesh), mesh_(mesh),
enabled_(dict.lookupOrDefault("enabled", true)),
interpolate_(dict.lookupOrDefault("interpolate", false)), interpolate_(dict.lookupOrDefault("interpolate", false)),
area_(-1) area_(-1)
{ {}
dict.readIfPresent("name", name_);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
@ -138,6 +139,12 @@ Foam::scalar Foam::sampledSurface::area() const
} }
bool Foam::sampledSurface::withSurfaceFields() const
{
return false;
}
Foam::tmp<Foam::scalarField> Foam::sampledSurface::sample Foam::tmp<Foam::scalarField> Foam::sampledSurface::sample
( (
const surfaceScalarField& sField const surfaceScalarField& sField

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2016-2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -43,6 +43,17 @@ Description
implementation should do nothing when the surface is already implementation should do nothing when the surface is already
up-to-date. up-to-date.
Any sampler is assumed to work for the standard volume field types.
Some may also support surface fields.
Dictionary entries:
\table
Property | Description | Required | Default
name | Alternative name | no |
enabled | Enable/disable the surface? | no | yes
interpolate | Sample to nodes instead of faces | no | false
\endtable
SourceFiles SourceFiles
sampledSurface.C sampledSurface.C
sampledSurfaceTemplates.C sampledSurfaceTemplates.C
@ -80,7 +91,7 @@ class sampledSurface
{ {
private: private:
// Private data // Private Data
//- Name of sample surface //- Name of sample surface
word name_; word name_;
@ -88,16 +99,18 @@ private:
//- Reference to mesh //- Reference to mesh
const polyMesh& mesh_; const polyMesh& mesh_;
//- Should surface sampling be enabled?
bool enabled_;
//- Do we intend to interpolate the information? //- Do we intend to interpolate the information?
const bool interpolate_; const bool interpolate_;
//- Total surface area (demand-driven)
// Demand-driven data
//- Total surface area
mutable scalar area_; mutable scalar area_;
protected: protected:
// Protected Member Functions // Protected Member Functions
@ -121,17 +134,18 @@ protected:
); );
//- Additional cleanup when clearing the geometry
virtual void clearGeom() const; virtual void clearGeom() const;
//- Construct null //- Construct null
explicit sampledSurface(const word& name, std::nullptr_t); explicit sampledSurface(const word& name, std::nullptr_t);
public: public:
//- Runtime type information //- Runtime type information
TypeName("sampledSurface"); TypeName("sampledSurface");
//- Declare run-time constructor selection table //- Declare run-time constructor selection table
declareRunTimeSelectionTable declareRunTimeSelectionTable
( (
@ -149,7 +163,7 @@ public:
// iNew helper class // iNew helper class
//- Class used for the PtrLists read-construction //- Class for PtrList read-construction
class iNew class iNew
{ {
//- Reference to the volume mesh //- Reference to the volume mesh
@ -209,7 +223,7 @@ public:
); );
//- Destructor //- Destructor - calls clearGeom()
virtual ~sampledSurface(); virtual ~sampledSurface();
@ -229,6 +243,12 @@ public:
return name_; return name_;
} }
//- Sampling is enabled
bool enabled() const
{
return enabled_;
}
//- Interpolation requested for surface //- Interpolation requested for surface
bool interpolate() const bool interpolate() const
{ {
@ -312,6 +332,10 @@ public:
) const = 0; ) const = 0;
//- Can it sample surface-fields?
virtual bool withSurfaceFields() const;
//- Sample surface field onto surface //- Sample surface field onto surface
virtual tmp<scalarField> sample virtual tmp<scalarField> sample
( (

View File

@ -226,58 +226,120 @@ bool Foam::sampledSurfaces::write()
bool Foam::sampledSurfaces::read(const dictionary& dict) bool Foam::sampledSurfaces::read(const dictionary& dict)
{ {
if (dict.found("surfaces")) PtrList<sampledSurface>::clear();
mergedList_.clear();
changedGeom_.clear();
fieldSelection_.clear();
sampleFaceScheme_ =
dict.lookupOrDefault<word>("sampleScheme", "cell");
sampleNodeScheme_ =
dict.lookupOrDefault<word>("interpolationScheme", "cellPoint");
const entry* eptr = dict.findEntry("surfaces");
if (eptr && eptr->isDict())
{ {
sampleFaceScheme_ = dict.lookupOrDefault<word>("sampleScheme", "cell"); PtrList<sampledSurface> surfs(eptr->dict().size());
dict.readEntry("interpolationScheme", sampleNodeScheme_); label surfi = 0;
for (const entry& dEntry : eptr->dict())
{
if (dEntry.isDict())
{
autoPtr<sampledSurface> surf =
sampledSurface::New
(
dEntry.keyword(),
mesh_,
dEntry.dict()
);
if (surf.valid() && surf->enabled())
{
surfs.set(surfi, surf);
++surfi;
}
}
}
surfs.resize(surfi);
surfaces().transfer(surfs);
}
else if (eptr)
{
PtrList<sampledSurface> surfs
(
eptr->stream(),
sampledSurface::iNew(mesh_)
);
forAll(surfs, surfi)
{
if (!surfs[surfi].enabled())
{
surfs.set(surfi, nullptr);
}
}
surfs.resize(surfs.squeezeNull());
surfaces().transfer(surfs);
}
const auto& surfs = surfaces();
if (surfs.size())
{
dict.readEntry("fields", fieldSelection_); dict.readEntry("fields", fieldSelection_);
fieldSelection_.uniq();
const word writeType(dict.get<word>("surfaceFormat")); // The surface writer and format options
const word writerType(dict.get<word>("surfaceFormat"));
const dictionary& formatOptions = dict.subOrEmptyDict("formatOptions");
// Define the surface formatter // Define the surface formatter
// Optionally defined extra controls for the output formats // Optionally defined extra controls for the output formats
formatter_ = surfaceWriter::New formatter_ = surfaceWriter::New
( (
writeType, writerType,
dict.subOrEmptyDict("formatOptions").subOrEmptyDict(writeType) dict.subOrEmptyDict("formatOptions").subOrEmptyDict(writerType)
); );
PtrList<sampledSurface> newList
(
dict.lookup("surfaces"),
sampledSurface::iNew(mesh_)
);
transfer(newList);
if (Pstream::parRun()) if (Pstream::parRun())
{ {
mergedList_.setSize(size()); mergedList_.resize(size());
} }
// Ensure all surfaces and merge information are expired // Ensure all surfaces and merge information are expired
expire(); expire();
if (this->size()) label surfi = 0;
for (const sampledSurface& s : surfs)
{ {
Info<< "Reading surface description:" << nl; if (!surfi)
forAll(*this, surfi)
{ {
Info<< " " << operator[](surfi).name() << nl; Info<< "Sampled surface:" << nl;
} }
Info<< endl; Info<< " " << s.name() << " -> " << writerType << nl;
++surfi;
} }
Info<< nl;
} }
if (Pstream::master() && debug) if (debug && Pstream::master())
{ {
Pout<< "sample fields:" << fieldSelection_ << nl Pout<< "sample fields:" << fieldSelection_ << nl
<< "sample surfaces:" << nl << "(" << nl; << "sample surfaces:" << nl << "(" << nl;
forAll(*this, surfi) for (const sampledSurface& s : surfaces())
{ {
Pout<< " " << operator[](surfi) << nl; Pout<< " " << s << nl;
} }
Pout<< ")" << endl; Pout<< ")" << endl;
} }

View File

@ -83,10 +83,10 @@ Description
\table \table
Property | Description | Required | Default Property | Description | Required | Default
type | surfaces | yes | type | surfaces | yes |
surfaces | the list of sample surfaces | recommended | surfaces | list or dictionary of sample surfaces | recommended |
fields | word/regex list of fields to sampled | yes | fields | word/regex list of fields to sampled | yes |
sampleScheme | scheme to obtain face centre value | no | cell sampleScheme | scheme to obtain face centre value | no | cell
interpolationScheme | scheme to obtain node values | yes | interpolationScheme | scheme to obtain node values | no | cellPoint
surfaceFormat | output surface format | yes | surfaceFormat | output surface format | yes |
formatOptions | dictionary of format options | no | formatOptions | dictionary of format options | no |
\endtable \endtable

View File

@ -132,7 +132,10 @@ void Foam::sampledSurfaces::sampleAndWrite
const GeometricField<Type, fvPatchField, volMesh>& vField const GeometricField<Type, fvPatchField, volMesh>& vField
) )
{ {
// sampler/interpolator for this field // The sampler for this field
autoPtr<interpolation<Type>> samplePtr;
// The interpolator for this field
autoPtr<interpolation<Type>> interpPtr; autoPtr<interpolation<Type>> interpPtr;
const word& fieldName = vField.name(); const word& fieldName = vField.name();
@ -159,16 +162,16 @@ void Foam::sampledSurfaces::sampleAndWrite
} }
else else
{ {
if (interpPtr.empty()) if (samplePtr.empty())
{ {
interpPtr = interpolation<Type>::New samplePtr = interpolation<Type>::New
( (
sampleFaceScheme_, sampleFaceScheme_,
vField vField
); );
} }
values = s.sample(*interpPtr); values = s.sample(*samplePtr);
} }
writeSurface<Type>(values, surfi, fieldName, outputDir); writeSurface<Type>(values, surfi, fieldName, outputDir);

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -101,7 +101,8 @@ Foam::surfMeshSample::surfMeshSample
) )
: :
name_(name), name_(name),
mesh_(mesh) mesh_(mesh),
enabled_(true)
{} {}
@ -112,11 +113,10 @@ Foam::surfMeshSample::surfMeshSample
const dictionary& dict const dictionary& dict
) )
: :
name_(name), name_(dict.lookupOrDefault<word>("name", name)),
mesh_(mesh) mesh_(mesh),
{ enabled_(dict.lookupOrDefault("enabled", true))
dict.readIfPresent("name", name_); {}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -30,6 +30,12 @@ Group
Description Description
An abstract class for surfMesh with sampling. An abstract class for surfMesh with sampling.
Dictionary entries:
\table
Property | Description | Required | Default
enabled | Enable/disable the surface? | no | yes
\endtable
SourceFiles SourceFiles
surfMeshSample.C surfMeshSample.C
surfMeshSampleTemplates.C surfMeshSampleTemplates.C
@ -69,7 +75,7 @@ class surfMeshSample;
class surfMeshSample class surfMeshSample
{ {
// Private data // Private Data
//- Name for surfMesh lookup //- Name for surfMesh lookup
word name_; word name_;
@ -77,6 +83,9 @@ class surfMeshSample
//- Mesh reference //- Mesh reference
const polyMesh& mesh_; const polyMesh& mesh_;
//- Should surface sampling be enabled?
bool enabled_;
protected: protected:
@ -142,7 +151,7 @@ public:
// iNew helper class // iNew helper class
//- Class used for the PtrLists read-construction //- Class for PtrList read-construction
class iNew class iNew
{ {
//- Reference to the volume mesh //- Reference to the volume mesh
@ -223,6 +232,11 @@ public:
return name_; return name_;
} }
//- Sampling is enabled
bool enabled() const
{
return enabled_;
}
//- Create surfMesh if required. //- Create surfMesh if required.
void create() const; void create() const;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -197,7 +197,7 @@ Foam::surfMeshSamplers::surfMeshSamplers
mesh_(refCast<const fvMesh>(obr_)), mesh_(refCast<const fvMesh>(obr_)),
fieldSelection_(), fieldSelection_(),
derivedNames_(), derivedNames_(),
sampleScheme_(word::null), sampleFaceScheme_(),
rhoRef_(1.0) rhoRef_(1.0)
{ {
read(dict); read(dict);
@ -216,7 +216,7 @@ Foam::surfMeshSamplers::surfMeshSamplers
mesh_(refCast<const fvMesh>(obr)), mesh_(refCast<const fvMesh>(obr)),
fieldSelection_(), fieldSelection_(),
derivedNames_(), derivedNames_(),
sampleScheme_(word::null), sampleFaceScheme_(),
rhoRef_(1.0) rhoRef_(1.0)
{ {
read(dict); read(dict);
@ -293,7 +293,7 @@ bool Foam::surfMeshSamplers::execute()
s.update(); s.update();
} }
s.sample(fields, sampleScheme_); s.sample(fields, sampleFaceScheme_);
} }
} }
@ -337,6 +337,7 @@ bool Foam::surfMeshSamplers::write()
bool Foam::surfMeshSamplers::read(const dictionary& dict) bool Foam::surfMeshSamplers::read(const dictionary& dict)
{ {
PtrList<surfMeshSample>::clear();
fieldSelection_.clear(); fieldSelection_.clear();
derivedNames_.clear(); derivedNames_.clear();
@ -344,10 +345,64 @@ bool Foam::surfMeshSamplers::read(const dictionary& dict)
const bool createOnRead = dict.lookupOrDefault("createOnRead", false); const bool createOnRead = dict.lookupOrDefault("createOnRead", false);
if (dict.found("surfaces")) sampleFaceScheme_ =
{ dict.lookupOrDefault<word>("sampleScheme", "cell");
sampleScheme_ = dict.lookupOrDefault<word>("sampleScheme", "cell");
const entry* eptr = dict.findEntry("surfaces");
if (eptr && eptr->isDict())
{
PtrList<surfMeshSample> surfs(eptr->dict().size());
label surfi = 0;
for (const entry& dEntry : eptr->dict())
{
if (dEntry.isDict())
{
autoPtr<surfMeshSample> surf =
surfMeshSample::New
(
dEntry.keyword(),
mesh_,
dEntry.dict()
);
if (surf.valid() && surf->enabled())
{
surfs.set(surfi, surf);
++surfi;
}
}
}
surfs.resize(surfi);
surfaces().transfer(surfs);
}
else if (eptr)
{
PtrList<surfMeshSample> surfs
(
eptr->stream(),
surfMeshSample::iNew(mesh_)
);
forAll(surfs, surfi)
{
if (!surfs[surfi].enabled())
{
surfs.set(surfi, nullptr);
}
}
surfs.resize(surfs.squeezeNull());
surfaces().transfer(surfs);
}
auto& surfs = surfaces();
if (surfs.size())
{
dict.readEntry("fields", fieldSelection_); dict.readEntry("fields", fieldSelection_);
fieldSelection_.uniq(); fieldSelection_.uniq();
@ -359,25 +414,22 @@ bool Foam::surfMeshSamplers::read(const dictionary& dict)
} }
Info<< nl; Info<< nl;
PtrList<surfMeshSample> newList
(
dict.lookup("surfaces"),
surfMeshSample::iNew(mesh_)
);
transfer(newList);
// Ensure all surfaces and merge information are expired // Ensure all surfaces and merge information are expired
expire(); expire();
// Need to initialize corresponding surfMesh for others in the chain. // Need to initialize corresponding surfMesh for others in the chain.
// This can simply be a zero-sized placeholder, or the real surface with // This can simply be a zero-sized placeholder, or the real surface with
// faces. // faces.
if (this->size())
label surfi = 0;
for (surfMeshSample& s : surfs)
{ {
Info<< "Reading surface description:" << nl; if (!surfi)
for (surfMeshSample& s : surfaces())
{ {
Info<< "Sampled surface:" << nl;
}
Info<< " " << s.name() << nl; Info<< " " << s.name() << nl;
if (createOnRead) if (createOnRead)
{ {
s.update(); s.update();
@ -386,9 +438,11 @@ bool Foam::surfMeshSamplers::read(const dictionary& dict)
{ {
s.create(); s.create();
} }
++surfi;
} }
Info<< endl;
} Info<< nl;
} }
return true; return true;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -77,12 +77,12 @@ Description
\table \table
Property | Description | Required | Default Property | Description | Required | Default
type | surfMeshes | yes | type | surfMeshes | yes |
surfaces | the list of sample surfaces | recommended | surfaces | list or dictionary of sample surfaces | recommended |
fields | word/regex list of fields to sampled | yes | fields | word/regex list of fields to sampled | yes |
derived | additional derived fields pTotal/rhoU | no | derived | additional derived fields pTotal/rhoU | no |
rhoRef | reference density for derived fields (incompressible) | no | 1 rhoRef | reference density for derived fields (incompressible) | no | 1
sampleScheme | scheme to obtain face centre value | no | cell sampleScheme | scheme to obtain face centre value | no | cell
createOnRead | Create surface immediately on read | no | false; createOnRead | Create surface immediately on read | no | false
\endtable \endtable
Note Note
@ -130,7 +130,7 @@ class surfMeshSamplers
{ {
// Static data members // Static data members
//- output verbosity //- Output verbosity
static bool verbose_; static bool verbose_;
@ -149,7 +149,7 @@ class surfMeshSamplers
wordList derivedNames_; wordList derivedNames_;
//- Sample scheme to obtain face values //- Sample scheme to obtain face values
word sampleScheme_; word sampleFaceScheme_;
//- Reference density (to convert from kinematic to static pressure) //- Reference density (to convert from kinematic to static pressure)
scalar rhoRef_; scalar rhoRef_;