ENH: derivedFields functionObject to create some predefined, calculated fields

- currently supports pTotal, rhoU.
This commit is contained in:
Mark Olesen
2019-02-08 17:47:45 +01:00
parent 7c21f42b6d
commit 8a99afd271
13 changed files with 616 additions and 186 deletions

View File

@ -77,93 +77,6 @@ bool Foam::surfMeshSamplers::verbose_ = false;
// return tmpRegistry().subRegistry(subName, true, false);
// }
bool Foam::surfMeshSamplers::add_rhoU(const word& derivedName)
{
const objectRegistry& db = mesh_.thisDb();
const bool existed = db.foundObject<volVectorField>(derivedName);
if (existed)
{
return false; // Volume field already existed - not added.
}
// rhoU = rho * U
const auto* rhoPtr = mesh_.findObject<volScalarField>("rho");
const volVectorField& U = mesh_.lookupObject<volVectorField>("U");
tmp<volVectorField> tresult;
if (rhoPtr)
{
const auto& rho = *rhoPtr;
tresult = tmp<volVectorField>::New
(
derivedName, (rho * U)
);
}
else
{
const dimensionedScalar rho("rho", dimDensity, rhoRef_);
tresult = tmp<volVectorField>::New
(
derivedName, (rho * U)
);
}
db.store(tresult.ptr());
return !existed;
}
bool Foam::surfMeshSamplers::add_pTotal(const word& derivedName)
{
const objectRegistry& db = mesh_.thisDb();
const bool existed = db.foundObject<volVectorField>(derivedName);
if (existed)
{
return false; // Volume field already existed - not added.
}
// pTotal = p + rho * U^2 / 2
const auto* rhoPtr = mesh_.findObject<volScalarField>("rho");
const volScalarField& p = mesh_.lookupObject<volScalarField>("p");
const volVectorField& U = mesh_.lookupObject<volVectorField>("U");
tmp<volScalarField> tresult;
if (rhoPtr)
{
const auto& rho = *rhoPtr;
tresult = tmp<volScalarField>::New
(
derivedName, (p + 0.5 * rho * magSqr(U))
);
}
else
{
const dimensionedScalar rho("rho", dimDensity, rhoRef_);
tresult = tmp<volScalarField>::New
(
derivedName, (rho * (p + 0.5 * magSqr(U)))
);
}
db.store(tresult.ptr());
return !existed;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -177,9 +90,7 @@ Foam::surfMeshSamplers::surfMeshSamplers
functionObjects::fvMeshFunctionObject(name, runTime, dict),
PtrList<surfMeshSample>(),
fieldSelection_(),
derivedNames_(),
sampleFaceScheme_(),
rhoRef_(1.0)
sampleFaceScheme_()
{
read(dict);
}
@ -195,9 +106,7 @@ Foam::surfMeshSamplers::surfMeshSamplers
functionObjects::fvMeshFunctionObject(name, obr, dict),
PtrList<surfMeshSample>(),
fieldSelection_(),
derivedNames_(),
sampleFaceScheme_(),
rhoRef_(1.0)
sampleFaceScheme_()
{
read(dict);
}
@ -218,44 +127,8 @@ bool Foam::surfMeshSamplers::execute()
return true;
}
const objectRegistry& db = mesh_.thisDb();
// Manage derived names
DynamicList<word> added(derivedNames_.size());
DynamicList<word> cleanup(derivedNames_.size());
for (const word& derivedName : derivedNames_)
{
// This is a fairly ugly dispatch mechanism
if (derivedName == "rhoU")
{
if (add_rhoU(derivedName))
{
cleanup.append(derivedName);
}
added.append(derivedName);
}
else if (derivedName == "pTotal")
{
if (add_pTotal(derivedName))
{
cleanup.append(derivedName);
}
added.append(derivedName);
}
else
{
WarningInFunction
<< "unknown derived name: " << derivedName << nl
<< "Use one of 'rhoU', 'pTotal'" << nl
<< endl;
}
}
// The acceptable fields
wordHashSet acceptable(added);
wordHashSet acceptable;
acceptable.insert(acceptType<scalar>());
acceptable.insert(acceptType<vector>());
acceptable.insert(acceptType<sphericalTensor>());
@ -277,11 +150,7 @@ bool Foam::surfMeshSamplers::execute()
}
}
// Cleanup any locally introduced names
for (const word& fieldName : cleanup)
{
db.checkOut(fieldName);
}
clearObjects(removeFieldsOnExecute_);
return true;
}
@ -294,27 +163,13 @@ bool Foam::surfMeshSamplers::write()
// Doesn't bother checking which fields have been generated here
// or elsewhere
// This could be more efficient
wordRes select(fieldSelection_.size() + derivedNames_.size());
label nElem = 0;
for (const wordRe& item : fieldSelection_)
{
select[nElem++] = item;
}
for (const auto& derivedName : derivedNames_)
{
select[nElem++] = derivedName;
}
// Avoid duplicate entries
select.uniq();
for (const surfMeshSample& s : surfaces())
{
s.write(select);
s.write(fieldSelection_);
}
clearObjects(removeFieldsOnWrite_);
return true;
}
@ -325,9 +180,11 @@ bool Foam::surfMeshSamplers::read(const dictionary& dict)
PtrList<surfMeshSample>::clear();
fieldSelection_.clear();
derivedNames_.clear();
removeFieldsOnExecute_.clear();
removeFieldsOnWrite_.clear();
rhoRef_ = dict.lookupOrDefault<scalar>("rhoRef", 1);
dict.readIfPresent("removeFieldsOnExecute", removeFieldsOnExecute_);
dict.readIfPresent("removeFieldsOnWrite", removeFieldsOnWrite_);
const bool createOnRead = dict.lookupOrDefault("createOnRead", false);
@ -393,11 +250,6 @@ bool Foam::surfMeshSamplers::read(const dictionary& dict)
fieldSelection_.uniq();
Info<< type() << " fields: " << flatOutput(fieldSelection_) << nl;
if (dict.readIfPresent("derived", derivedNames_))
{
Info<< type() << " derived: " << flatOutput(derivedNames_) << nl;
}
Info<< nl;
// Ensure all surfaces and merge information are expired
@ -431,6 +283,20 @@ bool Foam::surfMeshSamplers::read(const dictionary& dict)
Info<< nl;
}
if (removeFieldsOnExecute_.size())
{
Info<< type() << " Remove fields on-execute : "
<< removeFieldsOnExecute_ << nl;
}
if (removeFieldsOnWrite_.size())
{
Info<< type() << " Remove fields on-write :"
<< removeFieldsOnWrite_ << nl;
}
// Ensure all surfaces are expired (unsampled)
expire();
return true;
}

View File

@ -51,16 +51,13 @@ Description
// Scheme to obtain face centre value
sampleScheme cell;
// Optional: pre-defined derived fields to be sampled
derived (rhoU pTotal);
// Reference density for incompressible
rhoRef 1.25;
// Optional: create surface immediately on read
// The default is to create a placeholder without any faces.
createOnRead false;
// Optional: remove derived fields created prior
removeFieldsOnExecute ( someDerivedField );
surfaces
(
f0surf
@ -83,13 +80,13 @@ Description
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
removeFieldsOnExecute | List of fields to remove as "consumed" | no |
removeFieldsOnWrite | List of fields to remove as "consumed" | no |
\endtable
Note
The default is to create a placeholder surMesh without any faces on
construction. This behaviour can be changed by the createOnRead option.
For incompressible cases, \c rhoRef can be specified for use in the
derived quantities. The default is 1.
See also
Foam::sampledSurfaces
@ -134,27 +131,18 @@ class surfMeshSamplers
//- Names of fields to sample
wordRes fieldSelection_;
//- Names of derived fields to create and sample
wordList derivedNames_;
//- List of fields to remove as "consumed"
wordList removeFieldsOnExecute_;
//- List of fields to remove as "consumed"
wordList removeFieldsOnWrite_;
//- Sample scheme to obtain face values
word sampleFaceScheme_;
//- Reference density (to convert from kinematic to static pressure)
scalar rhoRef_;
// Private Member Functions
//- Hard-coded derived field (rho * U)
// \return true if field did not previously exist
bool add_rhoU(const word& derivedName);
//- Hard-coded derived field (p + 1/2 * rho * U)
// \return true if field did not previously exist
bool add_pTotal(const word& derivedName);
//- Access the sampling surfaces
inline const PtrList<surfMeshSample>& surfaces() const
{