Commit 6b8f56ef authored by Mark OLESEN's avatar Mark OLESEN
Browse files

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
parent 89438778
......@@ -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
(
const surfaceScalarField& sField
......
......@@ -272,6 +272,10 @@ public:
) const;
//- Can it sample surface-fields?
virtual bool withSurfaceFields() const;
//- Sample boundary of surface field on surface
virtual tmp<scalarField> sample
(
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2018-2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -82,6 +82,7 @@ Foam::sampledSurface::sampledSurface(const word& name, std::nullptr_t)
:
name_(name),
mesh_(NullObjectRef<polyMesh>()),
enabled_(true),
interpolate_(false),
area_(-1)
{}
......@@ -96,6 +97,7 @@ Foam::sampledSurface::sampledSurface
:
name_(name),
mesh_(mesh),
enabled_(true),
interpolate_(interpolate),
area_(-1)
{}
......@@ -108,13 +110,12 @@ Foam::sampledSurface::sampledSurface
const dictionary& dict
)
:
name_(name),
name_(dict.lookupOrDefault<word>("name", name)),
mesh_(mesh),
enabled_(dict.lookupOrDefault("enabled", true)),
interpolate_(dict.lookupOrDefault("interpolate", false)),
area_(-1)
{
dict.readIfPresent("name", name_);
}
{}
// * * * * * * * * * * * * * * * * 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
(
const surfaceScalarField& sField
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / 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
This file is part of OpenFOAM.
......@@ -43,6 +43,17 @@ Description
implementation should do nothing when the surface is already
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
sampledSurface.C
sampledSurfaceTemplates.C
......@@ -80,7 +91,7 @@ class sampledSurface
{
private:
// Private data
// Private Data
//- Name of sample surface
word name_;
......@@ -88,14 +99,16 @@ private:
//- Reference to mesh
const polyMesh& mesh_;
//- Should surface sampling be enabled?
bool enabled_;
//- Do we intend to interpolate the information?
const bool interpolate_;
//- Total surface area (demand-driven)
mutable scalar area_;
// Demand-driven data
//- Total surface area
mutable scalar area_;
protected:
......@@ -121,17 +134,18 @@ protected:
);
//- Additional cleanup when clearing the geometry
virtual void clearGeom() const;
//- Construct null
explicit sampledSurface(const word& name, std::nullptr_t);
public:
//- Runtime type information
TypeName("sampledSurface");
//- Declare run-time constructor selection table
declareRunTimeSelectionTable
(
......@@ -149,7 +163,7 @@ public:
// iNew helper class
//- Class used for the PtrLists read-construction
//- Class for PtrList read-construction
class iNew
{
//- Reference to the volume mesh
......@@ -209,7 +223,7 @@ public:
);
//- Destructor
//- Destructor - calls clearGeom()
virtual ~sampledSurface();
......@@ -229,6 +243,12 @@ public:
return name_;
}
//- Sampling is enabled
bool enabled() const
{
return enabled_;
}
//- Interpolation requested for surface
bool interpolate() const
{
......@@ -312,6 +332,10 @@ public:
) const = 0;
//- Can it sample surface-fields?
virtual bool withSurfaceFields() const;
//- Sample surface field onto surface
virtual tmp<scalarField> sample
(
......
......@@ -226,58 +226,120 @@ bool Foam::sampledSurfaces::write()
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());
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());
dict.readEntry("interpolationScheme", sampleNodeScheme_);
surfaces().transfer(surfs);
}
const auto& surfs = surfaces();
if (surfs.size())
{
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
// Optionally defined extra controls for the output formats
formatter_ = surfaceWriter::New
(
writeType,
dict.subOrEmptyDict("formatOptions").subOrEmptyDict(writeType)
writerType,
dict.subOrEmptyDict("formatOptions").subOrEmptyDict(writerType)
);
PtrList<sampledSurface> newList
(
dict.lookup("surfaces"),
sampledSurface::iNew(mesh_)
);
transfer(newList);
if (Pstream::parRun())
{
mergedList_.setSize(size());
mergedList_.resize(size());
}
// Ensure all surfaces and merge information are expired
expire();
if (this->size())
label surfi = 0;
for (const sampledSurface& s : surfs)
{
Info<< "Reading surface description:" << nl;
forAll(*this, surfi)
if (!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
<< "sample surfaces:" << nl << "(" << nl;
forAll(*this, surfi)
for (const sampledSurface& s : surfaces())
{
Pout<< " " << operator[](surfi) << nl;
Pout<< " " << s << nl;
}
Pout<< ")" << endl;
}
......
......@@ -81,14 +81,14 @@ Description
Entries:
\table
Property | Description | Required | Default
type | surfaces | yes |
surfaces | the list of sample surfaces | recommended |
fields | word/regex list of fields to sampled | yes |
sampleScheme | scheme to obtain face centre value | no | cell
interpolationScheme | scheme to obtain node values | yes |
surfaceFormat | output surface format | yes |
formatOptions | dictionary of format options | no |
Property | Description | Required | Default
type | surfaces | yes |
surfaces | list or dictionary of sample surfaces | recommended |
fields | word/regex list of fields to sampled | yes |
sampleScheme | scheme to obtain face centre value | no | cell
interpolationScheme | scheme to obtain node values | no | cellPoint
surfaceFormat | output surface format | yes |
formatOptions | dictionary of format options | no |
\endtable
Note
......
......@@ -132,7 +132,10 @@ void Foam::sampledSurfaces::sampleAndWrite
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;
const word& fieldName = vField.name();
......@@ -159,16 +162,16 @@ void Foam::sampledSurfaces::sampleAndWrite
}
else
{
if (interpPtr.empty())
if (samplePtr.empty())
{
interpPtr = interpolation<Type>::New
samplePtr = interpolation<Type>::New
(
sampleFaceScheme_,
vField
);
}
values = s.sample(*interpPtr);
values = s.sample(*samplePtr);
}
writeSurface<Type>(values, surfi, fieldName, outputDir);
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -101,7 +101,8 @@ Foam::surfMeshSample::surfMeshSample
)
:
name_(name),
mesh_(mesh)
mesh_(mesh),
enabled_(true)
{}
......@@ -112,11 +113,10 @@ Foam::surfMeshSample::surfMeshSample
const dictionary& dict
)
:
name_(name),
mesh_(mesh)
{
dict.readIfPresent("name", name_);
}
name_(dict.lookupOrDefault<word>("name", name)),
mesh_(mesh),
enabled_(dict.lookupOrDefault("enabled", true))
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -30,6 +30,12 @@ Group
Description
An abstract class for surfMesh with sampling.
Dictionary entries:
\table
Property | Description | Required | Default
enabled | Enable/disable the surface? | no | yes
\endtable
SourceFiles
surfMeshSample.C
surfMeshSampleTemplates.C
......@@ -69,7 +75,7 @@ class surfMeshSample;
class surfMeshSample
{
// Private data
// Private Data
//- Name for surfMesh lookup
word name_;
......@@ -77,6 +83,9 @@ class surfMeshSample
//- Mesh reference
const polyMesh& mesh_;
//- Should surface sampling be enabled?
bool enabled_;
protected:
......@@ -142,7 +151,7 @@ public:
// iNew helper class
//- Class used for the PtrLists read-construction
//- Class for PtrList read-construction
class iNew
{
//- Reference to the volume mesh
......@@ -223,6 +232,11 @@ public:
return name_;
}
//- Sampling is enabled
bool enabled() const
{
return enabled_;
}
//- Create surfMesh if required.
void create() const;
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -197,7 +197,7 @@ Foam::surfMeshSamplers::surfMeshSamplers
mesh_(refCast<const fvMesh>(obr_)),
fieldSelection_(),
derivedNames_(),
sampleScheme_(word::null),
sampleFaceScheme_(),
rhoRef_(1.0)
{
read(dict);
......@@ -216,7 +216,7 @@ Foam::surfMeshSamplers::surfMeshSamplers
mesh_(refCast<const fvMesh>(obr)),
fieldSelection_(),
derivedNames_(),
sampleScheme_(word::null),
sampleFaceScheme_(),
rhoRef_(1.0)
{
read(dict);
......@@ -293,7 +293,7 @@ bool Foam::surfMeshSamplers::execute()
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)
{
PtrList<surfMeshSample>::clear();
fieldSelection_.clear();
derivedNames_.clear();
......@@ -344,10 +345,64 @@ bool Foam::surfMeshSamplers::read(const dictionary& dict)
const bool createOnRead = dict.lookupOrDefault("createOnRead", false);
if (dict.found("surfaces"))
sampleFaceScheme_ =
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)
{
sampleScheme_ = dict.lookupOrDefault<word>("sampleScheme", "cell");
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_);
fieldSelection_.uniq();
......@@ -359,36 +414,35 @@ bool Foam::surfMeshSamplers::read(const dictionary& dict)
}
Info<< nl;
PtrList<surfMeshSample> newList
(
dict.lookup("surfaces"),
surfMeshSample::iNew(mesh_)
);
transfer(newList);
// Ensure all surfaces and merge information are expired
expire();