diff --git a/src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.C b/src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.C index 0b32cd176dce38a9b1464e5de952700884d5aaed..ae487be30a1bcebbc082e661025d15a9313edc77 100644 --- a/src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.C +++ b/src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.C @@ -75,7 +75,7 @@ void Foam::fv::effectivenessHeatExchangerSource::initialise() label count = 0; forAll(fZone, i) { - label facei = fZone[i]; + const label facei = fZone[i]; label faceId = -1; label facePatchId = -1; if (mesh_.isInternalFace(facei)) @@ -156,8 +156,8 @@ Foam::fv::effectivenessHeatExchangerSource::effectivenessHeatExchangerSource : fv::cellSetOption(name, modelType, dict, mesh), writeFile(mesh, name, modelType, coeffs_), - secondaryMassFlowRate_(0), - secondaryInletT_(0), + userPrimaryInletT_(false), + targetQdotActive_(false), secondaryCpPtr_ ( Function1<scalar>::NewIfPresent @@ -168,13 +168,13 @@ Foam::fv::effectivenessHeatExchangerSource::effectivenessHeatExchangerSource &mesh ) ), + eTable_(), + targetQdotCalcInterval_(5), + secondaryMassFlowRate_(0), + secondaryInletT_(0), primaryInletT_(0), - userPrimaryInletT_(false), - targetQdotActive_(false), targetQdot_(0), - targetQdotCalcInterval_(5), targetQdotRelax_(0.5), - eTable_(), UName_("U"), TName_("T"), phiName_("phi"), @@ -212,12 +212,10 @@ void Foam::fv::effectivenessHeatExchangerSource::addSup ) { const auto& thermo = mesh_.lookupObject<basicThermo>(basicThermo::dictName); - - const surfaceScalarField Cpf(fvc::interpolate(thermo.Cp())); - const auto& phi = mesh_.lookupObject<surfaceScalarField>(phiName_); - const auto& T = mesh_.lookupObject<volScalarField>(TName_); + + const surfaceScalarField Cpf(fvc::interpolate(thermo.Cp())); const surfaceScalarField Tf(fvc::interpolate(T)); scalar sumPhi = 0; @@ -226,29 +224,30 @@ void Foam::fv::effectivenessHeatExchangerSource::addSup scalar primaryInletTfMean = 0; forAll(faceId_, i) { - label facei = faceId_[i]; + const label facei = faceId_[i]; if (facePatchId_[i] != -1) { - label patchi = facePatchId_[i]; - scalar phii = phi.boundaryField()[patchi][facei]*faceSign_[i]; + const label patchi = facePatchId_[i]; + const scalar phii = phi.boundaryField()[patchi][facei]*faceSign_[i]; + const scalar magPhii = mag(phii); sumPhi += phii; + sumMagPhi += magPhii; - scalar Cpfi = Cpf.boundaryField()[patchi][facei]; - scalar Tfi = Tf.boundaryField()[patchi][facei]; - scalar magPhii = mag(phii); + const scalar Cpfi = Cpf.boundaryField()[patchi][facei]; + const scalar Tfi = Tf.boundaryField()[patchi][facei]; - sumMagPhi += magPhii; CpfMean += Cpfi*magPhii; primaryInletTfMean += Tfi*magPhii; } else { - scalar phii = phi[facei]*faceSign_[i]; - scalar magPhii = mag(phii); + const scalar phii = phi[facei]*faceSign_[i]; + const scalar magPhii = mag(phii); sumPhi += phii; sumMagPhi += magPhii; + CpfMean += Cpf[facei]*magPhii; primaryInletTfMean += Tf[facei]*magPhii; } @@ -265,9 +264,9 @@ void Foam::fv::effectivenessHeatExchangerSource::addSup primaryInletT = primaryInletTfMean/(sumMagPhi + ROOTVSMALL); } - const scalar alpha = - eTable_()(mag(sumPhi), secondaryMassFlowRate_) - *CpfMean*mag(sumPhi); + const scalar effectiveness = eTable_()(mag(sumPhi), secondaryMassFlowRate_); + + const scalar alpha = effectiveness*CpfMean*mag(sumPhi); const scalar Qt = alpha*(secondaryInletT_ - primaryInletT); @@ -277,7 +276,7 @@ void Foam::fv::effectivenessHeatExchangerSource::addSup && (mesh_.time().timeIndex() % targetQdotCalcInterval_ == 0) ) { - scalar dT = (targetQdot_ - Qt)/(alpha + ROOTVSMALL); + const scalar dT = (targetQdot_ - Qt)/(alpha + ROOTVSMALL); secondaryInletT_ += targetQdotRelax_*dT; } @@ -289,7 +288,7 @@ void Foam::fv::effectivenessHeatExchangerSource::addSup Tref = gMax(TCells); forAll(deltaTCells, i) { - deltaTCells[i] = max(Tref - TCells[i], 0.0); + deltaTCells[i] = max(Tref - TCells[i], scalar(0)); } } else @@ -297,7 +296,7 @@ void Foam::fv::effectivenessHeatExchangerSource::addSup Tref = gMin(TCells); forAll(deltaTCells, i) { - deltaTCells[i] = max(TCells[i] - Tref, 0.0); + deltaTCells[i] = max(TCells[i] - Tref, scalar(0)); } } @@ -307,7 +306,7 @@ void Foam::fv::effectivenessHeatExchangerSource::addSup scalar sumWeight = 0; forAll(cells_, i) { - label celli = cells_[i]; + const label celli = cells_[i]; sumWeight += V[celli]*mag(U[celli])*deltaTCells[i]; } reduce(sumWeight, sumOp<scalar>()); @@ -318,21 +317,21 @@ void Foam::fv::effectivenessHeatExchangerSource::addSup forAll(cells_, i) { - label celli = cells_[i]; + const label celli = cells_[i]; heSource[celli] -= Qt*V[celli]*mag(U[celli])*deltaTCells[i] /(sumWeight + ROOTVSMALL); } } - Info<< nl + Log << nl << type() << ": " << name() << nl << incrIndent - << indent << "Net mass flux [Kg/s] : " << sumPhi << nl + << indent << "Net mass flux [kg/s] : " << sumPhi << nl << indent << "Total heat exchange [W] : " << Qt << nl << indent << "Secondary inlet T [K] : " << secondaryInletT_ << nl << indent << "Tref [K] : " << Tref << nl - << indent << "Effectiveness : " - << eTable_()(mag(sumPhi), secondaryMassFlowRate_) << decrIndent; + << indent << "Effectiveness : " << effectiveness + << decrIndent; if (Pstream::master()) { @@ -343,7 +342,7 @@ void Foam::fv::effectivenessHeatExchangerSource::addSup << tab << Qt << tab << secondaryInletT_ << tab << Tref - << tab << eTable_()(mag(sumPhi), secondaryMassFlowRate_); + << tab << effectiveness; if (secondaryCpPtr_) { @@ -352,7 +351,7 @@ void Foam::fv::effectivenessHeatExchangerSource::addSup const scalar secondaryOutletT = Qt/(secondaryMassFlowRate_*secondaryCp) + secondaryInletT_; - Info<< nl << incrIndent << indent + Log << nl << incrIndent << indent << "Secondary outlet T [K] : " << secondaryOutletT << decrIndent; @@ -367,55 +366,55 @@ void Foam::fv::effectivenessHeatExchangerSource::addSup bool Foam::fv::effectivenessHeatExchangerSource::read(const dictionary& dict) { - if (fv::cellSetOption::read(dict) && writeFile::read(dict)) + if (!(fv::cellSetOption::read(dict) && writeFile::read(dict))) { - UName_ = coeffs_.getOrDefault<word>("U", "U"); - TName_ = coeffs_.getOrDefault<word>("T", "T"); - phiName_ = coeffs_.getOrDefault<word>("phi", "phi"); - coeffs_.readEntry("faceZone", faceZoneName_); - - coeffs_.readEntry("secondaryMassFlowRate", secondaryMassFlowRate_); - coeffs_.readEntry("secondaryInletT", secondaryInletT_); + return false; + } - if (coeffs_.readIfPresent("primaryInletT", primaryInletT_)) - { - userPrimaryInletT_ = true; - Info<< type() << " " << this->name() << ": " << indent << nl - << "employing user-specified primary flow inlet temperature: " - << primaryInletT_ << endl; - } - else - { - Info<< type() << " " << this->name() << ": " << indent << nl - << "employing flux-weighted primary flow inlet temperature" - << endl; - } + coeffs_.readEntry("secondaryMassFlowRate", secondaryMassFlowRate_); + coeffs_.readEntry("secondaryInletT", secondaryInletT_); - if (coeffs_.readIfPresent("targetQdot", targetQdot_)) - { - targetQdotActive_ = true; - Info<< indent << "employing target heat rejection of " - << targetQdot_ << nl; + if (coeffs_.readIfPresent("primaryInletT", primaryInletT_)) + { + userPrimaryInletT_ = true; + Info<< type() << " " << this->name() << ": " << indent << nl + << "employing user-specified primary flow inlet temperature: " + << primaryInletT_ << endl; + } + else + { + Info<< type() << " " << this->name() << ": " << indent << nl + << "employing flux-weighted primary flow inlet temperature" + << endl; + } - coeffs_.readIfPresent - ( - "targetQdotCalcInterval", - targetQdotCalcInterval_ - ); + if (coeffs_.readIfPresent("targetQdot", targetQdot_)) + { + targetQdotActive_ = true; + Info<< indent << "employing target heat rejection of " + << targetQdot_ << nl; - Info<< indent << "updating secondary inlet temperature every " - << targetQdotCalcInterval_ << " iterations" << nl; + coeffs_.readIfPresent + ( + "targetQdotCalcInterval", + targetQdotCalcInterval_ + ); - coeffs_.readIfPresent("targetQdotRelax", targetQdotRelax_); + Info<< indent << "updating secondary inlet temperature every " + << targetQdotCalcInterval_ << " iterations" << nl; - Info<< indent << "temperature relaxation: " - << targetQdotRelax_ << endl; - } + coeffs_.readIfPresent("targetQdotRelax", targetQdotRelax_); - return true; + Info<< indent << "temperature relaxation: " + << targetQdotRelax_ << endl; } - return false; + UName_ = coeffs_.getOrDefault<word>("U", "U"); + TName_ = coeffs_.getOrDefault<word>("T", "T"); + phiName_ = coeffs_.getOrDefault<word>("phi", "phi"); + coeffs_.readEntry("faceZone", faceZoneName_); + + return true; } diff --git a/src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.H b/src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.H index ccc47f4994e4472e90bc32adcbbd3dbeeb765950..b443e751e657431005258ed5d617e7e3f0f8f8d1 100644 --- a/src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.H +++ b/src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2013-2017 OpenFOAM Foundation - Copyright (C) 2016-2020 OpenCFD Ltd. + Copyright (C) 2016-2022 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -31,8 +31,8 @@ Group grpFvOptionsSources Description - Heat exchanger source model for compressible flows, in which the heat - exchanger is defined as an energy source using a selection of cells. + Heat exchanger source model for compressible flows, where the heat + exchanger is modelled as an energy source using a selection of cells. The total heat exchange source is given by: \f[ @@ -41,13 +41,13 @@ Description where: \vartable - Q_t | total heat source - e(\phi,\dot{m}_2) | effectivenes table - \phi | net mass flux entering heat exchanger [kg/s] - \dot{m}_2 | secondary mass flow rate [kg/s] - T_1 | primary inlet temperature [K] - T_2 | secondary inlet temperature [K] - c_p | specific heat capacity [J/kg/K] + Q_t | Total heat exchange source [J/s] + e(\phi,\dot{m}_2) | Effectivenes table [-] + \phi | Net mass flux entering heat exchanger [kg/s] + \dot{m}_2 | Secondary flow mass flow rate [kg/s] + T_1 | Primary flow inlet temperature [K] + T_2 | Secondary flow inlet temperature [K] + c_p | Primary flow specific heat capacity [J/kg/K] \endvartable @@ -58,11 +58,11 @@ Description where: \vartable - Q_c | source for cell - V_c | volume of the cell [m3] - U_c | local cell velocity [m/s] - T_c | local call temperature [K] - T_{ref} | min or max(T) in cell zone depending on the sign of Q_t [K] + Q_c | Source for cell + V_c | Volume of the cell [m3] + U_c | Local cell velocity [m/s] + T_c | Local cell temperature [K] + T_{ref} | Min or max(T) in cell zone depending on the sign of Qt [K] \endvartable Sources applied to either of the below, if exist: @@ -83,63 +83,69 @@ Usage \verbatim effectivenessHeatExchangerSource1 { - // Mandatory entries (unmodifiable) - type effectivenessHeatExchangerSource; - - // Mandatory entries (runtime modifiable) + // Mandatory entries + type effectivenessHeatExchangerSource; faceZone <faceZoneName>; - secondaryMassFlowRate 1.0; - secondaryInletT 336; - + secondaryMassFlowRate <scalar>; + secondaryInletT <scalar>; + file "effectivenessTable"; outOfBounds clamp; - file "effTable"; - // Optional entries (runtime modifiable) - primaryInletT 293; - targetQdot 1500; - U <Uname>; - T <Tname>; - phi <phiName>; + // Optional entries + U <word>; + T <word>; + phi <word>; + + // Conditional optional entries + + // when the total heat exchange is calculated with primary inlet T + primaryInletT <scalar>; - // Conditional optional entries (runtime modifiable) + // when the total heat exchange is calculated with a given target + targetQdot <scalar>; + targetQdotCalcInterval <label>; + targetQdotRelax <scalar>; - // when the entry "targetQdot" is present - targetQdotCalcInterval 1; - targetQdotRelax 1.0; + // when secondary outlet temperature is requested + secondaryCp <Function1<scalar>>; - // Mandatory/Optional (inherited) entries + // Inherited entries ... } \endverbatim where the entries mean: \table - Property | Description | Type | Reqd | Dflt + Property | Description | Type | Reqd | Deflt type | Type name: effectivenessHeatExchangerSource <!-- --> | word | yes | - secondaryMassFlowRate | Secondary flow mass rate [kg/s] <!-- --> | scalar | yes | - - secondaryInletT | Inlet secondary temperature [K] <!-- + secondaryInletT | Secondary flow inlet temperature [K] <!-- --> | scalar | yes | - - faceZone | Name of the faceZone at the heat exchange inlet <!-- + faceZone | Name of the faceZone at the heat exchanger inlet <!-- --> | word | yes | - - file | 2D look up table efficiency = function of primary <!-- + file | 2D effectiveness table = function of primary <!-- --> and secondary mass flow rates [kg/s] | file | yes | - - primaryInletT | Primary air temperature at the heat exchanger inlet <!-- + primaryInletT | Primary flow temperature at the heat exchanger inlet <!-- --> | scalar | no | - targetQdot | Target heat rejection | scalar | no | - targetQdotCalcInterval | Target heat rejection calculation interval <!-- --> | label | no | - targetQdotRelax | Target heat rejection temperature <!-- --> under-relaxation coefficient | scalar | no | - - U | Name of operand velocity field | word | no | U - T | Name of operand temperature field | word | no | T - phi | Name of operand flux field | word | no | phi + secondaryCp | Secondary flow specific heat capacity <!-- + --> | Function1\<scalar\> | no | - + U | Name of operand velocity field | word | no | U + T | Name of operand temperature field | word | no | T + phi | Name of operand flux field | word | no | phi \endtable The inherited entries are elaborated in: - - \link fvOption.H \endlink - - \link cellSetOption.H \endlink + - \link fvOption.H \endlink + - \link cellSetOption.H \endlink + - \link writeFile.H \endlink + - \link Function1.H \endlink The effectiveness table is described in terms of the primary and secondary mass flow rates. For example, the table: @@ -185,13 +191,15 @@ Usage \endverbatim Note + - Primary flow indicates the CFD flow region and + secondary flow the non-CFD-model region. - The table with name \c file should have the same units as the - secondary mass flow rate and kg/s for \c phi. + secondary mass flow rate and kg/s for \c phi. - \c faceZone is the faces at the inlet of the \c cellZone, it needs to be - created with flip map flags. It is used to integrate the net mass flow - rate into the heat exchanger. + created with flip map flags. It is used to integrate the net mass flow + rate into the heat exchanger. - \c primaryInletT sets the primary inlet temperature. If not set, the - flux-averaged temperature is used. + flux-averaged temperature is used. SourceFiles effectivenessHeatExchangerSource.C @@ -223,73 +231,66 @@ class effectivenessHeatExchangerSource public fv::cellSetOption, public functionObjects::writeFile { -protected: + // Private Data + + //- Flag to use a user-specified primary flow inlet temperature + bool userPrimaryInletT_; + + //- Flag to use target heat rejection + bool targetQdotActive_; + + //- Secondary flow specific heat capacity [J/kg/K] + autoPtr<Function1<scalar>> secondaryCpPtr_; + + //- 2D effectiveness table = function of primary and secondary + //- mass flow rates [kg/s] + autoPtr<interpolation2DTable<scalar>> eTable_; - // Protected Data + //- Target heat rejection calculation interval + label targetQdotCalcInterval_; //- Secondary flow mass rate [kg/s] scalar secondaryMassFlowRate_; - //- Inlet secondary temperature [K] + //- Secondary flow inlet temperature [K] scalar secondaryInletT_; - //- Secondary specific heat capacity [J/kg/K] - autoPtr<Function1<scalar>> secondaryCpPtr_; - - //- Primary air temperature at the heat exchanger inlet [K] + //- Primary flow temperature at the heat exchanger inlet [K] scalar primaryInletT_; - //- Flag to use a user-specified primary inlet temperature - bool userPrimaryInletT_; - - //- Flag to use target heat rejection - bool targetQdotActive_; - //- Target heat rejection scalar targetQdot_; - //- Target heat rejection calculation interval - label targetQdotCalcInterval_; - //- Target heat rejection temperature under-relaxation coefficient scalar targetQdotRelax_; - //- 2D look up table efficiency = function of primary and secondary - //- mass flow rates [kg/s] - autoPtr<interpolation2DTable<scalar>> eTable_; - - //- Name of velocity field; default = U + //- Name of operand velocity field word UName_; - //- Name of temperature field; default = T + //- Name of operand temperature field word TName_; - //- Name of the flux + //- Name of operand flux field word phiName_; - //- Name of the faceZone at the heat exchange inlet + //- Name of the faceZone at the heat exchanger inlet word faceZoneName_; - //- Local list of face IDs + //- Local list of face IDs labelList faceId_; - //- Local list of patch ID per face + //- Local list of patch IDs per face labelList facePatchId_; //- List of +1/-1 representing face flip map (1 use as is, -1 negate) labelList faceSign_; -private: - // Private Member Functions //- Initialise heat exchanger source model void initialise(); - //- Calculate total area of faceZone across processors - void calculateTotalArea(scalar& area); - //- Output file header information virtual void writeFileHeader(Ostream& os); @@ -347,7 +348,7 @@ public: ); - // IO + // I-O //- Read dictionary virtual bool read(const dictionary& dict);