diff --git a/src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.C b/src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.C index 210168f72a..5363103512 100644 --- a/src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.C +++ b/src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -142,6 +142,10 @@ Foam::fv::effectivenessHeatExchangerSource::effectivenessHeatExchangerSource secondaryInletT_(0), primaryInletT_(0), userPrimaryInletT_(false), + targetQdotActive_(false), + targetQdot_(0), + targetQdotCalcInterval_(5), + targetQdotRelax_(0.5), eTable_(), UName_("U"), TName_("T"), @@ -225,48 +229,52 @@ void Foam::fv::effectivenessHeatExchangerSource::addSup reduce(CpfMean, sumOp()); reduce(sumPhi, sumOp()); reduce(sumMagPhi, sumOp()); - reduce(primaryInletTfMean, sumOp()); - - primaryInletTfMean /= sumMagPhi + ROOTVSMALL; CpfMean /= sumMagPhi + ROOTVSMALL; scalar primaryInletT = primaryInletT_; if (!userPrimaryInletT_) { - primaryInletT = primaryInletTfMean; + reduce(primaryInletTfMean, sumOp()); + primaryInletT = primaryInletTfMean/(sumMagPhi + ROOTVSMALL); } - scalar Qt = + const scalar alpha = eTable_()(mag(sumPhi), secondaryMassFlowRate_) - *(secondaryInletT_ - primaryInletT) *CpfMean*mag(sumPhi); + const scalar Qt = alpha*(secondaryInletT_ - primaryInletT); + + if + ( + targetQdotActive_ + && (mesh_.time().timeIndex() % targetQdotCalcInterval_ == 0) + ) + { + scalar dT = (targetQdot_ - Qt)/(alpha + ROOTVSMALL); + secondaryInletT_ += targetQdotRelax_*dT; + } + const scalarField TCells(T, cells_); scalar Tref = 0; + scalarField deltaTCells(cells_.size(), 0); if (Qt > 0) { - Tref = max(TCells); - reduce(Tref, maxOp()); - } - else - { - Tref = min(TCells); - reduce(Tref, minOp()); - } - - scalarField deltaTCells(cells_.size(), 0); - forAll(deltaTCells, i) - { - if (Qt > 0) + Tref = gMax(TCells); + forAll(deltaTCells, i) { deltaTCells[i] = max(Tref - TCells[i], 0.0); } - else + } + else + { + Tref = gMin(TCells); + forAll(deltaTCells, i) { deltaTCells[i] = max(TCells[i] - Tref, 0.0); } } + const volVectorField& U = mesh_.lookupObject(UName_); const scalarField& V = mesh_.V(); scalar sumWeight = 0; @@ -293,6 +301,7 @@ void Foam::fv::effectivenessHeatExchangerSource::addSup Info<< type() << ": " << name() << nl << incrIndent << indent << "Net mass flux [Kg/s] : " << sumPhi << nl << indent << "Total energy exchange [W] : " << Qt << nl + << indent << "Secondary inlet T [K] : " << secondaryInletT_ << nl << indent << "Tref [K] : " << Tref << nl << indent << "Effectiveness : " << eTable_()(mag(sumPhi), secondaryMassFlowRate_) << decrIndent @@ -314,7 +323,7 @@ bool Foam::fv::effectivenessHeatExchangerSource::read(const dictionary& dict) if (coeffs_.readIfPresent("primaryInletT", primaryInletT_)) { - Info<< type() << " " << this->name() << ": " + Info<< type() << " " << this->name() << ": " << indent << nl << "employing user-specified primary flow inlet temperature: " << primaryInletT_ << endl; @@ -322,11 +331,33 @@ bool Foam::fv::effectivenessHeatExchangerSource::read(const dictionary& dict) } else { - Info<< type() << " " << this->name() << ": " + Info<< type() << " " << this->name() << ": " << indent << nl << "employing flux-weighted primary flow inlet temperature" << endl; } + if (coeffs_.readIfPresent("targetQdot", targetQdot_)) + { + targetQdotActive_ = true; + Info<< indent << "employing target heat rejection of " + << targetQdot_ << nl; + + coeffs_.readIfPresent + ( + "targetQdotCalcInterval", + targetQdotCalcInterval_ + ); + + Info<< indent << "updating secondary inlet temperature every " + << targetQdotCalcInterval_ << " iterations" << nl; + + coeffs_.readIfPresent("targetQdotRelax", targetQdotRelax_); + + Info<< indent << "temperature relaxation: " + << targetQdotRelax_ << endl; + + } + return true; } else diff --git a/src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.H b/src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.H index 9e276fa01e..46b3c6fb89 100644 --- a/src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.H +++ b/src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2013-2017 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,8 +28,8 @@ Group grpFvOptionsSources Description - Heat exchanger source model, in which the heat exchanger is defined as a - selection of cells. + Heat exchanger source model, in which the heat exchanger is defined as an + energy source using a selection of cells. The total heat exchange source is given by: \f[ @@ -75,13 +75,21 @@ Usage secondaryMassFlowRate 1.0; secondaryInletT 336; - // primaryInletT 293; // Constrain to this T if present faceZone facesZoneInletOriented; outOfBounds clamp; file "effTable"; + + // Optional + // primaryInletT 293; + // targetQdot 1500; } \endverbatim + Optional entries: + - \c primaryInletT : sets the primary inlet temperature. If not set, the + flux-averaged temperature is used. + - \c targetQdot : target heat rejection + The effectiveness table is described in terms of the primary and secondary mass flow rates. For example, the table: @@ -95,7 +103,7 @@ Usage \endverbatim - Is specified by the following: + is specified by the following: \verbatim ( @@ -121,9 +129,9 @@ Usage \endverbatim Note -- the table with name "file" should have the same units as the +- the table with name \c file should have the same units as the secondary mass flow rate and kg/s for phi -- faceZone is the faces at the inlet of the cellzone, it needs to be +- \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 @@ -133,8 +141,8 @@ SourceFiles \*---------------------------------------------------------------------------*/ -#ifndef effectivenessHeatExchangerSource_H -#define effectivenessHeatExchangerSource_H +#ifndef fv_effectivenessHeatExchangerSource_H +#define fv_effectivenessHeatExchangerSource_H #include "cellSetOption.H" #include "autoPtr.H" @@ -172,6 +180,18 @@ protected: //- 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> eTable_; @@ -214,7 +234,7 @@ private: //- Initialise heat exchanger source model void initialise(); - //- Calculate total area of faceZone accross processors + //- Calculate total area of faceZone across processors void calculateTotalArea(scalar& area); @@ -237,8 +257,7 @@ public: //- Destructor - virtual ~effectivenessHeatExchangerSource() - {} + virtual ~effectivenessHeatExchangerSource() = default; // Member Functions