Nodes of different colours represent the following:
Solid arrows point from a parent (sub)module to the submodule which is descended from it. Dashed arrows point from a module being used to the module or program unit using it. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer, | intent(in) | :: | Num |
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed arrows point from an interface to procedures which implement that interface. This could include the module procedures in a generic interface or the implementation in a submodule of an interface in a parent module. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed arrows point from an interface to procedures which implement that interface. This could include the module procedures in a generic interface or the implementation in a submodule of an interface in a parent module. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
SUBROUTINE CalcFuelCellGenHeatRecovery(Num)
! SUBROUTINE INFORMATION:
! AUTHOR: Brent Griffith
! DATE WRITTEN: Aug. 2005
! PURPOSE OF THIS SUBROUTINE:
! To perform heat recovery calculations and node updates
! METHODOLOGY EMPLOYED:
! model exhaust gas to water heat exchanger
! REFERENCES: Annex 42 model documentation
! USE STATEMENTS:
USE FluidProperties , ONLY: GetSpecificHeatGlycol
USE DataPlant, ONLY: PlantLoop
IMPLICIT NONE
! SUBROUTINE ARGUMENT DEFINITIONS:
INTEGER,INTENT(IN) :: Num ! Generator number
! SUBROUTINE PARAMETER DEFINITIONS:
! na
! DERIVED TYPE DEFINITIONS
! na
! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
REAL(r64) :: eHX ! fixed effectiveness
REAL(r64) :: MdotWater
INTEGER :: inNodeNum
REAL(r64) :: MWwater
REAL(r64) :: NdotWater
REAL(r64) :: TwaterIn
REAL(r64) :: CpWaterMol
REAL(r64) :: NdotGas
REAL(r64) :: TprodGasIn
REAL(r64) :: CpProdGasMol
REAL(r64) :: NdotCp
REAL(r64) :: qHX
REAL(r64) :: UAeff
REAL(r64) :: TauxMix
REAL(r64) :: NdotCpWater
REAL(r64) :: NdotCpAuxMix
REAL(r64) :: THXexh
REAL(r64) :: TwaterOut
REAL(r64) :: hgas
REAL(r64) :: hwater
REAL(r64) :: waterFract=0.0d0
REAL(r64) :: NdotWaterVapor
REAL(r64) :: TcondThresh
REAL(r64) :: hxl1
REAL(r64) :: hxl2
REAL(r64) :: NdotWaterCond=0.0d0
REAL(r64) :: hfpwater
INTEGER :: I
REAL(r64) :: qSens
REAL(r64) :: qLatent
INTEGER :: loop
REAL(r64) :: Cp
SELECT CASE (FuelCell(Num)%ExhaustHX%HXmodelMode)
CASE(FixedEffectiveness) !Method 1
eHX = FuelCell(Num)%ExhaustHX%HXEffect
inNodeNum = FuelCell(Num)%ExhaustHX%WaterInNode
MdotWater = FuelCell(Num)%ExhaustHX%WaterMassFlowRate
MWwater = GasPhaseThermoChemistryData(4)%MolecularWeight
NdotWater = MdotWater/MWwater
TwaterIn = FuelCell(Num)%ExhaustHX%WaterInletTemp
CALL FigureLiquidWaterHeatCap(TwaterIn, CpWaterMol)
NdotGas = FuelCell(Num)%AuxilHeat%NdotAuxMix
TprodGasIn = FuelCell(Num)%AuxilHeat%TauxMix
CALL FigureAuxilHeatGasHeatCap(Num, TprodGasIn , CpProdGasMol) ! Cp in (J/mol*K)
!factor of 1000.0 for kmol -> mol
NdotCp = MIN(NdotGas*CpProdGasMol*1000.0d0, NdotWater*CpWaterMol*1000.0d0)
qHX = eHX * NdotCp*(TprodGasIn - TwaterIn)
THXexh = TprodGasIn - qHX / (NdotGas*CpProdGasMol*1000.0d0)
Cp = GetSpecificHeatGlycol(PlantLoop(FuelCell(Num)%CWLoopNum)%FluidName, &
TwaterIn, &
PlantLoop(FuelCell(Num)%CWLoopNum)%FluidIndex, &
'CalcFuelCellGenHeatRecovery')
IF (MdotWater * Cp <= 0.0d0) THEN
TwaterOut = TwaterIn
ELSE
TwaterOut = TwaterIn + qHX / (MdotWater * Cp)
ENDIF
CASE(LMTDempiricalUAeff) !method 2
inNodeNum = FuelCell(Num)%ExhaustHX%WaterInNode
MdotWater = FuelCell(Num)%ExhaustHX%WaterMassFlowRate
MWwater = GasPhaseThermoChemistryData(4)%MolecularWeight
NdotWater = MdotWater/MWwater
NdotGas = FuelCell(Num)%AuxilHeat%NdotAuxMix
UAeff = FuelCell(Num)%ExhaustHX%hxs0 + FuelCell(Num)%ExhaustHX%hxs1*NdotWater &
+ FuelCell(Num)%ExhaustHX%hxs2 * (NdotWater**2) + &
FuelCell(Num)%ExhaustHX%hxs3 * NdotGas + FuelCell(Num)%ExhaustHX%hxs4*(NdotGas**2)
TauxMix = FuelCell(Num)%AuxilHeat%TauxMix
TwaterIn = FuelCell(Num)%ExhaustHX%WaterInletTemp
CALL FigureLiquidWaterHeatCap(TwaterIn, CpWaterMol)
!factor of 1000.0 for kmol -> mol
NdotCpWater = NdotWater*CpWaterMol*1000.0d0
CALL FigureAuxilHeatGasHeatCap(Num, TauxMix , CpProdGasMol) ! Cp in (J/mol*K)
NdotCpAuxMix = NdotGas*CpProdGasMol*1000.0d0
! commented out protection for taking exponent of too large a number
! because it hasn't been a problem in testing
!testVal = log(huge(NdotCpAuxMix))
!ExpTestVal = 700.0
!IF (UAeff*(1/NdotCpAuxMix) > ExpTestVal) THEN
! write(*,*) 'Houston, we have a problem, EXP [] func will fail for UAeff*(1/NdotCpAuxMix):', UAeff*(1/NdotCpAuxMix)
! ELSEIF (UAeff*(1/NdotCpWater) > ExpTestVal) THEN
! write(*,*) 'Houston, we have a problem, EXP [] func will fail for UAeff*(1/NdotCpWater:', UAeff*(1/NdotCpWater)
! ELSE
If ((NdotCpWater /= 0.0d0) .AND. (NdotCpAuxMix /= 0.0d0)) then ! trap divide by zero
! now evaluate Eq. 44
THXexh = ((1.0d0-NdotCpAuxMix/NdotCpWater)/ &
(EXP(UAeff*(1.0d0/NdotCpAuxMix - 1.0d0/NdotCpWater)) - NdotCpAuxMix/NdotCpWater) )* TauxMix &
+( (EXP(UAeff*(1.0d0/NdotCpAuxMix - 1.0d0/NdotCpWater)) -1.0d0) &
/(EXP(UAeff*(1.0d0/NdotCpAuxMix - 1.0d0/NdotCpWater)) - NdotCpAuxMix/NdotCpWater) )* TwaterIn
TwaterOut = TwaterIn + (NdotCpAuxMix/NdotCpWater) * (TauxMix - THXexh) ! Eq. 42
ELSE
THXexh = TauxMix
TwaterOut = TwaterIn
ENDIF
! ENDIF
IF ((THXexh - TwaterIn) /= 0.0d0) THEN ! trap divide by zero
qHX = UAeff * ( (TauxMix - TwaterOut) - (THXexh - TwaterIn) )/LOG( (TauxMix - TwaterOut) / (THXexh - TwaterIn) )
ELSE
qHX = 0.0d0
ENDIF
CASE(LMTDfundementalUAeff) !method 3
NdotGas = FuelCell(Num)%AuxilHeat%NdotAuxMix
inNodeNum = FuelCell(Num)%ExhaustHX%WaterInNode
MdotWater = FuelCell(Num)%ExhaustHX%WaterMassFlowRate
MWwater = GasPhaseThermoChemistryData(4)%MolecularWeight
NdotWater = MdotWater/MWwater
hgas = FuelCell(Num)%ExhaustHX%h0gas * (NdotGas/FuelCell(Num)%ExhaustHX%NdotGasRef)**FuelCell(Num)%ExhaustHX%nCoeff !Eq. 48
hwater = FuelCell(Num)%ExhaustHX%h0Water &
* (NdotWater/FuelCell(Num)%ExhaustHX%NdotWaterRef)**FuelCell(Num)%ExhaustHX%mCoeff !Eq. 48
! now equation 47
UAeff = 1.0d0/(1.0d0/(hgas*FuelCell(Num)%ExhaustHX%AreaGas) + 1.0d0/(hwater*FuelCell(Num)%ExhaustHX%AreaWater) &
+ FuelCell(Num)%ExhaustHX%Fadjust)
TauxMix = FuelCell(Num)%AuxilHeat%TauxMix
TwaterIn = FuelCell(Num)%ExhaustHX%WaterInletTemp
CALL FigureLiquidWaterHeatCap(TwaterIn, CpWaterMol)
NdotCpWater = NdotWater*CpWaterMol*1000.0d0
CALL FigureAuxilHeatGasHeatCap(Num, TauxMix , CpProdGasMol) ! Cp in (J/mol*K)
NdotCpAuxMix = NdotGas*CpProdGasMol*1000.0d0
If ((NdotCpWater /= 0.0d0) .AND. (NdotCpAuxMix /= 0.0d0)) then ! trap divide by zero
! now evaluate Eq. 44
THXexh = ((1.0d0-NdotCpAuxMix/NdotCpWater)/ &
(EXP(UAeff*(1.0d0/NdotCpAuxMix - 1.0d0/NdotCpWater)) - NdotCpAuxMix/NdotCpWater) )* TauxMix &
+( (EXP(UAeff*(1.0d0/NdotCpAuxMix - 1.0d0/NdotCpWater)) -1.0d0) &
/(EXP(UAeff*(1.0d0/NdotCpAuxMix - 1.0d0/NdotCpWater)) - NdotCpAuxMix/NdotCpWater) )* TwaterIn
TwaterOut = TwaterIn + (NdotCpAuxMix/NdotCpWater) * (TauxMix - THXexh) ! Eq. 42
ELSE
THXexh = TauxMix
TwaterOut = TwaterIn
ENDIF
IF ((THXexh - TwaterIn) /= 0.0d0) THEN ! trap divide by zero
qHX = UAeff * ( (TauxMix - TwaterOut) - (THXexh - TwaterIn) )/LOG( (TauxMix - TwaterOut) / (THXexh - TwaterIn) )
ELSE
qHX = 0.0d0
ENDIF
CASE(Condensing) !method 4
inNodeNum = FuelCell(Num)%ExhaustHX%WaterInNode
MdotWater = FuelCell(Num)%ExhaustHX%WaterMassFlowRate
If (MdotWater /= 0.0D0) Then !
MWwater = GasPhaseThermoChemistryData(4)%MolecularWeight
NdotWater = MdotWater/MWwater
NdotGas = FuelCell(Num)%AuxilHeat%NdotAuxMix
UAeff = FuelCell(Num)%ExhaustHX%hxs0 + FuelCell(Num)%ExhaustHX%hxs1*NdotWater &
+ FuelCell(Num)%ExhaustHX%hxs2 * NdotWater**2 + &
FuelCell(Num)%ExhaustHX%hxs3 * NdotGas + FuelCell(Num)%ExhaustHX%hxs4*NdotGas**2
TauxMix = FuelCell(Num)%AuxilHeat%TauxMix
TwaterIn = FuelCell(Num)%ExhaustHX%WaterInletTemp
CALL FigureLiquidWaterHeatCap(TwaterIn, CpWaterMol)
NdotCpWater = NdotWater*CpWaterMol*1000.0d0
CALL FigureAuxilHeatGasHeatCap(Num, TauxMix , CpProdGasMol) ! Cp in (J/mol*K)
NdotCpAuxMix = NdotGas*CpProdGasMol*1000.0d0
!find water fraction in incoming gas stream
DO I = 1, Size(FuelCell(Num)%AuxilHeat%GasLibID)
If (FuelCell(Num)%AuxilHeat%GasLibID(I) == 4) waterFract = FuelCell(Num)%AuxilHeat%ConstitMolalFract(I)
ENDDO
NdotWaterVapor =waterFract * NdotGas
TcondThresh = FuelCell(Num)%ExhaustHX%CondensationThresholdTemp
hxl1 = FuelCell(Num)%ExhaustHX%l1Coeff
hxl2 = FuelCell(Num)%ExhaustHX%l2Coeff
NdotWaterCond = (TcondThresh - TwaterIn) * ( hxl1 * (NdotWaterVapor/NdotGas) + hxl2*(NdotWaterVapor/NdotGas)**2)
If (NdotWaterCond < 0.0d0) NdotWaterCond = 0.0d0
hfpwater = 4.4004d+07 ! molal heat of vaporization of water J/kmol)
If ((NdotCpWater /= 0.0d0) .AND. (NdotCpAuxMix /= 0.0d0)) then ! trap divide by zero
! now evaluate Eq. 44
THXexh = ((1.0d0-NdotCpAuxMix/NdotCpWater)/ &
(EXP(UAeff*(1.0d0/NdotCpAuxMix - 1.0d0/NdotCpWater)) - NdotCpAuxMix/NdotCpWater) )* TauxMix &
+( (EXP(UAeff*(1.0d0/NdotCpAuxMix - 1.0d0/NdotCpWater)) -1.0d0) &
/(EXP(UAeff*(1.0d0/NdotCpAuxMix - 1.0d0/NdotCpWater)) - NdotCpAuxMix/NdotCpWater) )* TwaterIn
TwaterOut = TwaterIn + (NdotCpAuxMix/NdotCpWater) * (TauxMix - THXexh) + (NdotWaterCond * hfpwater)/NdotCpWater
IF (NdotWaterCond > 0) then ! Eq. 44 is not correct. use its result as first guess for revised way...
do loop = 1, 5 ! iterative soluion because in condensing case THXexh is function of qSens and qLatent
IF ((THXexh - TwaterIn) /= 0.0d0) THEN ! trap divide by zero
qSens = UAeff * ( (TauxMix - TwaterOut) - (THXexh - TwaterIn) )/ &
LOG( (TauxMix - TwaterOut) / (THXexh - TwaterIn) )
else
qSens = 0.0d0
endif
qLatent= NdotWaterCond * hfpwater
If (qSens > 0) then
THXexh = TauxMix *( (1.0d0-NdotCpAuxMix/NdotCpWater) &
/( ( EXP(UAeff*(1.0d0/NdotCpAuxMix - 1.0d0/NdotCpWater) ) &
/( EXP((UAeff * qLatent)/(NdotCpWater * qSens)) ) ) - NdotCpAuxMix/NdotCpWater) ) &
+ TwaterIn *( ( EXP(UAeff*(1.0d0/NdotCpAuxMix - 1.0d0/NdotCpWater)) &
/( EXP((UAeff * qLatent)/(NdotCpWater * qSens)) ) -1.0d0) &
/(EXP(UAeff*(1.0d0/NdotCpAuxMix - 1.0d0/NdotCpWater)) &
/( EXP((UAeff * qLatent)/(NdotCpWater * qSens)) ) - NdotCpAuxMix/NdotCpWater) ) &
-( (qLatent/NdotCpWater) /(EXP(UAeff*(1.0d0/NdotCpAuxMix - 1.0d0/NdotCpWater)) &
/( EXP((UAeff * qLatent)/(NdotCpWater * qSens)) ) - NdotCpAuxMix/NdotCpWater) )
else
THXexh = TauxMix
endif
TwaterOut = TwaterIn + (NdotCpAuxMix/NdotCpWater) * (TauxMix - THXexh) + (NdotWaterCond * hfpwater)/NdotCpWater
enddo
endif
ELSE
THXexh = TauxMix
TwaterOut = TwaterIn
ENDIF
IF ((THXexh - TwaterIn) /= 0.0d0) THEN ! trap divide by zero
qHX = UAeff * ( (TauxMix - TwaterOut) - (THXexh - TwaterIn) )/LOG( (TauxMix - TwaterOut) / (THXexh - TwaterIn) ) &
+ NdotWaterCond * hfpwater
ELSE
qHX = 0.0d0
ENDIF
ELSE !no cooling water flow, model will blow up.
qHX = 0.0D0
THXexh = FuelCell(Num)%AuxilHeat%TauxMix
TwaterOut = FuelCell(Num)%ExhaustHX%WaterInletTemp
NdotWaterCond = 0.0D0
waterFract = -9999.0D0 ! not defined
ENDIF
!init input from Auxiliary heater
! FuelCell(Num)%ExhaustHX%NdotHXleaving = FuelCell(Num)%AuxilHeat%NdotAuxMix
! FuelCell(Num)%ExhaustHX%ConstitMolalFract = FuelCell(Num)%AuxilHeat%ConstitMolalFract
! FuelCell(Num)%ExhaustHX%GasLibID = FuelCell(Num)%AuxilHeat%GasLibID
! now modify leaving gas constituents for condensed water.
! FuelCell(Num)%ExhaustHX%NdotHXleaving = FuelCell(Num)%AuxilHeat%NdotAuxMix - NdotWaterCond
! If ( FuelCell(Num)%ExhaustHX%NdotHXleaving > 0) then
! DO I = 1, Size(FuelCell(Num)%AuxilHeat%GasLibID)
! If (FuelCell(Num)%AuxilHeat%GasLibID(I) == 4) then ! water constituent
! FuelCell(Num)%ExhaustHX%ConstitMolalFract(I) = &
! (FuelCell(Num)%AuxilHeat%ConstitMolalFract(I)* FuelCell(Num)%AuxilHeat%NdotAuxMix - NdotWaterCond) &
! / FuelCell(Num)%ExhaustHX%NdotHXleaving
! cycle
! ENDIF
! FuelCell(Num)%ExhaustHX%ConstitMolalFract(I) = FuelCell(Num)%AuxilHeat%ConstitMolalFract(I) &
! * FuelCell(Num)%AuxilHeat%NdotAuxMix / FuelCell(Num)%ExhaustHX%NdotHXleaving
! ENDDO
! ENDIF
! get new average heat capacity
!CALL FigureHXleavingGasHeatCap(Num, (THXexh + TauxMix)/2 , CpHXleavingGasMol)
! NdotCpHXleaving = FuelCell(Num)%ExhaustHX%NdotHXleaving*CpHXleavingGasMol* 1000.0
! update gas leaving temperature with modified heat transfer rate
! IF ((NdotCpHXleaving > 0) .AND. (qHX > 0)) THEN
! THXexh = TauxMix - (qHX / NdotCpHXleaving)
! ELSE
! THXexh = TauxMix
! ENDIF
! update water leaving temperature with modified heat transfer rate
! IF (MdotWater * CPCW( (TwaterIn + TwaterOut)/2 ) <= 0.0) THEN
! TwaterOut = TwaterIn
! ELSE
! TwaterOut = TwaterIn + qHX / (MdotWater * CPCW( (TwaterIn + TwaterOut)/2 ))
! ENDIF
END SELECT
! update results in data structure.
FuelCell(Num)%ExhaustHX%qHX = qHX
FuelCell(Num)%ExhaustHX%THXexh = THXexh
FuelCell(Num)%ExhaustHX%WaterMassFlowRate = MdotWater
FuelCell(Num)%ExhaustHX%WaterVaporFractExh = waterFract
FuelCell(Num)%ExhaustHX%CondensateRate = NdotWaterCond
FuelCell(Num)%ExhaustHX%WaterOutletTemp = Twaterout
FuelCell(Num)%ExhaustHX%WaterOutletEnthalpy = Node(inNodeNum)%Enthalpy + qHX
! now update water outlet node Changing to Kg/s!
! OutNodeNum = FuelCell(Num)%ExhaustHX%WaterOutNode
! inNodeNum = FuelCell(Num)%ExhaustHX%WaterInNode
! Node(OutNodeNum)%Temp = Twaterout
! Node(OutNodeNum)%Enthalpy =
! Node(OutNodeNum)%MassFlowRate = MdotWater
RETURN
END SUBROUTINE CalcFuelCellGenHeatRecovery