ENH: fanFvPatchField - refactored; added flowRate option

The basis of the table is specified according to the mode:

- velocity: deltap = F(velocity per face) \[DEFAULT\]
- uniformVelocity: deltap = F(patch area-averaged velocity)
- volumeFlowRate:  deltap = F(patch volume flow rate)
- nonDimensional:  non-dim deltap = F(non-dim volume flow rate)

Example of the boundary condition specification:

    <patchName>
    {
        type            fan;
        patchType       cyclic;
        jumpTable       csvFile;
        mode            velocity; // New entry

        jumpTableCoeffs
        {
            nHeaderLine     1;
            refColumn       0;
            componentColumns 1(1);
            separator       ",";
            mergeSeparators no;
            file            "<constant>/UvsPressure";
        }
        value           uniform 0;
    }
This commit is contained in:
Andrew Heather 2024-12-18 15:24:30 +00:00
parent b0b1d0f8b2
commit 4423efd313
4 changed files with 186 additions and 86 deletions

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2017-2021 OpenCFD Ltd.
Copyright (C) 2017-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,6 +28,19 @@ License
#include "fanFvPatchField.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
template<class Type>
const Foam::Enum<typename Foam::fanFvPatchField<Type>::operatingMode>
Foam::fanFvPatchField<Type>::operatingModeNames_
({
{ operatingMode::VELOCITY, "velocity" },
{ operatingMode::UNIFORM_VELOCITY, "uniformVelocity" },
{ operatingMode::VOL_FLOW_RATE, "volumeFlowRate" },
{ operatingMode::NON_DIMENSIONAL, "nonDimensional" },
});
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
@ -50,10 +63,9 @@ Foam::fanFvPatchField<Type>::fanFvPatchField
)
:
uniformJumpFvPatchField<Type>(p, iF),
operatingMode_(operatingMode::VELOCITY),
phiName_("phi"),
rhoName_("rho"),
uniformJump_(false),
nonDimensional_(false),
rpm_(nullptr),
dm_(nullptr)
{}
@ -68,15 +80,36 @@ Foam::fanFvPatchField<Type>::fanFvPatchField
)
:
uniformJumpFvPatchField<Type>(p, iF, dict, false), // needValue = false
operatingMode_
(
operatingModeNames_.getOrDefault("mode", dict, operatingMode::VELOCITY)
),
phiName_(dict.getOrDefault<word>("phi", "phi")),
rhoName_(dict.getOrDefault<word>("rho", "rho")),
uniformJump_(dict.getOrDefault("uniformJump", false)),
nonDimensional_(dict.getOrDefault("nonDimensional", false)),
rpm_(nullptr),
dm_(nullptr)
{
// Backwards compatibility
if (operatingMode_ == operatingMode::VELOCITY)
{
bool nonDimCompat = dict.getOrDefault("nonDimensional", false);
if (nonDimCompat)
{
// Warn?
operatingMode_ = operatingMode::NON_DIMENSIONAL;
}
bool uniformCompat = dict.getOrDefault("uniformJump", false);
if (uniformCompat)
{
// Warn?
operatingMode_ = operatingMode::UNIFORM_VELOCITY;
}
}
// Note that we've not read jumpTable_ etc
if (nonDimensional_)
if (operatingMode_ == operatingMode::NON_DIMENSIONAL)
{
rpm_.reset(Function1<scalar>::New("rpm", dict, &this->db()));
dm_.reset(Function1<scalar>::New("dm", dict, &this->db()));
@ -104,10 +137,9 @@ Foam::fanFvPatchField<Type>::fanFvPatchField
)
:
uniformJumpFvPatchField<Type>(rhs, p, iF, mapper),
operatingMode_(rhs.operatingMode_),
phiName_(rhs.phiName_),
rhoName_(rhs.rhoName_),
uniformJump_(rhs.uniformJump_),
nonDimensional_(rhs.nonDimensional_),
rpm_(rhs.rpm_.clone()),
dm_(rhs.dm_.clone())
{}
@ -120,10 +152,9 @@ Foam::fanFvPatchField<Type>::fanFvPatchField
)
:
uniformJumpFvPatchField<Type>(rhs),
operatingMode_(rhs.operatingMode_),
phiName_(rhs.phiName_),
rhoName_(rhs.rhoName_),
uniformJump_(rhs.uniformJump_),
nonDimensional_(rhs.nonDimensional_),
rpm_(rhs.rpm_.clone()),
dm_(rhs.dm_.clone())
{}
@ -137,10 +168,9 @@ Foam::fanFvPatchField<Type>::fanFvPatchField
)
:
uniformJumpFvPatchField<Type>(rhs, iF),
operatingMode_(rhs.operatingMode_),
phiName_(rhs.phiName_),
rhoName_(rhs.rhoName_),
uniformJump_(rhs.uniformJump_),
nonDimensional_(rhs.nonDimensional_),
rpm_(rhs.rpm_.clone()),
dm_(rhs.dm_.clone())
{}
@ -170,14 +200,10 @@ void Foam::fanFvPatchField<Type>::write(Ostream& os) const
os.writeEntryIfDifferent<word>("phi", "phi", phiName_);
os.writeEntryIfDifferent<word>("rho", "rho", rhoName_);
if (uniformJump_)
{
os.writeEntry("uniformJump", "true");
}
os.writeEntry("mode", operatingModeNames_[operatingMode_]);
if (nonDimensional_)
if (operatingMode_ == operatingMode::NON_DIMENSIONAL)
{
os.writeEntry("nonDimensional", "true");
rpm_->writeData(os);
dm_->writeData(os);
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd.
Copyright (C) 2017-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -37,14 +37,21 @@ Description
The jump is specified as a \c Function1 type, to enable the use of, e.g.
constant, polynomial, table values.
The switch nonDimensional can be used for a non-dimensional table,
in combination with uniformJump = true.
The basis of the table is specified according to the \c mode:
- velocity: deltap = F(velocity per face) \[DEFAULT\]
- uniformVelocity: deltap = F(patch area-averaged velocity)
- volumeFlowRate: deltap = F(patch volume flow rate)
- nonDimensional: non-dim deltap = F(non-dim volume flow rate)
Non-dimensional operation:
As inputs it needs the fan RPM (rpm) and the mean diameter (dm).
The non-dimensional U for the table is calculated as follows:
\verbatim
phi = 120*Un/(PI^3*dm*rpm)
phi = 120*Un/(PI^3*dm^3*rpm)
where:
dm is the mean diameter.
rpm is the RPM of the fan.
@ -64,11 +71,10 @@ Usage
\table
Property | Description | Required | Default
patchType | underlying patch type should be \c cyclic | yes |
mode | jump table operating mode (see above) | no | velocity
jumpTable | jump data, e.g. \c csvFile | yes |
phi | flux field name | no | phi
rho | density field name | no | rho
uniformJump | apply uniform pressure based on avg velocity | no | false
nonDimensional | use non-dimensional table | no | false
rpm | fan rpm (non-dimensional table) | no |
dm | mean diameter (non-dimensional table) | no |
\endtable
@ -80,6 +86,7 @@ Usage
type fan;
patchType cyclic;
jumpTable csvFile;
mode velocity;
jumpTableCoeffs
{
@ -107,15 +114,15 @@ SourceFiles
fanFvPatchField.C
fanFvPatchFields.H
fanFvPatchFields.C
fanFvPatchFieldsFwd.H
\*---------------------------------------------------------------------------*/
#ifndef fanFvPatchField_H
#define fanFvPatchField_H
#ifndef foam_fanFvPatchField_H
#define foam_fanFvPatchField_H
#include "uniformJumpFvPatchField.H"
#include "Function1.H"
#include "Enum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -131,20 +138,36 @@ class fanFvPatchField
:
public uniformJumpFvPatchField<Type>
{
public:
// Public Data Types
//- Enumeration defining the operating modes
enum class operatingMode
{
VELOCITY, //!< velocity-based lookup
UNIFORM_VELOCITY, //!< uniform velocity-based lookup
VOL_FLOW_RATE, //!< volume-flow-rate-based lookup
NON_DIMENSIONAL //!< non-dimensional-based lookup
};
//- Names for the operating modes
static const Enum<operatingMode> operatingModeNames_;
private:
// Private Data
//- Operating mode
operatingMode operatingMode_;
//- Name of the flux transporting the field
word phiName_;
//- Name of the density field for normalising the mass flux if necessary
word rhoName_;
//- Apply uniform pressure drop
bool uniformJump_;
//- Use non-dimensional curve
bool nonDimensional_;
//- Fan rpm (for non-dimensional curve)
autoPtr<Function1<scalar>> rpm_;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2017-2021 OpenCFD Ltd.
Copyright (C) 2017-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -44,69 +44,120 @@ namespace Foam
template<>
void Foam::fanFvPatchField<Foam::scalar>::calcFanJump()
{
if (this->cyclicPatch().owner())
if (!this->cyclicPatch().owner())
{
const auto& phip =
patch().lookupPatchField<surfaceScalarField>(phiName_);
return;
}
scalarField Un(max(phip/patch().magSf(), scalar(0)));
const auto& phip = patch().lookupPatchField<surfaceScalarField>(phiName_);
// The non-dimensional parameters
scalarField volFlowRate(max(phip, scalar(0)));
scalar rpm(0);
scalar meanDiam(0);
if (phip.internalField().dimensions() == dimVolume/dimTime)
{
// No conversion of volFlowRate required
}
else if (phip.internalField().dimensions() == dimMass/dimTime)
{
const auto& rhop = patch().lookupPatchField<volScalarField>(rhoName_);
volFlowRate /= rhop;
}
else
{
FatalErrorInFunction
<< "dimensions of phi are not correct\n"
<< " on patch " << patch().name()
<< " of field " << internalField().name()
<< " in file " << internalField().objectPath() << nl
<< exit(FatalError);
}
if (nonDimensional_)
// The non-dimensional parameters
scalar rpm(0);
scalar meanDiam(0);
scalarField pdFan(patch().size(), Zero);
switch (operatingMode_)
{
case operatingMode::VELOCITY:
{
// Note: volFlowRate now becomes face normal velocity
volFlowRate /= patch().magSf();
// Per-face values
pdFan = this->jumpTable_->value(volFlowRate);
break;
}
case operatingMode::UNIFORM_VELOCITY:
{
// Note: volFlowRate now becomes face normal velocity
volFlowRate /= patch().magSf();
// Set face values to patch area-averaged value
const scalar area = gSum(patch().magSf());
const scalar UnAve = gSum(volFlowRate*patch().magSf())/area;
// Assign uniform value
pdFan = this->jumpTable_->value(UnAve);
break;
}
case operatingMode::VOL_FLOW_RATE:
{
// Face-based volFlowRate converted to patch-based volFlowRate
// for pd curve lookup
const scalar sumVolFlowRate = gSum(volFlowRate);
// Assign uniform value
pdFan = this->jumpTable_->value(sumVolFlowRate);
break;
}
case operatingMode::NON_DIMENSIONAL:
{
// Face-based volFlowRate converted to patch-based volFlowRate
// for pd curve lookup
scalar sumVolFlowRate = gSum(volFlowRate);
rpm = rpm_->value(this->db().time().timeOutputValue());
meanDiam = dm_->value(this->db().time().timeOutputValue());
}
if (uniformJump_)
{
const scalar area = gSum(patch().magSf());
Un = gSum(Un*patch().magSf())/area;
if (nonDimensional_)
{
// Create an non-dimensional velocity
Un =
(
120.0*Un
/ stabilise
(
pow3(constant::mathematical::pi) * meanDiam * rpm,
VSMALL
)
);
}
}
if (phip.internalField().dimensions() == dimMass/dimTime)
{
Un /= patch().lookupPatchField<volScalarField>(rhoName_);
}
if (nonDimensional_)
{
scalarField deltap(this->jumpTable_->value(Un));
// Convert non-dimensional deltap from curve into deltaP
scalarField pdFan
// Create a non-dimensional flow rate
sumVolFlowRate *=
(
deltap*pow4(constant::mathematical::pi)
* sqr(meanDiam*rpm)/1800.0
120.0
/stabilise
(
pow3(constant::mathematical::pi*meanDiam)*rpm,
VSMALL
)
);
this->setJump(pdFan);
}
else
{
this->setJump(jumpTable_->value(Un));
}
const scalar pdNonDim = this->jumpTable_->value(sumVolFlowRate);
this->relax();
// Convert uniform non-dimensional pdFan from curve into deltaP
pdFan =
pdNonDim
*pow4(constant::mathematical::pi)*sqr(meanDiam*rpm)/1800.0;
break;
}
default:
{
FatalErrorInFunction
<< "Unhandled enumeration "
<< operatingModeNames_[operatingMode_]
<< abort(FatalError);
}
}
this->setJump(pdFan);
this->relax();
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,8 +25,8 @@ License
\*---------------------------------------------------------------------------*/
#ifndef fanFvPatchFields_H
#define fanFvPatchFields_H
#ifndef foam_fanFvPatchFields_H
#define foam_fanFvPatchFields_H
#include "fanFvPatchField.H"
#include "fieldTypes.H"