Commit c137d3f8 authored by Mark Olesen's avatar Mark Olesen Committed by Andrew Heather
Browse files

ENH: derivedFields functionObject to create some predefined, calculated fields

- currently supports pTotal, rhoU.
parent e2754962
......@@ -4,6 +4,8 @@ columnAverage/columnAverage.C
continuityError/continuityError.C
derivedFields/derivedFields.C
fieldAverage/fieldAverage.C
fieldAverage/fieldAverageItem/fieldAverageItem.C
fieldAverage/fieldAverageItem/fieldAverageItemIO.C
......
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
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 "derivedFields.H"
#include "volFields.H"
#include "dictionary.H"
#include "Time.H"
#include "mapPolyMesh.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
defineTypeNameAndDebug(derivedFields, 0);
addToRunTimeSelectionTable
(
functionObject,
derivedFields,
dictionary
);
}
}
const Foam::Enum
<
Foam::functionObjects::derivedFields::derivedType
>
Foam::functionObjects::derivedFields::knownNames
({
{ derivedType::NONE , "none" },
{ derivedType::MASS_FLUX , "rhoU" },
{ derivedType::TOTAL_PRESSURE , "pTotal" },
});
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
static bool calc_rhoU
(
const fvMesh& mesh,
const word& derivedName,
const scalar rhoRef
)
{
// rhoU = rho * U
const auto* rhoPtr = mesh.findObject<volScalarField>("rho");
const volVectorField& U = mesh.lookupObject<volVectorField>("U");
volVectorField* result = mesh.getObjectPtr<volVectorField>(derivedName);
const bool isNew = !result;
if (!result)
{
result = new volVectorField
(
IOobject
(
derivedName,
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
true
),
mesh,
(dimDensity * dimVelocity)
);
result->store();
}
if (rhoPtr)
{
const auto& rho = *rhoPtr;
*result = (rho * U);
}
else
{
const dimensionedScalar rho("rho", dimDensity, rhoRef);
*result = (rho * U);
}
return isNew;
}
static bool calc_pTotal
(
const fvMesh& mesh,
const word& derivedName,
const scalar rhoRef
)
{
// 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");
volScalarField* result = mesh.getObjectPtr<volScalarField>(derivedName);
const bool isNew = !result;
if (!result)
{
result = new volScalarField
(
IOobject
(
derivedName,
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
true
),
mesh,
dimPressure
);
result->store();
}
if (rhoPtr)
{
const auto& rho = *rhoPtr;
*result = (p + 0.5 * rho * magSqr(U));
}
else
{
const dimensionedScalar rho("rho", dimDensity, rhoRef);
*result = (rho * (p + 0.5 * magSqr(U)));
}
return isNew;
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::derivedFields::derivedFields
(
const word& name,
const Time& runTime,
const dictionary& dict
)
:
fvMeshFunctionObject(name, runTime, dict),
derivedTypes_(),
rhoRef_(1.0)
{
read(dict);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::derivedFields::read(const dictionary& dict)
{
fvMeshFunctionObject::read(dict),
rhoRef_ = dict.lookupOrDefault<scalar>("rhoRef", 1);
wordList derivedNames(dict.get<wordList>("derived"));
derivedTypes_.resize(derivedNames.size());
label nbad = 0, ngood = 0;
for (const word& key : derivedNames)
{
derivedTypes_[ngood] = knownNames.get(key, derivedType::UNKNOWN);
switch (derivedTypes_[ngood])
{
case derivedType::NONE:
break;
case derivedType::UNKNOWN:
{
derivedNames[nbad++] = key;
break;
}
default:
{
++ngood;
break;
}
}
}
if (nbad)
{
WarningInFunction
<< "Ignoring unknown derived names: "
<< SubList<word>(derivedNames, nbad) << nl;
}
derivedTypes_.resize(ngood);
// Output the good names
forAll(derivedTypes_, i)
{
derivedNames[i] = knownNames[derivedTypes_[i]];
}
Info<< type() << " derived: "
<< flatOutput(SubList<word>(derivedNames, ngood)) << nl;
return true;
}
bool Foam::functionObjects::derivedFields::execute()
{
Log << type() << " calculating:";
for (const derivedType category : derivedTypes_)
{
bool isNew = false;
switch (category)
{
case derivedType::MASS_FLUX:
{
isNew = calc_rhoU(mesh_, knownNames[category], rhoRef_);
Log << " " << knownNames[category];
if (isNew) Log << " (new)";
break;
}
case derivedType::TOTAL_PRESSURE:
{
isNew = calc_pTotal(mesh_, knownNames[category], rhoRef_);
Log << " " << knownNames[category];
if (isNew) Log << " (new)";
break;
}
default:
break;
}
}
Log << nl;
return true;
}
bool Foam::functionObjects::derivedFields::write()
{
for (const derivedType category : derivedTypes_)
{
switch (category)
{
case derivedType::NONE:
case derivedType::UNKNOWN:
break;
default:
{
const auto* ioptr =
mesh_.cfindObject<regIOobject>(knownNames[category]);
if (ioptr)
{
Log << type() << " " << name() << " write:" << nl
<< " writing field " << ioptr->name() << endl;
ioptr->write();
}
break;
}
}
}
return true;
}
void Foam::functionObjects::derivedFields::removeDerivedFields()
{
for (const derivedType category : derivedTypes_)
{
mesh_.thisDb().checkOut(knownNames[category]);
}
}
void Foam::functionObjects::derivedFields::updateMesh(const mapPolyMesh& mpm)
{
if (&mpm.mesh() == &mesh_)
{
removeDerivedFields();
}
}
void Foam::functionObjects::derivedFields::movePoints(const polyMesh& m)
{
if (&m == &mesh_)
{
removeDerivedFields();
}
}
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
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::functionObjects::derivedFields
Group
grpFieldFunctionObjects
Description
A limited set of predefined derived fields ("rhoU", "pTotal").
\verbatim
derived
{
type derivedFields;
libs ("libfieldFunctionObjects.so");
fields (rhoU pTotal);
// Optional: reference density for incompressible
rhoRef 1.25;
}
\endverbatim
Entries:
\table
Property | Description | Required | Default
type | derivedFields | yes |
derived | Derived fields (pTotal/rhoU) | yes |
rhoRef | Reference density (incompressible) | no | 1
\endtable
The known derived fields
\plaintable
rhoU | (rho * U)
pTotal | (p + 1/2 * rho * U)
\endplaintable
SourceFiles
derivedFields.C
\*---------------------------------------------------------------------------*/
#ifndef functionObjects_derivedFields_H
#define functionObjects_derivedFields_H
#include "fvMeshFunctionObject.H"
#include "Enum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
/*---------------------------------------------------------------------------*\
Class derivedFields Declaration
\*---------------------------------------------------------------------------*/
class derivedFields
:
public fvMeshFunctionObject
{
public:
// Public Enumerations
//- Derived/calculated field type
enum derivedType
{
NONE = 0, //!< "none"
MASS_FLUX, //!< "rhoU"
TOTAL_PRESSURE, //!< "pTotal"
UNKNOWN
};
//- Known derived field types
static const Enum<derivedType> knownNames;
protected:
// Read from dictionary
//- List of derived field (types) to create
List<derivedType> derivedTypes_;
//- 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);
public:
//- Run-time type information
TypeName("derivedFields");
// Constructors
//- Construct from Time and dictionary
derivedFields
(
const word& name,
const Time& runTime,
const dictionary& dict
);
//- Destructor
virtual ~derivedFields() = default;
// Member Functions
//- Remove (checkOut) derived fields from the object registry
void removeDerivedFields();
//- Read the data
virtual bool read(const dictionary& dict);
//- Calculate the derived fields
virtual bool execute();
//- Write derived fields
virtual bool write();
//- Update for changes of mesh
virtual void updateMesh(const mapPolyMesh& mpm);
//- Update for mesh point-motion
virtual void movePoints(const polyMesh& m);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace functionObjects
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //
......@@ -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