externalWallHeatFluxTemperature: Removed "mode"

Heat power (Q), heat flux (q) and heat transfer coefficient (h)
can now all be specified simultaneously. Their effects will be summed
into a single heat transfer rate. The "mode" keyword is no longer
required.
This commit is contained in:
Will Bainbridge
2022-03-07 09:01:49 +00:00
parent e7aaae76ac
commit 373c4993a8
3 changed files with 238 additions and 307 deletions

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -30,30 +30,6 @@ License
using Foam::constant::physicoChemical::sigma; using Foam::constant::physicoChemical::sigma;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
const char*
NamedEnum
<
externalWallHeatFluxTemperatureFvPatchScalarField::operationMode,
3
>::names[] =
{
"power",
"flux",
"coefficient"
};
}
const Foam::NamedEnum
<
Foam::externalWallHeatFluxTemperatureFvPatchScalarField::operationMode,
3
> Foam::externalWallHeatFluxTemperatureFvPatchScalarField::operationModeNames;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -66,15 +42,20 @@ externalWallHeatFluxTemperatureFvPatchScalarField
: :
mixedFvPatchScalarField(p, iF), mixedFvPatchScalarField(p, iF),
temperatureCoupledBase(patch()), temperatureCoupledBase(patch()),
mode_(fixedHeatFlux), haveQ_(false),
Q_(0), Q_(NaN),
haveq_(false),
q_(),
haveh_(false),
h_(),
Ta_(), Ta_(),
relaxation_(1),
emissivity_(0), emissivity_(0),
qrRelaxation_(1),
qrName_("undefined-qr"),
thicknessLayers_(), thicknessLayers_(),
kappaLayers_() kappaLayers_(),
relaxation_(1),
qrName_(word::null),
qrRelaxation_(1),
qrPrevious_()
{ {
refValue() = 0; refValue() = 0;
refGrad() = 0; refGrad() = 0;
@ -92,57 +73,50 @@ externalWallHeatFluxTemperatureFvPatchScalarField
: :
mixedFvPatchScalarField(p, iF), mixedFvPatchScalarField(p, iF),
temperatureCoupledBase(patch(), dict), temperatureCoupledBase(patch(), dict),
mode_(operationModeNames.read(dict.lookup("mode"))), haveQ_(dict.found("Q")),
Q_(0), Q_(haveQ_ ? dict.lookup<scalar>("Q") : NaN),
Ta_(), haveq_(dict.found("q")),
relaxation_(dict.lookupOrDefault<scalar>("relaxation", 1)), q_(haveq_ ? scalarField("q", dict, p.size()) : scalarField()),
haveh_(dict.found("h")),
h_(haveh_ ? scalarField("h", dict, p.size()) : scalarField()),
Ta_(haveh_ ? Function1<scalar>::New("Ta", dict).ptr() : nullptr),
emissivity_(dict.lookupOrDefault<scalar>("emissivity", 0)), emissivity_(dict.lookupOrDefault<scalar>("emissivity", 0)),
thicknessLayers_
(
dict.lookupOrDefault<scalarList>("thicknessLayers", scalarList())
),
kappaLayers_
(
dict.lookupOrDefault<scalarList>("kappaLayers", scalarList())
),
relaxation_(dict.lookupOrDefault<scalar>("relaxation", 1)),
qrName_(dict.lookupOrDefault<word>("qr", word::null)),
qrRelaxation_(dict.lookupOrDefault<scalar>("qrRelaxation", 1)), qrRelaxation_(dict.lookupOrDefault<scalar>("qrRelaxation", 1)),
qrName_(dict.lookupOrDefault<word>("qr", "none")), qrPrevious_
thicknessLayers_(), (
kappaLayers_() qrName_ != word::null
? dict.found("qrPrevious")
? scalarField("qrPrevious", dict, p.size())
: scalarField(0, p.size())
: scalarField()
)
{ {
switch (mode_)
{
case fixedPower:
{
dict.lookup("Q") >> Q_;
break;
}
case fixedHeatFlux:
{
q_ = scalarField("q", dict, p.size());
break;
}
case fixedHeatTransferCoeff:
{
h_ = scalarField("h", dict, p.size());
Ta_ = Function1<scalar>::New("Ta", dict);
if (dict.found("thicknessLayers"))
{
dict.lookup("thicknessLayers") >> thicknessLayers_;
dict.lookup("kappaLayers") >> kappaLayers_;
}
break;
}
}
fvPatchScalarField::operator=(scalarField("value", dict, p.size())); fvPatchScalarField::operator=(scalarField("value", dict, p.size()));
if (qrName_ != "none") if (!haveQ_ && !haveq_ && !haveh_)
{ {
if (dict.found("qrPrevious")) FatalIOErrorInFunction(dict)
{ << "One or more of Q (heat power), q (heat flux), and h (heat "
qrPrevious_ = scalarField("qrPrevious", dict, p.size()); << "transfer coefficient) must be specified"
<< exit(FatalIOError);
} }
else
if (thicknessLayers_.size() != kappaLayers_.size())
{ {
qrPrevious_.setSize(p.size(), 0); FatalIOErrorInFunction(dict)
} << "If either thicknessLayers or kappaLayers is specified, then "
<< "both must be specified and be lists of the same length "
<< exit(FatalIOError);
} }
if (dict.found("refValue")) if (dict.found("refValue"))
@ -173,39 +147,26 @@ externalWallHeatFluxTemperatureFvPatchScalarField
: :
mixedFvPatchScalarField(ptf, p, iF, mapper), mixedFvPatchScalarField(ptf, p, iF, mapper),
temperatureCoupledBase(patch(), ptf), temperatureCoupledBase(patch(), ptf),
mode_(ptf.mode_), haveQ_(ptf.haveQ_),
Q_(ptf.Q_), Q_(ptf.Q_),
haveq_(ptf.haveq_),
q_(haveq_ ? mapper(ptf.q_)() : scalarField()),
haveh_(ptf.haveq_),
h_(haveh_ ? mapper(ptf.q_)() : scalarField()),
Ta_(ptf.Ta_, false), Ta_(ptf.Ta_, false),
relaxation_(ptf.relaxation_),
emissivity_(ptf.emissivity_), emissivity_(ptf.emissivity_),
qrRelaxation_(ptf.qrRelaxation_),
qrName_(ptf.qrName_),
thicknessLayers_(ptf.thicknessLayers_), thicknessLayers_(ptf.thicknessLayers_),
kappaLayers_(ptf.kappaLayers_) kappaLayers_(ptf.kappaLayers_),
{ relaxation_(ptf.relaxation_),
switch (mode_) qrName_(ptf.qrName_),
{ qrRelaxation_(ptf.qrRelaxation_),
case fixedPower: qrPrevious_
{ (
break; qrName_ != word::null
} ? mapper(ptf.qrPrevious_)()
case fixedHeatFlux: : scalarField()
{ )
mapper(q_, ptf.q_); {}
break;
}
case fixedHeatTransferCoeff:
{
mapper(h_, ptf.h_);
break;
}
}
if (qrName_ != "none")
{
mapper(qrPrevious_, ptf.qrPrevious_);
}
}
Foam::externalWallHeatFluxTemperatureFvPatchScalarField:: Foam::externalWallHeatFluxTemperatureFvPatchScalarField::
@ -217,18 +178,20 @@ externalWallHeatFluxTemperatureFvPatchScalarField
: :
mixedFvPatchScalarField(tppsf, iF), mixedFvPatchScalarField(tppsf, iF),
temperatureCoupledBase(patch(), tppsf), temperatureCoupledBase(patch(), tppsf),
mode_(tppsf.mode_), haveQ_(tppsf.haveQ_),
Q_(tppsf.Q_), Q_(tppsf.Q_),
haveq_(tppsf.haveq_),
q_(tppsf.q_), q_(tppsf.q_),
haveh_(tppsf.haveh_),
h_(tppsf.h_), h_(tppsf.h_),
Ta_(tppsf.Ta_, false), Ta_(tppsf.Ta_, false),
relaxation_(tppsf.relaxation_),
emissivity_(tppsf.emissivity_), emissivity_(tppsf.emissivity_),
qrPrevious_(tppsf.qrPrevious_),
qrRelaxation_(tppsf.qrRelaxation_),
qrName_(tppsf.qrName_),
thicknessLayers_(tppsf.thicknessLayers_), thicknessLayers_(tppsf.thicknessLayers_),
kappaLayers_(tppsf.kappaLayers_) kappaLayers_(tppsf.kappaLayers_),
relaxation_(tppsf.relaxation_),
qrName_(tppsf.qrName_),
qrRelaxation_(tppsf.qrRelaxation_),
qrPrevious_(tppsf.qrPrevious_)
{} {}
@ -241,27 +204,17 @@ void Foam::externalWallHeatFluxTemperatureFvPatchScalarField::autoMap
{ {
mixedFvPatchScalarField::autoMap(m); mixedFvPatchScalarField::autoMap(m);
switch (mode_) if (haveq_)
{
case fixedPower:
{
break;
}
case fixedHeatFlux:
{ {
m(q_, q_); m(q_, q_);
break;
} }
case fixedHeatTransferCoeff:
if (haveh_)
{ {
m(h_, h_); m(h_, h_);
break;
}
} }
if (qrName_ != "none") if (qrName_ != word::null)
{ {
m(qrPrevious_, qrPrevious_); m(qrPrevious_, qrPrevious_);
} }
@ -279,27 +232,17 @@ void Foam::externalWallHeatFluxTemperatureFvPatchScalarField::rmap
const externalWallHeatFluxTemperatureFvPatchScalarField& tiptf = const externalWallHeatFluxTemperatureFvPatchScalarField& tiptf =
refCast<const externalWallHeatFluxTemperatureFvPatchScalarField>(ptf); refCast<const externalWallHeatFluxTemperatureFvPatchScalarField>(ptf);
switch (mode_) if (haveq_)
{
case fixedPower:
{
break;
}
case fixedHeatFlux:
{ {
q_.rmap(tiptf.q_, addr); q_.rmap(tiptf.q_, addr);
break;
} }
case fixedHeatTransferCoeff:
if (haveh_)
{ {
h_.rmap(tiptf.h_, addr); h_.rmap(tiptf.h_, addr);
break;
}
} }
if (qrName_ != "none") if (qrName_ != word::null)
{ {
qrPrevious_.rmap(tiptf.qrPrevious_, addr); qrPrevious_.rmap(tiptf.qrPrevious_, addr);
} }
@ -319,36 +262,36 @@ void Foam::externalWallHeatFluxTemperatureFvPatchScalarField::updateCoeffs()
const scalarField valueFraction0(valueFraction()); const scalarField valueFraction0(valueFraction());
const scalarField refValue0(refValue()); const scalarField refValue0(refValue());
// Get the radiative heat flux and relax
scalarField qr(Tp.size(), 0); scalarField qr(Tp.size(), 0);
if (qrName_ != "none") if (qrName_ != word::null)
{ {
qr = qr =
qrRelaxation_ qrRelaxation_
*patch().lookupPatchField<volScalarField, scalar>(qrName_) *patch().lookupPatchField<volScalarField, scalar>(qrName_)
+ (1 - qrRelaxation_)*qrPrevious_; + (1 - qrRelaxation_)*qrPrevious_;
qrPrevious_ = qr; qrPrevious_ = qr;
} }
switch (mode_) // Compute the total non-convective heat flux
scalarField qTot(qr);
if (haveQ_)
{ {
case fixedPower: qTot += Q_;
}
if (haveq_)
{ {
refGrad() = (Q_/gSum(patch().magSf()) + qr)/kappa(*this); qTot += q_;
}
// Evaluate
if (!haveh_)
{
refGrad() = qTot/kappa(*this);
refValue() = Tp; refValue() = Tp;
valueFraction() = 0; valueFraction() = 0;
break;
} }
case fixedHeatFlux: else
{
refGrad() = (q_ + qr)/kappa(*this);
refValue() = Tp;
valueFraction() = 0;
break;
}
case fixedHeatTransferCoeff:
{ {
scalar totalSolidRes = 0; scalar totalSolidRes = 0;
if (thicknessLayers_.size()) if (thicknessLayers_.size())
@ -390,32 +333,27 @@ void Foam::externalWallHeatFluxTemperatureFvPatchScalarField::updateCoeffs()
); );
refGrad() = 0; refGrad() = 0;
forAll(Tp, i) forAll(Tp, i)
{ {
if (qr[i] < 0) if (qTot[i] < 0)
{ {
const scalar hpmqr = hp[i] - qr[i]/Tp[i]; const scalar hpmqTot = hp[i] - qTot[i]/Tp[i];
refValue()[i] = hpTa[i]/hpmqTot;
refValue()[i] = hpTa[i]/hpmqr; valueFraction()[i] = hpmqTot/(hpmqTot + kappaDeltaCoeffs[i]);
valueFraction()[i] = hpmqr/(hpmqr + kappaDeltaCoeffs[i]);
} }
else else
{ {
refValue()[i] = (hpTa[i] + qr[i])/hp[i]; refValue()[i] = (hpTa[i] + qTot[i])/hp[i];
valueFraction()[i] = hp[i]/(hp[i] + kappaDeltaCoeffs[i]); valueFraction()[i] = hp[i]/(hp[i] + kappaDeltaCoeffs[i]);
} }
} }
break;
}
} }
// Relax
valueFraction() = valueFraction() =
relaxation_*valueFraction() relaxation_*valueFraction() + (1 - relaxation_)*valueFraction0;
+ (1 - relaxation_)*valueFraction0; refValue() =
relaxation_*refValue() + (1 - relaxation_)*refValue0;
refValue() = relaxation_*refValue() + (1 - relaxation_)*refValue0;
mixedFvPatchScalarField::updateCoeffs(); mixedFvPatchScalarField::updateCoeffs();
@ -443,54 +381,45 @@ void Foam::externalWallHeatFluxTemperatureFvPatchScalarField::write
{ {
fvPatchScalarField::write(os); fvPatchScalarField::write(os);
writeEntry(os, "mode", operationModeNames[mode_]);
temperatureCoupledBase::write(os); temperatureCoupledBase::write(os);
switch (mode_) if (haveQ_)
{
case fixedPower:
{ {
writeEntry(os, "Q", Q_); writeEntry(os, "Q", Q_);
break;
} }
case fixedHeatFlux:
if (haveq_)
{ {
writeEntry(os, "q", q_); writeEntry(os, "q", q_);
break;
} }
case fixedHeatTransferCoeff:
if (haveh_)
{ {
writeEntry(os, "h", h_); writeEntry(os, "h", h_);
writeEntry(os, Ta_()); writeEntry(os, Ta_());
writeEntryIfDifferent(os, "emissivity", scalar(0), emissivity_);
writeEntryIfDifferent
(
os,
"thicknessLayers",
scalarList(),
thicknessLayers_
);
writeEntryIfDifferent
(
os,
"kappaLayers",
scalarList(),
kappaLayers_
);
}
if (relaxation_ < 1) writeEntryIfDifferent(os, "relaxation", scalar(1), relaxation_);
if (qrName_ != word::null)
{ {
writeEntry(os, "relaxation", relaxation_);
}
if (emissivity_ > 0)
{
writeEntry(os, "emissivity", emissivity_);
}
if (thicknessLayers_.size())
{
writeEntry(os, "thicknessLayers", thicknessLayers_);
writeEntry(os, "kappaLayers", kappaLayers_);
}
break;
}
}
writeEntry(os, "qr", qrName_); writeEntry(os, "qr", qrName_);
if (qrName_ != "none")
{
writeEntry(os, "qrRelaxation", qrRelaxation_); writeEntry(os, "qrRelaxation", qrRelaxation_);
writeEntry(os, "qrPrevious", qrPrevious_); writeEntry(os, "qrPrevious", qrPrevious_);
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -26,7 +26,7 @@ Class
Description Description
This boundary condition applies a heat flux condition to temperature This boundary condition applies a heat flux condition to temperature
on an external wall in one of three modes: on an external wall. Heat flux can be specified in the following ways:
- fixed power: supply Q - fixed power: supply Q
- fixed heat flux: supply q - fixed heat flux: supply q
@ -40,8 +40,11 @@ Description
Ta | Ambient temperature [K] Ta | Ambient temperature [K]
\endvartable \endvartable
For heat transfer coefficient mode optional thin thermal layer resistances If more than one parameter is given then the heat fluxes are summed.
can be specified through thicknessLayers and kappaLayers entries.
If a heat transfer coefficient is given optional thin thermal layer
resistances can be specified through thicknessLayers and kappaLayers
entries.
The thermal conductivity \c kappa can either be retrieved from various The thermal conductivity \c kappa can either be retrieved from various
possible sources, as detailed in the class temperatureCoupledBase. possible sources, as detailed in the class temperatureCoupledBase.
@ -52,11 +55,10 @@ Description
Usage Usage
\table \table
Property | Description | Required | Default value Property | Description | Required | Default value
mode | 'power', 'flux' or 'coefficient' | yes | Q | Power [W] | no | 0
Q | Power [W] | for mode 'power' | q | Heat flux [W/m^2] | no | 0
q | Heat flux [W/m^2] | for mode 'flux' | h | Heat transfer coefficient [W/m^2/K] | no | 0
h | Heat transfer coefficient [W/m^2/K] | for mode 'coefficent' | Ta | Ambient temperature [K] | if h is given |
Ta | Ambient temperature [K] | for mode 'coefficient' |
thicknessLayers | Layer thicknesses [m] | no | thicknessLayers | Layer thicknesses [m] | no |
kappaLayers | Layer thermal conductivities [W/m/K] | no | kappaLayers | Layer thermal conductivities [W/m/K] | no |
relaxation | Relaxation for the wall temperature | no | 1 relaxation | Relaxation for the wall temperature | no | 1
@ -71,8 +73,6 @@ Usage
{ {
type externalWallHeatFluxTemperature; type externalWallHeatFluxTemperature;
mode coefficient;
Ta constant 300.0; Ta constant 300.0;
h uniform 10.0; h uniform 10.0;
thicknessLayers (0.1 0.2 0.3 0.4); thicknessLayers (0.1 0.2 0.3 0.4);
@ -112,55 +112,42 @@ class externalWallHeatFluxTemperatureFvPatchScalarField
public mixedFvPatchScalarField, public mixedFvPatchScalarField,
public temperatureCoupledBase public temperatureCoupledBase
{ {
public:
// Public data
//- Operation mode enumeration
enum operationMode
{
fixedPower,
fixedHeatFlux,
fixedHeatTransferCoeff
};
static const NamedEnum<operationMode, 3> operationModeNames;
private: private:
// Private Data // Private Data
//- Operation mode // Heat power
operationMode mode_;
//- Do we have a heat power?
bool haveQ_;
//- Heat power [W] //- Heat power [W]
scalar Q_; scalar Q_;
// Heat flux
//- Do we have a heat flux?
bool haveq_;
//- Heat flux [W/m^2] //- Heat flux [W/m^2]
scalarField q_; scalarField q_;
// Heat transfer coefficient
//- Do we have a heat transfer coefficient?
bool haveh_;
//- Heat transfer coefficient [W/m^2K] //- Heat transfer coefficient [W/m^2K]
scalarField h_; scalarField h_;
//- Ambient temperature [K] //- Ambient temperature [K]
autoPtr<Function1<scalar>> Ta_; autoPtr<Function1<scalar>> Ta_;
//- Relaxation for the wall temperature (thermal inertia)
scalar relaxation_;
//- Optional surface emissivity for radiative transfer to ambient //- Optional surface emissivity for radiative transfer to ambient
scalar emissivity_; scalar emissivity_;
//- Cache qr for relaxation
scalarField qrPrevious_;
//- Relaxation for qr
scalar qrRelaxation_;
//- Name of the radiative heat flux
const word qrName_;
//- Thickness of layers //- Thickness of layers
scalarList thicknessLayers_; scalarList thicknessLayers_;
@ -168,6 +155,22 @@ private:
scalarList kappaLayers_; scalarList kappaLayers_;
//- Relaxation for the wall temperature (thermal inertia)
scalar relaxation_;
// Radiation
//- Name of the radiative heat flux
const word qrName_;
//- Relaxation for qr
scalar qrRelaxation_;
//- Cache qr for relaxation
scalarField qrPrevious_;
public: public:
//- Runtime type information //- Runtime type information

View File

@ -25,7 +25,6 @@ boundaryField
external external
{ {
type externalWallHeatFluxTemperature; type externalWallHeatFluxTemperature;
mode coefficient;
h uniform 1e3; h uniform 1e3;
Ta $internalField; Ta $internalField;
value $internalField; value $internalField;