ENH: atmopshericModels: avoid storing common fields in fvOptions

This commit is contained in:
Kutalmis Bercin
2022-10-21 09:12:39 +01:00
committed by Andrew Heather
parent b50591166e
commit 5fb0cd77f1
4 changed files with 190 additions and 133 deletions

View File

@ -43,14 +43,45 @@ namespace fv
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
Foam::volScalarField& Foam::fv::atmPlantCanopyTurbSource::getOrReadField
(
const word& fieldName
) const
{
auto* ptr = mesh_.getObjectPtr<volScalarField>(fieldName);
if (!ptr)
{
ptr = new volScalarField
(
IOobject
(
fieldName,
mesh_.time().timeName(),
mesh_,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh_
);
mesh_.objectRegistry::store(ptr);
}
return *ptr;
}
Foam::tmp<Foam::volScalarField::Internal>
Foam::fv::atmPlantCanopyTurbSource::calcPlantCanopyTerm
(
const volVectorField::Internal& U
) const
{
const volScalarField& Cd = getOrReadField(CdName_);
const volScalarField& LAD = getOrReadField(LADname_);
// (SP:Eq. 42)
return 12.0*Foam::sqrt(Cmu_)*Cd_()*LAD_()*mag(U);
return 12.0*Foam::sqrt(Cmu_)*Cd()*LAD()*mag(U);
}
@ -65,36 +96,15 @@ Foam::fv::atmPlantCanopyTurbSource::atmPlantCanopyTurbSource
)
:
fv::cellSetOption(sourceName, modelType, dict, mesh),
isEpsilon_(false),
rhoName_(coeffs_.getOrDefault<word>("rho", "rho")),
isEpsilon_(true),
Cmu_(Zero),
C1_(Zero),
C2_(Zero),
Cd_
(
IOobject
(
"Cd",
mesh.time().timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
),
LAD_
(
IOobject
(
"LAD",
mesh.time().timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
)
CdName_(),
LADname_()
{
read(dict);
const auto* turbPtr =
mesh_.findObject<turbulenceModel>
(
@ -113,9 +123,8 @@ Foam::fv::atmPlantCanopyTurbSource::atmPlantCanopyTurbSource
tmp<volScalarField> tepsilon = turbPtr->epsilon();
tmp<volScalarField> tomega = turbPtr->omega();
if (tepsilon.is_reference())
if (!tepsilon.isTmp())
{
isEpsilon_ = true;
fieldNames_[0] = tepsilon().name();
const dictionary& turbDict = turbPtr->coeffDict();
@ -123,7 +132,7 @@ Foam::fv::atmPlantCanopyTurbSource::atmPlantCanopyTurbSource
C1_.read("C1", turbDict);
C2_.read("C2", turbDict);
}
else if (tomega.is_reference())
else if (!tomega.isTmp())
{
isEpsilon_ = false;
fieldNames_[0] = tomega().name();
@ -214,4 +223,21 @@ void Foam::fv::atmPlantCanopyTurbSource::addSup
}
bool Foam::fv::atmPlantCanopyTurbSource::read(const dictionary& dict)
{
if (!fv::cellSetOption::read(dict))
{
return false;
}
CdName_ = dict.getOrDefault<word>("Cd", "Cd");
LADname_ = dict.getOrDefault<word>("LAD", "LAD");
(void) getOrReadField(CdName_);
(void) getOrReadField(LADname_);
return true;
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 ENERCON GmbH
Copyright (C) 2020 OpenCFD Ltd.
Copyright (C) 2020-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -36,15 +36,16 @@ Description
Corrections applied to either of the below, if exist:
\verbatim
epsilon | Turbulent kinetic energy dissipation rate [m2/s3]
epsilon | Turbulent kinetic energy dissipation rate [m^2/s^3]
omega | Specific dissipation rate [1/s]
\endverbatim
Required fields:
\verbatim
epsilon/omega | Dissipation rate OR Spec. dissipation rate [m2/s3]/[1/s]
Cd | Plant canopy drag coefficient [-]
LAD | Leaf area density [1/m]
Cd | Canopy drag coefficient [-]
LAD | Leaf area density [m^2/m^3]
epsilon | Turbulent kinetic energy dissipation rate [m^2/s^3]
omega | Specific dissipation rate [1/s]
\endverbatim
References:
@ -61,28 +62,24 @@ Usage
\verbatim
atmPlantCanopyTurbSource1
{
// Mandatory entries (unmodifiable)
type atmPlantCanopyTurbSource;
// Mandatory entries
type atmPlantCanopyTurbSource;
atmPlantCanopyTurbSourceCoeffs
{
// Mandatory (inherited) entries (unmodifiable)
selectionMode all;
// Optional entries
Cd <word>;
LAD <word>;
// Optional entries (unmodifiable)
rho rho;
}
// Optional (inherited) entries
// Inherited entries
...
}
\endverbatim
where the entries mean:
\table
Property | Description | Type | Req'd | Dflt
type | Type name: atmPlantCanopyTurbSource | word | yes | -
rho | Name of density field | word | no | rho
Property | Description | Type | Reqd | Deflt
type | Type name: atmPlantCanopyTurbSource | word | yes | -
Cd | Name of operand canopy drag coefficient field | word | no | Cd
LAD | Name of operand leaf area density field | word | no | LAD
\endtable
The inherited entries are elaborated in:
@ -109,7 +106,7 @@ namespace fv
{
/*---------------------------------------------------------------------------*\
Class atmPlantCanopyTurbSource Declaration
Class atmPlantCanopyTurbSource Declaration
\*---------------------------------------------------------------------------*/
class atmPlantCanopyTurbSource
@ -121,26 +118,24 @@ class atmPlantCanopyTurbSource
//- Internal flag to determine the working field is epsilon or omega
Switch isEpsilon_;
//- Name of density field
const word rhoName_;
//- Required turbulence model coefficients (copied from turb model)
dimensionedScalar Cmu_;
dimensionedScalar C1_;
dimensionedScalar C2_;
//- Name of operand canopy drag coefficient field
word CdName_;
// Fields
//- Plant canopy drag coefficient field [-]
volScalarField Cd_;
//- Leaf area density field [1/m]
volScalarField LAD_;
//- Name of operand leaf area density field
word LADname_;
// Private Member Functions
//- Return requested field from the object registry
//- or read+register the field to the object registry
volScalarField& getOrReadField(const word& fieldName) const;
//- Return the modifier for plant canopy effects
tmp<volScalarField::Internal> calcPlantCanopyTerm
(
@ -221,11 +216,8 @@ public:
const label fieldi
);
//- Read source dictionary (effectively no-op)
virtual bool read(const dictionary& dict)
{
return true;
}
//- Read source dictionary
virtual bool read(const dictionary& dict);
};

View File

@ -42,6 +42,36 @@ namespace fv
}
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
Foam::volScalarField& Foam::fv::atmPlantCanopyUSource::getOrReadField
(
const word& fieldName
) const
{
auto* ptr = mesh_.getObjectPtr<volScalarField>(fieldName);
if (!ptr)
{
ptr = new volScalarField
(
IOobject
(
fieldName,
mesh_.time().timeName(),
mesh_,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh_
);
mesh_.objectRegistry::store(ptr);
}
return *ptr;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fv::atmPlantCanopyUSource::atmPlantCanopyUSource
@ -53,32 +83,11 @@ Foam::fv::atmPlantCanopyUSource::atmPlantCanopyUSource
)
:
fv::cellSetOption(sourceName, modelType, dict, mesh),
rhoName_(coeffs_.getOrDefault<word>("rho", "rho")),
Cd_
(
IOobject
(
"Cd",
mesh.time().timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
),
LAD_
(
IOobject
(
"LAD",
mesh.time().timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
)
CdName_(),
LADname_()
{
read(dict);
fieldNames_.resize(1, "U");
fv::option::resetApplied();
@ -95,13 +104,17 @@ void Foam::fv::atmPlantCanopyUSource::addSup
const label fieldi
)
{
const volVectorField& U = eqn.psi();
if (V_ > VSMALL)
if (V_ < VSMALL)
{
// (SP:Eq. 42)
eqn -= fvm::Sp(Cd_*LAD_*mag(U), U);
return;
}
const volVectorField& U = eqn.psi();
const volScalarField& Cd = getOrReadField(CdName_);
const volScalarField& LAD = getOrReadField(LADname_);
// (SP:Eq. 42), (BSG:Eq. 7)
eqn -= fvm::Sp(Cd*LAD*mag(U), U);
}
@ -112,12 +125,16 @@ void Foam::fv::atmPlantCanopyUSource::addSup
const label fieldi
)
{
const volVectorField& U = eqn.psi();
if (V_ > VSMALL)
if (V_ < VSMALL)
{
eqn -= fvm::Sp(rho*Cd_*LAD_*mag(U), U);
return;
}
const volVectorField& U = eqn.psi();
const volScalarField& Cd = getOrReadField(CdName_);
const volScalarField& LAD = getOrReadField(LADname_);
eqn -= fvm::Sp(rho*Cd*LAD*mag(U), U);
}
@ -129,12 +146,33 @@ void Foam::fv::atmPlantCanopyUSource::addSup
const label fieldi
)
{
const volVectorField& U = eqn.psi();
if (V_ > VSMALL)
if (V_ < VSMALL)
{
eqn -= fvm::Sp(alpha*rho*Cd_*LAD_*mag(U), U);
return;
}
const volVectorField& U = eqn.psi();
const volScalarField& Cd = getOrReadField(CdName_);
const volScalarField& LAD = getOrReadField(LADname_);
eqn -= fvm::Sp(alpha*rho*Cd*LAD*mag(U), U);
}
bool Foam::fv::atmPlantCanopyUSource::read(const dictionary& dict)
{
if (!fv::cellSetOption::read(dict))
{
return false;
}
CdName_ = dict.getOrDefault<word>("Cd", "Cd");
LADname_ = dict.getOrDefault<word>("LAD", "LAD");
(void) getOrReadField(CdName_);
(void) getOrReadField(LADname_);
return true;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 ENERCON GmbH
Copyright (C) 2020 OpenCFD Ltd.
Copyright (C) 2020-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,7 +31,7 @@ Group
grpFvOptionsSources
Description
Applies sources on velocity, i.e. \c U, to incorporate effects
Applies sources on velocity (i.e. \c U) to incorporate effects
of plant canopy for atmospheric boundary layer modelling.
Corrections applied to:
@ -53,6 +53,13 @@ Description
Modification of two-equation models to account for plant drag.
Boundary-Layer Meteorology, 121(2), 229-266.
DOI:10.1007/s10546-006-9073-5
Governing equations (tag:BSG):
Brozovsky, J., Simonsen, A., & Gaitani, N. (2021).
Validation of a CFD model for the evaluation of urban microclimate
at high latitudes: A case study in Trondheim, Norway.
Building and Environment, 205, 108175.
DOI:10.1016/j.buildenv.2021.108175
\endverbatim
Usage
@ -60,28 +67,24 @@ Usage
\verbatim
atmPlantCanopyUSource1
{
// Mandatory entries (unmodifiable)
type atmPlantCanopyUSource;
// Mandatory entries
type atmPlantCanopyUSource;
atmPlantCanopyUSourceCoeffs
{
// Mandatory (inherited) entries (unmodifiable)
selectionMode all;
// Optional entries
Cd <word>;
LAD <word>;
// Optional entries (unmodifiable)
rho rho;
}
// Optional (inherited) entries
// Inherited entries
...
}
\endverbatim
where the entries mean:
\table
Property | Description | Type | Req'd | Dflt
type | Type name: atmPlantCanopyUSource | word | yes | -
rho | Name of density field | word | no | rho
Property | Description | Type | Reqd | Deflt
type | Type name: atmPlantCanopyUSource | word | yes | -
Cd | Name of operand canopy drag coefficient field | word | no | Cd
LAD | Name of operand leaf area density field | word | no | LAD
\endtable
The inherited entries are elaborated in:
@ -108,7 +111,7 @@ namespace fv
{
/*---------------------------------------------------------------------------*\
Class atmPlantCanopyUSource Declaration
Class atmPlantCanopyUSource Declaration
\*---------------------------------------------------------------------------*/
class atmPlantCanopyUSource
@ -117,17 +120,18 @@ class atmPlantCanopyUSource
{
// Private Data
//- Name of density field
const word rhoName_;
//- Name of operand canopy drag coefficient field
word CdName_;
//- Name of operand leaf area density field
word LADname_;
// Fields
// Private Member Functions
//- Plant canopy drag coefficient field [-]
volScalarField Cd_;
//- Leaf area density field [1/m]
volScalarField LAD_;
//- Return requested field from the object registry
//- or read+register the field to the object registry
volScalarField& getOrReadField(const word& fieldName) const;
public:
@ -180,11 +184,8 @@ public:
const label fieldi
);
//- Read source dictionary (effectively no-op)
virtual bool read(const dictionary& dict)
{
return true;
}
//- Read source dictionary
virtual bool read(const dictionary& dict);
};