ENH: Function1 and PatchFunction for external wall heat transfer (#1709)

- can define spatial/temporal variations for heat-flux or
  convection coefficient.

- can define temporal variations for power or ambient temperature
This commit is contained in:
Mark Olesen
2020-05-22 20:12:49 +02:00
parent 1a9f067df9
commit b68ab9bd5a
2 changed files with 135 additions and 154 deletions

View File

@ -67,10 +67,10 @@ externalWallHeatFluxTemperatureFvPatchScalarField
"undefined-alpha" "undefined-alpha"
), ),
mode_(fixedHeatFlux), mode_(fixedHeatFlux),
Q_(0), Q_(nullptr),
q_(), q_(nullptr),
h_(), h_(nullptr),
Ta_(), Ta_(nullptr),
relaxation_(1), relaxation_(1),
emissivity_(0), emissivity_(0),
qrRelaxation_(1), qrRelaxation_(1),
@ -95,14 +95,14 @@ externalWallHeatFluxTemperatureFvPatchScalarField
mixedFvPatchScalarField(p, iF), mixedFvPatchScalarField(p, iF),
temperatureCoupledBase(patch(), dict), temperatureCoupledBase(patch(), dict),
mode_(operationModeNames.get("mode", dict)), mode_(operationModeNames.get("mode", dict)),
Q_(0), Q_(nullptr),
q_(), q_(nullptr),
h_(), h_(nullptr),
Ta_(), Ta_(nullptr),
relaxation_(dict.lookupOrDefault<scalar>("relaxation", 1)), relaxation_(dict.getOrDefault<scalar>("relaxation", 1)),
emissivity_(dict.lookupOrDefault<scalar>("emissivity", 0)), emissivity_(dict.getOrDefault<scalar>("emissivity", 0)),
qrRelaxation_(dict.lookupOrDefault<scalar>("qrRelaxation", 1)), qrRelaxation_(dict.getOrDefault<scalar>("qrRelaxation", 1)),
qrName_(dict.lookupOrDefault<word>("qr", "none")), qrName_(dict.getOrDefault<word>("qr", "none")),
thicknessLayers_(), thicknessLayers_(),
kappaLayers_() kappaLayers_()
{ {
@ -110,19 +110,17 @@ externalWallHeatFluxTemperatureFvPatchScalarField
{ {
case fixedPower: case fixedPower:
{ {
dict.readEntry("Q", Q_); Q_ = Function1<scalar>::New("Q", dict);
break; break;
} }
case fixedHeatFlux: case fixedHeatFlux:
{ {
q_ = scalarField("q", dict, p.size()); q_ = PatchFunction1<scalar>::New(patch().patch(), "q", dict);
break; break;
} }
case fixedHeatTransferCoeff: case fixedHeatTransferCoeff:
{ {
h_ = scalarField("h", dict, p.size()); h_ = PatchFunction1<scalar>::New(patch().patch(), "h", dict);
Ta_ = Function1<scalar>::New("Ta", dict); Ta_ = Function1<scalar>::New("Ta", dict);
if (dict.readIfPresent("thicknessLayers", thicknessLayers_)) if (dict.readIfPresent("thicknessLayers", thicknessLayers_))
@ -155,7 +153,7 @@ externalWallHeatFluxTemperatureFvPatchScalarField
} }
else else
{ {
qrPrevious_.setSize(p.size(), 0); qrPrevious_.resize(p.size(), Zero);
} }
} }
@ -179,53 +177,31 @@ externalWallHeatFluxTemperatureFvPatchScalarField
Foam::externalWallHeatFluxTemperatureFvPatchScalarField:: Foam::externalWallHeatFluxTemperatureFvPatchScalarField::
externalWallHeatFluxTemperatureFvPatchScalarField externalWallHeatFluxTemperatureFvPatchScalarField
( (
const externalWallHeatFluxTemperatureFvPatchScalarField& ptf, const externalWallHeatFluxTemperatureFvPatchScalarField& rhs,
const fvPatch& p, const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF, const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper const fvPatchFieldMapper& mapper
) )
: :
mixedFvPatchScalarField(ptf, p, iF, mapper), mixedFvPatchScalarField(rhs, p, iF, mapper),
temperatureCoupledBase(patch(), ptf), temperatureCoupledBase(patch(), rhs),
mode_(ptf.mode_), mode_(rhs.mode_),
Q_(ptf.Q_), Q_(rhs.Q_.clone()),
q_(), q_(rhs.q_.clone(patch().patch())),
h_(), h_(rhs.h_.clone(patch().patch())),
Ta_(ptf.Ta_.clone()), Ta_(rhs.Ta_.clone()),
relaxation_(ptf.relaxation_), relaxation_(rhs.relaxation_),
emissivity_(ptf.emissivity_), emissivity_(rhs.emissivity_),
qrPrevious_(), qrPrevious_(),
qrRelaxation_(ptf.qrRelaxation_), qrRelaxation_(rhs.qrRelaxation_),
qrName_(ptf.qrName_), qrName_(rhs.qrName_),
thicknessLayers_(ptf.thicknessLayers_), thicknessLayers_(rhs.thicknessLayers_),
kappaLayers_(ptf.kappaLayers_) kappaLayers_(rhs.kappaLayers_)
{ {
switch (mode_)
{
case fixedPower:
{
break;
}
case fixedHeatFlux:
{
q_.setSize(mapper.size());
q_.map(ptf.q_, mapper);
break;
}
case fixedHeatTransferCoeff:
{
h_.setSize(mapper.size());
h_.map(ptf.h_, mapper);
break;
}
}
if (qrName_ != "none") if (qrName_ != "none")
{ {
qrPrevious_.setSize(mapper.size()); qrPrevious_.resize(mapper.size());
qrPrevious_.map(ptf.qrPrevious_, mapper); qrPrevious_.map(rhs.qrPrevious_, mapper);
} }
} }
@ -233,47 +209,47 @@ externalWallHeatFluxTemperatureFvPatchScalarField
Foam::externalWallHeatFluxTemperatureFvPatchScalarField:: Foam::externalWallHeatFluxTemperatureFvPatchScalarField::
externalWallHeatFluxTemperatureFvPatchScalarField externalWallHeatFluxTemperatureFvPatchScalarField
( (
const externalWallHeatFluxTemperatureFvPatchScalarField& ewhftpsf const externalWallHeatFluxTemperatureFvPatchScalarField& rhs
) )
: :
mixedFvPatchScalarField(ewhftpsf), mixedFvPatchScalarField(rhs),
temperatureCoupledBase(ewhftpsf), temperatureCoupledBase(rhs),
mode_(ewhftpsf.mode_), mode_(rhs.mode_),
Q_(ewhftpsf.Q_), Q_(rhs.Q_.clone()),
q_(ewhftpsf.q_), q_(rhs.q_.clone(patch().patch())),
h_(ewhftpsf.h_), h_(rhs.h_.clone(patch().patch())),
Ta_(ewhftpsf.Ta_.clone()), Ta_(rhs.Ta_.clone()),
relaxation_(ewhftpsf.relaxation_), relaxation_(rhs.relaxation_),
emissivity_(ewhftpsf.emissivity_), emissivity_(rhs.emissivity_),
qrPrevious_(ewhftpsf.qrPrevious_), qrPrevious_(rhs.qrPrevious_),
qrRelaxation_(ewhftpsf.qrRelaxation_), qrRelaxation_(rhs.qrRelaxation_),
qrName_(ewhftpsf.qrName_), qrName_(rhs.qrName_),
thicknessLayers_(ewhftpsf.thicknessLayers_), thicknessLayers_(rhs.thicknessLayers_),
kappaLayers_(ewhftpsf.kappaLayers_) kappaLayers_(rhs.kappaLayers_)
{} {}
Foam::externalWallHeatFluxTemperatureFvPatchScalarField:: Foam::externalWallHeatFluxTemperatureFvPatchScalarField::
externalWallHeatFluxTemperatureFvPatchScalarField externalWallHeatFluxTemperatureFvPatchScalarField
( (
const externalWallHeatFluxTemperatureFvPatchScalarField& ewhftpsf, const externalWallHeatFluxTemperatureFvPatchScalarField& rhs,
const DimensionedField<scalar, volMesh>& iF const DimensionedField<scalar, volMesh>& iF
) )
: :
mixedFvPatchScalarField(ewhftpsf, iF), mixedFvPatchScalarField(rhs, iF),
temperatureCoupledBase(patch(), ewhftpsf), temperatureCoupledBase(patch(), rhs),
mode_(ewhftpsf.mode_), mode_(rhs.mode_),
Q_(ewhftpsf.Q_), Q_(rhs.Q_.clone()),
q_(ewhftpsf.q_), q_(rhs.q_.clone(patch().patch())),
h_(ewhftpsf.h_), h_(rhs.h_.clone(patch().patch())),
Ta_(ewhftpsf.Ta_.clone()), Ta_(rhs.Ta_.clone()),
relaxation_(ewhftpsf.relaxation_), relaxation_(rhs.relaxation_),
emissivity_(ewhftpsf.emissivity_), emissivity_(rhs.emissivity_),
qrPrevious_(ewhftpsf.qrPrevious_), qrPrevious_(rhs.qrPrevious_),
qrRelaxation_(ewhftpsf.qrRelaxation_), qrRelaxation_(rhs.qrRelaxation_),
qrName_(ewhftpsf.qrName_), qrName_(rhs.qrName_),
thicknessLayers_(ewhftpsf.thicknessLayers_), thicknessLayers_(rhs.thicknessLayers_),
kappaLayers_(ewhftpsf.kappaLayers_) kappaLayers_(rhs.kappaLayers_)
{} {}
@ -281,34 +257,23 @@ externalWallHeatFluxTemperatureFvPatchScalarField
void Foam::externalWallHeatFluxTemperatureFvPatchScalarField::autoMap void Foam::externalWallHeatFluxTemperatureFvPatchScalarField::autoMap
( (
const fvPatchFieldMapper& m const fvPatchFieldMapper& mapper
) )
{ {
mixedFvPatchScalarField::autoMap(m); mixedFvPatchScalarField::autoMap(mapper);
switch (mode_) if (q_)
{ {
case fixedPower: q_->autoMap(mapper);
{ }
break; if (h_)
} {
case fixedHeatFlux: h_->autoMap(mapper);
{
q_.autoMap(m);
break;
}
case fixedHeatTransferCoeff:
{
h_.autoMap(m);
break;
}
} }
if (qrName_ != "none") if (qrName_ != "none")
{ {
qrPrevious_.autoMap(m); qrPrevious_.autoMap(mapper);
} }
} }
@ -321,32 +286,21 @@ void Foam::externalWallHeatFluxTemperatureFvPatchScalarField::rmap
{ {
mixedFvPatchScalarField::rmap(ptf, addr); mixedFvPatchScalarField::rmap(ptf, addr);
const externalWallHeatFluxTemperatureFvPatchScalarField& ewhftpsf = const auto& rhs =
refCast<const externalWallHeatFluxTemperatureFvPatchScalarField>(ptf); refCast<const externalWallHeatFluxTemperatureFvPatchScalarField>(ptf);
switch (mode_) if (q_)
{ {
case fixedPower: q_->rmap(rhs.q_(), addr);
{ }
break; if (h_)
} {
case fixedHeatFlux: h_->rmap(rhs.h_(), addr);
{
q_.rmap(ewhftpsf.q_, addr);
break;
}
case fixedHeatTransferCoeff:
{
h_.rmap(ewhftpsf.h_, addr);
break;
}
} }
if (qrName_ != "none") if (qrName_ != "none")
{ {
qrPrevious_.rmap(ewhftpsf.qrPrevious_, addr); qrPrevious_.rmap(rhs.qrPrevious_, addr);
} }
} }
@ -378,7 +332,10 @@ void Foam::externalWallHeatFluxTemperatureFvPatchScalarField::updateCoeffs()
{ {
case fixedPower: case fixedPower:
{ {
refGrad() = (Q_/gSum(patch().magSf()) + qr)/kappa(Tp); const scalar heatPower =
Q_->value(this->db().time().timeOutputValue());
refGrad() = (heatPower/gSum(patch().magSf()) + qr)/kappa(Tp);
refValue() = 0; refValue() = 0;
valueFraction() = 0; valueFraction() = 0;
@ -386,7 +343,10 @@ void Foam::externalWallHeatFluxTemperatureFvPatchScalarField::updateCoeffs()
} }
case fixedHeatFlux: case fixedHeatFlux:
{ {
refGrad() = (q_ + qr)/kappa(Tp); tmp<scalarField> heatFlux =
q_->value(this->db().time().timeOutputValue());
refGrad() = (heatFlux + qr)/kappa(Tp);
refValue() = 0; refValue() = 0;
valueFraction() = 0; valueFraction() = 0;
@ -394,6 +354,12 @@ void Foam::externalWallHeatFluxTemperatureFvPatchScalarField::updateCoeffs()
} }
case fixedHeatTransferCoeff: case fixedHeatTransferCoeff:
{ {
tmp<scalarField> thtcCoeff =
(
h_->value(this->db().time().timeOutputValue()) + VSMALL
);
const auto& htcCoeff = thtcCoeff();
scalar totalSolidRes = 0; scalar totalSolidRes = 0;
if (thicknessLayers_.size()) if (thicknessLayers_.size())
{ {
@ -406,9 +372,11 @@ void Foam::externalWallHeatFluxTemperatureFvPatchScalarField::updateCoeffs()
} }
} }
} }
scalarField hp(1/(1/h_ + totalSolidRes)); scalarField hp(1/(1/htcCoeff + totalSolidRes));
const scalar Ta =
Ta_->value(this->db().time().timeOutputValue());
const scalar Ta = Ta_->value(this->db().time().timeOutputValue());
scalarField hpTa(hp*Ta); scalarField hpTa(hp*Ta);
if (emissivity_ > 0) if (emissivity_ > 0)
@ -419,7 +387,7 @@ void Foam::externalWallHeatFluxTemperatureFvPatchScalarField::updateCoeffs()
{ {
// ... including the effect of the solid wall thermal // ... including the effect of the solid wall thermal
// resistance // resistance
scalarField TpLambda(h_/(h_ + 1/totalSolidRes)); scalarField TpLambda(htcCoeff/(htcCoeff + 1/totalSolidRes));
scalarField Ts(TpLambda*Tp + (1 - TpLambda)*Ta); scalarField Ts(TpLambda*Tp + (1 - TpLambda)*Ta);
scalarField lambdaTa4(pow4((1 - TpLambda)*Ta)); scalarField lambdaTa4(pow4((1 - TpLambda)*Ta));
@ -489,24 +457,27 @@ void Foam::externalWallHeatFluxTemperatureFvPatchScalarField::write
os.writeEntry("mode", operationModeNames[mode_]); os.writeEntry("mode", operationModeNames[mode_]);
temperatureCoupledBase::write(os); temperatureCoupledBase::write(os);
if (Q_)
{
Q_->writeData(os);
}
if (q_)
{
q_->writeData(os);
}
if (h_)
{
h_->writeData(os);
}
if (Ta_)
{
Ta_->writeData(os);
}
switch (mode_) switch (mode_)
{ {
case fixedPower:
{
os.writeEntry("Q", Q_);
break;
}
case fixedHeatFlux:
{
q_.writeEntry("q", os);
break;
}
case fixedHeatTransferCoeff: case fixedHeatTransferCoeff:
{ {
h_.writeEntry("h", os);
Ta_->writeData(os);
if (relaxation_ < 1) if (relaxation_ < 1)
{ {
os.writeEntry("relaxation", relaxation_); os.writeEntry("relaxation", relaxation_);
@ -525,6 +496,9 @@ void Foam::externalWallHeatFluxTemperatureFvPatchScalarField::write
break; break;
} }
default:
break;
} }
os.writeEntry("qr", qrName_); os.writeEntry("qr", qrName_);

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -81,7 +82,7 @@ Usage
mode coefficient; mode coefficient;
Ta constant 300.0; Ta constant 300.0;
h uniform 10.0; h constant 10.0;
thicknessLayers (0.1 0.2 0.3 0.4); thicknessLayers (0.1 0.2 0.3 0.4);
kappaLayers (1 2 3 4); kappaLayers (1 2 3 4);
@ -91,6 +92,12 @@ Usage
} }
\endverbatim \endverbatim
Note
Quantities that are considered "global" (eg, power, ambient temperature)
can be specified as Function1 types.
Quantities that may have local variations (eg, htc, heat-flux)
can be specified as PatchFunction1 types.
See also See also
Foam::temperatureCoupledBase Foam::temperatureCoupledBase
Foam::mixedFvPatchScalarField Foam::mixedFvPatchScalarField
@ -105,7 +112,7 @@ SourceFiles
#include "mixedFvPatchFields.H" #include "mixedFvPatchFields.H"
#include "temperatureCoupledBase.H" #include "temperatureCoupledBase.H"
#include "Function1.H" #include "PatchFunction1.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -123,14 +130,14 @@ class externalWallHeatFluxTemperatureFvPatchScalarField
{ {
public: public:
// Public data // Public Data
//- Operation mode enumeration //- Operation mode enumeration
enum operationMode enum operationMode
{ {
fixedPower, //!< Fixed heat power [W] fixedPower, //!< Heat power [W]
fixedHeatFlux, //!< Fixed heat flux [W/m2] fixedHeatFlux, //!< Heat flux [W/m2]
fixedHeatTransferCoeff, //!< Fixed heat transfer coefficient fixedHeatTransferCoeff, //!< Heat transfer coefficient [W/m^2/K]
}; };
static const Enum<operationMode> operationModeNames; static const Enum<operationMode> operationModeNames;
@ -138,19 +145,19 @@ public:
private: private:
// Private data // Private Data
//- Operation mode //- Operation mode
operationMode mode_; operationMode mode_;
//- Heat power [W] //- Heat power [W]
scalar Q_; autoPtr<Function1<scalar>> Q_;
//- Heat flux [W/m2] //- Heat flux [W/m2]
scalarField q_; autoPtr<PatchFunction1<scalar>> q_;
//- Heat transfer coefficient [W/m2K] //- Heat transfer coefficient [W/m2K]
scalarField h_; autoPtr<PatchFunction1<scalar>> h_;
//- Ambient temperature [K] //- Ambient temperature [K]
autoPtr<Function1<scalar>> Ta_; autoPtr<Function1<scalar>> Ta_;