diff --git a/src/sampling/sampledSurface/sampledPatch/sampledPatch.C b/src/sampling/sampledSurface/sampledPatch/sampledPatch.C index 4b3b27a024..1718cd314f 100644 --- a/src/sampling/sampledSurface/sampledPatch/sampledPatch.C +++ b/src/sampling/sampledSurface/sampledPatch/sampledPatch.C @@ -265,6 +265,12 @@ Foam::tmp Foam::sampledPatch::sample } +bool Foam::sampledPatch::withSurfaceFields() const +{ + return true; +} + + Foam::tmp Foam::sampledPatch::sample ( const surfaceScalarField& sField diff --git a/src/sampling/sampledSurface/sampledPatch/sampledPatch.H b/src/sampling/sampledSurface/sampledPatch/sampledPatch.H index 91385e7bca..917e039663 100644 --- a/src/sampling/sampledSurface/sampledPatch/sampledPatch.H +++ b/src/sampling/sampledSurface/sampledPatch/sampledPatch.H @@ -272,6 +272,10 @@ public: ) const; + //- Can it sample surface-fields? + virtual bool withSurfaceFields() const; + + //- Sample boundary of surface field on surface virtual tmp sample ( diff --git a/src/sampling/sampledSurface/sampledSurface/sampledSurface.C b/src/sampling/sampledSurface/sampledSurface/sampledSurface.C index e5eafd25ae..a128fc298a 100644 --- a/src/sampling/sampledSurface/sampledSurface/sampledSurface.C +++ b/src/sampling/sampledSurface/sampledSurface/sampledSurface.C @@ -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()), + 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("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::sampledSurface::sample ( const surfaceScalarField& sField diff --git a/src/sampling/sampledSurface/sampledSurface/sampledSurface.H b/src/sampling/sampledSurface/sampledSurface/sampledSurface.H index 7a56559ab5..418eafd702 100644 --- a/src/sampling/sampledSurface/sampledSurface/sampledSurface.H +++ b/src/sampling/sampledSurface/sampledSurface/sampledSurface.H @@ -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,16 +99,18 @@ private: //- Reference to mesh const polyMesh& mesh_; + //- Should surface sampling be enabled? + bool enabled_; + //- Do we intend to interpolate the information? const bool interpolate_; - - // Demand-driven data - - //- Total surface area + //- Total surface area (demand-driven) mutable scalar area_; + + protected: // Protected Member Functions @@ -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 sample ( diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C index 12dc6058d8..f36c7b05b4 100644 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C +++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C @@ -226,58 +226,120 @@ bool Foam::sampledSurfaces::write() bool Foam::sampledSurfaces::read(const dictionary& dict) { - if (dict.found("surfaces")) + PtrList::clear(); + mergedList_.clear(); + changedGeom_.clear(); + fieldSelection_.clear(); + + sampleFaceScheme_ = + dict.lookupOrDefault("sampleScheme", "cell"); + + sampleNodeScheme_ = + dict.lookupOrDefault("interpolationScheme", "cellPoint"); + + const entry* eptr = dict.findEntry("surfaces"); + + if (eptr && eptr->isDict()) { - sampleFaceScheme_ = dict.lookupOrDefault("sampleScheme", "cell"); + PtrList surfs(eptr->dict().size()); - dict.readEntry("interpolationScheme", sampleNodeScheme_); + label surfi = 0; + + for (const entry& dEntry : eptr->dict()) + { + if (dEntry.isDict()) + { + autoPtr 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 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_); + fieldSelection_.uniq(); - const word writeType(dict.get("surfaceFormat")); + // The surface writer and format options + const word writerType(dict.get("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 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; } diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H index 401d0eddd8..eda1851914 100644 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H +++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H @@ -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 diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C index 71afcb9f78..a64ffb536d 100644 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C +++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C @@ -132,7 +132,10 @@ void Foam::sampledSurfaces::sampleAndWrite const GeometricField& vField ) { - // sampler/interpolator for this field + // The sampler for this field + autoPtr> samplePtr; + + // The interpolator for this field autoPtr> interpPtr; const word& fieldName = vField.name(); @@ -159,16 +162,16 @@ void Foam::sampledSurfaces::sampleAndWrite } else { - if (interpPtr.empty()) + if (samplePtr.empty()) { - interpPtr = interpolation::New + samplePtr = interpolation::New ( sampleFaceScheme_, vField ); } - values = s.sample(*interpPtr); + values = s.sample(*samplePtr); } writeSurface(values, surfi, fieldName, outputDir); diff --git a/src/sampling/surfMeshSample/surfMeshSample/surfMeshSample.C b/src/sampling/surfMeshSample/surfMeshSample/surfMeshSample.C index 616de169fe..8ed1f3229e 100644 --- a/src/sampling/surfMeshSample/surfMeshSample/surfMeshSample.C +++ b/src/sampling/surfMeshSample/surfMeshSample/surfMeshSample.C @@ -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("name", name)), + mesh_(mesh), + enabled_(dict.lookupOrDefault("enabled", true)) +{} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // diff --git a/src/sampling/surfMeshSample/surfMeshSample/surfMeshSample.H b/src/sampling/surfMeshSample/surfMeshSample/surfMeshSample.H index 72c2c1b4a7..c7ed6707b5 100644 --- a/src/sampling/surfMeshSample/surfMeshSample/surfMeshSample.H +++ b/src/sampling/surfMeshSample/surfMeshSample/surfMeshSample.H @@ -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; diff --git a/src/sampling/surfMeshSample/surfMeshSamplers/surfMeshSamplers.C b/src/sampling/surfMeshSample/surfMeshSamplers/surfMeshSamplers.C index f51801ae77..5cf3391d5d 100644 --- a/src/sampling/surfMeshSample/surfMeshSamplers/surfMeshSamplers.C +++ b/src/sampling/surfMeshSample/surfMeshSamplers/surfMeshSamplers.C @@ -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(obr_)), fieldSelection_(), derivedNames_(), - sampleScheme_(word::null), + sampleFaceScheme_(), rhoRef_(1.0) { read(dict); @@ -216,7 +216,7 @@ Foam::surfMeshSamplers::surfMeshSamplers mesh_(refCast(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::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")) - { - sampleScheme_ = dict.lookupOrDefault("sampleScheme", "cell"); + sampleFaceScheme_ = + dict.lookupOrDefault("sampleScheme", "cell"); + const entry* eptr = dict.findEntry("surfaces"); + + if (eptr && eptr->isDict()) + { + PtrList surfs(eptr->dict().size()); + + label surfi = 0; + + for (const entry& dEntry : eptr->dict()) + { + if (dEntry.isDict()) + { + autoPtr 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 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 newList - ( - dict.lookup("surfaces"), - surfMeshSample::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()) + + label surfi = 0; + for (surfMeshSample& s : surfs) { - Info<< "Reading surface description:" << nl; - for (surfMeshSample& s : surfaces()) + if (!surfi) { - Info<< " " << s.name() << nl; - if (createOnRead) - { - s.update(); - } - else - { - s.create(); - } + Info<< "Sampled surface:" << nl; } - Info<< endl; + Info<< " " << s.name() << nl; + + if (createOnRead) + { + s.update(); + } + else + { + s.create(); + } + + ++surfi; } + + Info<< nl; } return true; diff --git a/src/sampling/surfMeshSample/surfMeshSamplers/surfMeshSamplers.H b/src/sampling/surfMeshSample/surfMeshSamplers/surfMeshSamplers.H index f97feb88cd..19cd1bb8fa 100644 --- a/src/sampling/surfMeshSample/surfMeshSamplers/surfMeshSamplers.H +++ b/src/sampling/surfMeshSample/surfMeshSamplers/surfMeshSamplers.H @@ -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 @@ -75,14 +75,14 @@ Description Entries: \table - Property | Description | Required | Default - type | surfMeshes | yes | - surfaces | the list of sample surfaces | recommended | - fields | word/regex list of fields to sampled | yes | - derived | additional derived fields pTotal/rhoU | no | + Property | Description | Required | Default + type | surfMeshes | yes | + surfaces | list or dictionary of sample surfaces | recommended | + fields | word/regex list of fields to sampled | yes | + derived | additional derived fields pTotal/rhoU | no | rhoRef | reference density for derived fields (incompressible) | no | 1 - sampleScheme | scheme to obtain face centre value | no | cell - createOnRead | Create surface immediately on read | no | false; + sampleScheme | scheme to obtain face centre value | no | cell + createOnRead | Create surface immediately on read | no | false \endtable Note @@ -130,7 +130,7 @@ class surfMeshSamplers { // Static data members - //- output verbosity + //- Output verbosity static bool verbose_; @@ -149,7 +149,7 @@ class surfMeshSamplers wordList derivedNames_; //- Sample scheme to obtain face values - word sampleScheme_; + word sampleFaceScheme_; //- Reference density (to convert from kinematic to static pressure) scalar rhoRef_;