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) | :: | TESCoilNum | |||
real(kind=r64), | intent(in) | :: | PartLoadRatio |
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 CalcTESCoilDischargeOnlyMode( TESCoilNum , PartLoadRatio)
! SUBROUTINE INFORMATION:
! AUTHOR Brent Griffith
! DATE WRITTEN April 2013
! MODIFIED na
! RE-ENGINEERED na
! PURPOSE OF THIS SUBROUTINE:
! <description>
! METHODOLOGY EMPLOYED:
! <description>
! REFERENCES:
! na
! USE STATEMENTS:
USE CurveManager, ONLY: CurveValue
USE DataHVACGlobals, ONLY: TimeStepSys
USE FluidProperties, ONLY: GetSpecificHeatGlycol, GetDensityGlycol
IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
! SUBROUTINE ARGUMENT DEFINITIONS:
INTEGER , INTENT (IN) :: TESCoilNum
REAL(r64) , INTENT (IN) :: PartLoadRatio
! SUBROUTINE PARAMETER DEFINITIONS:
INTEGER, PARAMETER :: MaxIter = 30
REAL(r64), PARAMETER :: RelaxationFactor = 0.4d0
REAL(r64), PARAMETER :: Tolerance = 0.1d0
! INTERFACE BLOCK SPECIFICATIONS:
! na
! DERIVED TYPE DEFINITIONS:
! na
! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
REAL(r64) :: AirMassFlowRatio ! evaporator inlet air mass flow divided by design mass flow [ ]
REAL(r64) :: EvapAirMassFlow ! local for evaporator air mass flow [kg/s]
REAL(r64) :: EvapInletDryBulb ! evaporator inlet air drybulb [C]
REAL(r64) :: EvapInletHumRat ! evaporator inlet air humidity ratio [kg/kg]
REAL(r64) :: EvapInletWetBulb ! evaporator inlet air wetbulb [C]
REAL(r64) :: EvapInletEnthalpy ! evaporator inlet air enthalpy [J/kg]
REAL(r64) :: sTES ! state of charge of Thermal Energy Storage
REAL(r64) :: TotCapTempModFac ! total coolin capacity modification factor due to temps []
REAL(r64) :: TotCapFlowModFac !Total cooling capacity modification factor due to flow []
REAL(r64) :: TotCap ! total cooling capacity
REAL(r64) :: SHRTempFac ! sensible heat ratio modification factor due to temps []
REAL(r64) :: SHRFlowFac ! sensible heat ratio modification factor due to flow []
REAL(r64) :: SHR ! sensible heat ratio
REAL(r64) :: PLF ! part load factor
REAL(r64) :: PLR ! part load ratio
REAL(r64) :: RuntimeFraction ! compressor running time divided by full time of timestep.
REAL(r64) :: FullLoadOutAirEnth ! evaporator outlet full load enthalpy [J/kg]
REAL(r64) :: FullLoadOutAirHumRat ! evaporator outlet humidity ratio at full load
REAL(r64) :: FullLoadOutAirTemp !evaporator outlet air temperature at full load [C]
REAL(r64) :: hTinwout ! Enthalpy at inlet dry-bulb and outlet humidity ratio [J/kg]
REAL(r64) :: EvapOutletAirEnthalpy ! evaporator outlet air enthalpy [J/kg]
REAL(r64) :: EvapOutletAirHumRat !evaporator outlet air humidity ratio [kg/kg]
REAL(r64) :: EvapOutletAirTemp !evaporator outlet dryblub [C]
REAL(r64) :: EIRTempModFac ! energy input ratio modification factor due to temperatures []
REAL(r64) :: EIRFlowModFac !energy input ratio modification factor due to flow []
REAL(r64) :: EIR ! energy input ratio
REAL(r64) :: ElecCoolingPower ! compressor electric power
REAL(r64) :: MinAirHumRat ! minimum air humidity ratio
LOGICAL :: TESHasSomeCharge ! true when there is something avaiable in storage
REAL(r64) :: QdotDischargelimit ! limit for how much storage can be discharged without overshooting
REAL(r64) :: rho ! density of water in tank (kg/m3)
REAL(r64) :: TankMass ! Mass of water in tank (kg)
REAL(r64) :: CpTank ! Specific heat of water in tank (J/kg K)
REAL(r64) :: QdotTEStest
REAL(r64) :: RuntimeFractionLimit
REAL(r64) :: PartLoadOutAirEnth ! local leaving enthalpy at part load
REAL(r64) :: PartLoadDryCoilOutAirTemp ! local leaving drybulb if coil were dry
LOGICAL :: CoilMightBeDry
INTEGER :: Counter
LOGICAL :: Converged
REAL(r64) :: DryCoilTestEvapInletHumRat
REAL(r64) :: DryCoilTestEvapInletWetBulb
REAL(r64) :: hADP
REAL(r64) :: tADP
REAL(r64) :: wADP
REAL(r64) :: hTinwADP
REAL(r64) :: SHRadp
REAL(r64) :: werror
PLR = PartLoadRatio
EvapAirMassFlow = Node(TESCoil(TESCoilNum)%EvapAirInletNodeNum)%MassFlowRate
EvapInletDryBulb = Node(TESCoil(TESCoilNum)%EvapAirInletNodeNum)%Temp
EvapInletHumRat = Node(TESCoil(TESCoilNum)%EvapAirInletNodeNum)%HumRat
EvapInletWetBulb = PsyTwbFnTdbWPb(EvapInletDryBulb, EvapInletHumRat, OutBaroPress, 'CalcTESCoilDischargeOnlyMode')
EvapInletEnthalpy = Node(TESCoil(TESCoilNum)%EvapAirInletNodeNum)%Enthalpy
CoilMightBeDry = .FALSE.
IF (TESCoil(TESCoilNum)%StorageMedia == FluidBased) THEN
sTES = TESCoil(TESCoilNum)%FluidTankTempFinalLastTimestep
IF ((sTES >= TESCoil(TESCoilNum)%MinimumFluidTankTempLimit) .AND. (sTES < TESCoil(TESCoilNum)%MaximumFluidTankTempLimit)) THEN
TESHasSomeCharge = .TRUE.
rho = GetDensityGlycol(TESCoil(TESCoilNum)%StorageFluidName, sTES, &
TESCoil(TESCoilNum)%StorageFluidIndex, 'CalcTESWaterStorageTank')
TankMass = rho * TESCoil(TESCoilNum)%FluidStorageVolume
CpTank = GetSpecificHeatGlycol(TESCoil(TESCoilNum)%StorageFluidName, sTES, &
TESCoil(TESCoilNum)%StorageFluidIndex, 'CalcTESWaterStorageTank')
!simple linear approximation of DT/Dt term in McpDT/Dt
QdotDischargelimit = TankMass * CpTank * (TESCoil(TESCoilNum)%MaximumFluidTankTempLimit - sTES)/ (TimeStepSys * SecInHour)
ELSE
TESHasSomeCharge = .FALSE.
ENDIF
ELSEIF (TESCoil(TESCoilNum)%StorageMedia == IceBased) THEN
sTES = TESCoil(TESCoilNum)%IceFracRemainLastTimestep
If (sTES > 0.d0 ) THEN
TESHasSomeCharge = .TRUE.
! discharge limit
QdotDischargelimit = (sTES) * TESCoil(TESCoilNum)%IceStorageCapacity / (TimeStepSys * SecInHour)
ELSE
TESHasSomeCharge = .FALSE.
ENDIF
ENDIF
IF ((EvapAirMassFlow > SmallMassFlow) .AND. (PLR > 0.d0) .AND. TESHasSomeCharge ) THEN ! coil is running
AirMassFlowRatio = EvapAirMassFlow / TESCoil(TESCoilNum)%RatedEvapAirMassFlowRate
TotCapTempModFac = CurveValue(TESCoil(TESCoilNum)%DischargeOnlyCapFTempCurve, EvapInletWetBulb, sTES)
TotCapTempModFac = MAX(0.d0, TotCapTempModFac)
TotCapFlowModFac = CurveValue(TESCoil(TESCoilNum)%DischargeOnlyCapFFlowCurve, AirMassFlowRatio)
TotCapFlowModFac = MAX(0.d0, TotCapFlowModFac)
TotCap = TESCoil(TESCoilNum)%DischargeOnlyRatedDischargeCap * TotCapTempModFac * TotCapFlowModFac
PLF = CurveValue(TESCoil(TESCoilNum)%DischargeOnlyPLFFPLRCurve, PLR)
IF (PLF >= PLR .and. PLF > 0.d0 ) THEN
RuntimeFraction = PLR / PLF
ELSE
RuntimeFraction = 1.d0 ! warn maybe
ENDIF
! Calculate electricity consumed. First, get EIR modifying factors for off-rated conditions
EIRTempModFac = CurveValue(TESCoil(TESCoilNum)%DischargeOnlyEIRFTempCurve, EvapInletWetBulb, sTES)
EIRTempModFac = MAX(EIRTempModFac, 0.d0)
EIRFlowModFac = CurveValue(TESCoil(TESCoilNum)%DischargeOnlyEIRFFlowCurve, AirMassFlowRatio)
EIRFlowModFac = MAX(EIRFlowModFac, 0.d0)
EIR = EIRTempModFac * EIRFlowModFac / TESCoil(TESCoilNum)%DischargeOnlyRatedCOP
ElecCoolingPower = TotCap * EIR * RuntimeFraction
QdotTEStest = TotCap*RuntimeFraction + ElecCoolingPower
IF (QdotTEStest > QdotDischargelimit) THEN
RuntimeFractionLimit = QdotDischargelimit / (TotCap + TotCap * EIR)
RuntimeFraction = MIN(RuntimeFraction, RuntimeFractionLimit)
PLR = RuntimeFraction * PLF
ElecCoolingPower = TotCap * EIR * RuntimeFraction
ENDIF
! now see if coil is running dry
PartLoadOutAirEnth = EvapInletEnthalpy - (TotCap * PartLoadRatio) / EvapAirMassFlow
PartLoadDryCoilOutAirTemp = PsyTdbFnHW(PartLoadOutAirEnth, EvapInletHumRat,'CalcTESCoilDischargeOnlyMode')
IF (PartLoadDryCoilOutAirTemp > PsyTsatFnHPb(PartLoadOutAirEnth,OutBaroPress, 'CalcTESCoilDischargeOnlyMode')) THEN
CoilMightBeDry = .TRUE.
! find wADP, humidity ratio at apparatus dewpoint and inlet hum rat that would have dry coil
DryCoilTestEvapInletHumRat = EvapInletHumRat
DryCoilTestEvapInletWetBulb = EvapInletWetBulb
counter = 0
Converged = .FALSE.
DO While (.NOT. Converged)
TotCapTempModFac = CurveValue(TESCoil(TESCoilNum)%DischargeOnlyCapFTempCurve, DryCoilTestEvapInletWetBulb, sTES)
TotCapTempModFac = MAX(0.d0, TotCapTempModFac)
TotCapFlowModFac = CurveValue(TESCoil(TESCoilNum)%DischargeOnlyCapFFlowCurve, AirMassFlowRatio)
TotCapFlowModFac = MAX(0.d0, TotCapFlowModFac)
TotCap = TESCoil(TESCoilNum)%DischargeOnlyRatedDischargeCap * TotCapTempModFac * TotCapFlowModFac
! coil bypass factor = 0.0
hADP = EvapInletEnthalpy - (TotCap / EvapAirMassFlow)
tADP = PsyTsatFnHPb(hADP, OutBaroPress, 'CalcTESCoilDischargeOnlyMode')
wADP = MIN(EvapInletHumRat, PsyWfnTdbH(tADP, hADP, 'CalcTESCoilDischargeOnlyMode') )
hTinwADP = PsyHFnTdbW(EvapInletDryBulb, wADP, 'CalcTESCoilDischargeOnlyMode')
IF ((EvapInletEnthalpy - hADP) > 1.d-10) THEN
SHRadp = MIN((hTinwADP-hADP)/(EvapInletEnthalpy-hADP),1.d0)
ELSE
SHRadp = 1.d0
ENDIF
IF ((wADP > DryCoilTestEvapInletHumRat) .or. (Counter .ge. 1 .and. Counter .lt. MaxIter)) THEN
IF (DryCoilTestEvapInletHumRat <= 0.d0) DryCoilTestEvapInletHumRat = 0.00001d0
werror = (DryCoilTestEvapInletHumRat - wADP)/DryCoilTestEvapInletHumRat
DryCoilTestEvapInletHumRat = RelaxationFactor*wADP + (1.d0 - RelaxationFactor)*DryCoilTestEvapInletHumRat
DryCoilTestEvapInletWetBulb = PsyTwbFnTdbWPb(EvapInletDryBulb , DryCoilTestEvapInletHumRat, OutBaroPress, &
'CalcTESCoilDischargeOnlyMode')
Counter = Counter + 1
IF (ABS(werror) <= Tolerance) THEN
Converged = .TRUE.
ELSE
Converged = .FALSE.
ENDIF
ELSE
Converged = .TRUE.
ENDIF
ENDDO
ENDIF ! coil will be wet so use SHR curves
SELECT CASE ( TESCoil(TESCoilNum)%DischargeOnlySHRFTempObjectNum )
CASE ( CurveType_BiCubic, CurveType_BiQuadratic, CurveType_QuadraticLinear, CurveType_TableTwoIV )
SHRTempFac = CurveValue(TESCoil(TESCoilNum)%DischargeOnlySHRFTempCurve, EvapInletWetBulb, EvapInletDryBulb)
CASE ( CurveType_TriQuadratic, CurveType_TableMultiIV )
SHRTempFac = CurveValue(TESCoil(TESCoilNum)%DischargeOnlySHRFTempCurve, EvapInletWetBulb, EvapInletDryBulb, sTES)
END SELECT
SHRFlowFac = CurveValue(TESCoil(TESCoilNum)%DischargeOnlySHRFFLowCurve, AirMassFlowRatio)
SHR = TESCoil(TESCoilNum)%DischargeOnlyRatedSHR * SHRTempFac * SHRFlowFac
SHR = MIN(SHR, 1.d0) ! warn maybe
SHR = MAX(SHR, 0.d0) ! warn maybe
IF ( CoilMightBeDry) THEN
IF ((EvapInletHumRat < DryCoilTestEvapInletHumRat) .AND. (SHRadp > SHR)) THEN ! coil is dry for sure
SHR = 1.0d0
ELSEIF (SHRadp > SHR) THEN
SHR = SHRadp
ENDIF
ENDIF
! Calculate full load output conditions
FullLoadOutAirEnth = EvapInletEnthalpy - TotCap / EvapAirMassFlow
hTinwout = EvapInletEnthalpy - (1.0d0-SHR)* (TotCap / EvapAirMassFlow)
!The following will often throw psych warnings for neg w, suppress warnings because error condition is handled in next IF
FullLoadOutAirHumRat = PsyWFnTdbH(EvapInletDryBulb,hTinwout, 'CalcTESCoilDischargeOnlyMode', SuppressWarnings = .TRUE.)
FullLoadOutAirTemp = PsyTdbFnHW(FullLoadOutAirEnth,FullLoadOutAirHumRat, 'CalcTESCoilDischargeOnlyMode')
! Check for saturation error and modify temperature at constant enthalpy
IF(FullLoadOutAirTemp .LT. PsyTsatFnHPb(FullLoadOutAirEnth,OutBaroPress, 'CalcTESCoilDischargeOnlyMode')) THEN
FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,OutBaroPress, 'CalcTESCoilDischargeOnlyMode')
FullLoadOutAirHumRat = PsyWFnTdbH(FullLoadOutAirTemp,FullLoadOutAirEnth, 'CalcTESCoilDischargeOnlyMode')
ENDIF
! Continuous fan, cycling compressor
EvapOutletAirEnthalpy = ((PLR)*FullLoadOutAirEnth + &
(1.d0-(PLR ))*EvapInletEnthalpy)
EvapOutletAirHumRat = ((PLR)*FullLoadOutAirHumRat + &
(1.d0-(PLR ))*EvapInletHumRat)
EvapOutletAirTemp = PsyTdbFnHW(EvapOutletAirEnthalpy,EvapOutletAirHumRat)
IF(EvapOutletAirTemp .LT. PsyTsatFnHPb(EvapOutletAirEnthalpy,OutBaroPress, 'CalcTESCoilDischargeOnlyMode')) THEN
EvapOutletAirTemp = PsyTsatFnHPb(EvapOutletAirEnthalpy,OutBaroPress, 'CalcTESCoilDischargeOnlyMode')
EvapOutletAirHumRat = PsyWFnTdbH(EvapOutletAirTemp,EvapOutletAirEnthalpy, 'CalcTESCoilDischargeOnlyMode')
ENDIF
Node(TESCoil(TESCoilNum)%EvapAirOutletNodeNum )%Temp = EvapOutletAirTemp
Node(TESCoil(TESCoilNum)%EvapAirOutletNodeNum )%HumRat = EvapOutletAirHumRat
Node(TESCoil(TESCoilNum)%EvapAirOutletNodeNum )%Enthalpy = EvapOutletAirEnthalpy
Node(TESCoil(TESCoilNum)%EvapAirOutletNodeNum )%MassFlowRate = EvapAirMassFlow
TESCoil(TESCoilNum)%ElecCoolingPower = ElecCoolingPower + TESCoil(TESCoilNum)%AncillaryControlsPower
TESCoil(TESCoilNum)%ElecCoolingEnergy = TESCoil(TESCoilNum)%ElecCoolingPower * TimeStepSys *SecInHour
TESCoil(TESCoilNum)%RuntimeFraction = RuntimeFraction
TESCoil(TESCoilNum)%EvapTotCoolingRate = TotCap* RuntimeFraction ! double check this
TESCoil(TESCoilNum)%EvapTotCoolingEnergy = TotCap* RuntimeFraction * TimeStepSys *SecInHour
MinAirHumRat = MIN( Node(TESCoil(TESCoilNum)%EvapAirOutletNodeNum )%HumRat, &
Node(TESCoil(TESCoilNum)%EvapAirInletNodeNum)%HumRat )
TESCoil(TESCoilNum)%EvapSensCoolingRate = EvapAirMassFlow *&
(PsyHFnTdbW(EvapInletDryBulb , MinAirHumRat, 'CalcTESCoilDischargeOnlyMode') - &
PsyHFnTdbW(EvapOutletAirTemp, MinAirHumRat, 'CalcTESCoilDischargeOnlyMode') )
IF (TESCoil(TESCoilNum)%EvapSensCoolingRate > TESCoil(TESCoilNum)%EvapTotCoolingRate) THEN
TESCoil(TESCoilNum)%EvapSensCoolingRate = TESCoil(TESCoilNum)%EvapTotCoolingRate
ENDIF
TESCoil(TESCoilNum)%EvapSensCoolingEnergy= TESCoil(TESCoilNum)%EvapSensCoolingRate * TimeStepSys *SecInHour
TESCoil(TESCoilNum)%EvapLatCoolingRate = TESCoil(TESCoilNum)%EvapTotCoolingRate &
- TESCoil(TESCoilNum)%EvapSensCoolingRate
TESCoil(TESCoilNum)%EvapLatCoolingEnergy = TESCoil(TESCoilNum)%EvapLatCoolingRate * TimeStepSys *SecInHour
TESCoil(TESCoilNum)%QdotTES = TotCap*RuntimeFraction + ElecCoolingPower ! all heat rejection into storage
ELSE !coil is off; just pass through conditions
TESCoil(TESCoilNum)%QdotTES = 0.d0
TESCoil(TESCoilNum)%ElecCoolingPower = TESCoil(TESCoilNum)%AncillaryControlsPower
TESCoil(TESCoilNum)%ElecCoolingEnergy = TESCoil(TESCoilNum)%ElecCoolingPower * TimeStepSys *SecInHour
TESCoil(TESCoilNum)%RuntimeFraction = 0.d0
TESCoil(TESCoilNum)%RuntimeFraction = 0.d0
TESCoil(TESCoilNum)%EvapTotCoolingRate = 0.d0
TESCoil(TESCoilNum)%EvapTotCoolingEnergy = 0.d0
TESCoil(TESCoilNum)%EvapSensCoolingRate = 0.d0
TESCoil(TESCoilNum)%EvapSensCoolingEnergy= 0.d0
TESCoil(TESCoilNum)%EvapLatCoolingRate = 0.d0
TESCoil(TESCoilNum)%EvapLatCoolingEnergy = 0.d0
Node(TESCoil(TESCoilNum)%EvapAirOutletNodeNum )%Temp = Node(TESCoil(TESCoilNum)%EvapAirInletNodeNum)%Temp
Node(TESCoil(TESCoilNum)%EvapAirOutletNodeNum )%HumRat = Node(TESCoil(TESCoilNum)%EvapAirInletNodeNum)%HumRat
Node(TESCoil(TESCoilNum)%EvapAirOutletNodeNum )%MassFlowRate = Node(TESCoil(TESCoilNum)%EvapAirInletNodeNum)%MassFlowRate
Node(TESCoil(TESCoilNum)%EvapAirOutletNodeNum)%Enthalpy = &
PsyHFnTdbW(Node(TESCoil(TESCoilNum)%EvapAirOutletNodeNum )%Temp, &
Node(TESCoil(TESCoilNum)%EvapAirOutletNodeNum )%HumRat, &
'CalcTESCoilCoolingOnlyMode')
ENDIF
!nothing happens at condenser
Node(TESCoil(TESCoilNum)%CondAirOutletNodeNum )%Temp = Node(TESCoil(TESCoilNum)%CondAirInletNodeNum)%Temp
Node(TESCoil(TESCoilNum)%CondAirOutletNodeNum )%HumRat = Node(TESCoil(TESCoilNum)%CondAirInletNodeNum)%HumRat
Node(TESCoil(TESCoilNum)%CondAirInletNodeNum )%MassFlowRate = 0.d0
Node(TESCoil(TESCoilNum)%CondAirOutletNodeNum )%MassFlowRate = Node(TESCoil(TESCoilNum)%CondAirInletNodeNum)%MassFlowRate
Node(TESCoil(TESCoilNum)%CondAirOutletNodeNum )%Enthalpy = &
PsyHFnTdbW(Node(TESCoil(TESCoilNum)%CondAirOutletNodeNum )%Temp, &
Node(TESCoil(TESCoilNum)%CondAirOutletNodeNum )%HumRat, &
'CalcTESCoilCoolingOnlyMode')
TESCoil(TESCoilNum)%CondInletTemp = Node(TESCoil(TESCoilNum)%CondAirInletNodeNum)%Temp
TESCoil(TESCoilNum)%Q_TES = TESCoil(TESCoilNum)%QdotTES * TimeStepSys * SecInHour
CALL UpdateTEStorage(TESCoilNum)
CALL UpdateColdWeatherProtection(TESCoilNum)
IF (TESCoil(TESCoilNum)%CondenserType == EvapCooled) THEN
CALL UpdateEvaporativeCondenserBasinHeater(TESCoilNum)
CALL UpdateEvaporativeCondenserWaterUse(TESCoilNum, Node(TESCoil(TESCoilNum)%CondAirInletNodeNum)%HumRat, &
TESCoil(TESCoilNum)%CondAirInletNodeNum )
ENDIF
RETURN
END SUBROUTINE CalcTESCoilDischargeOnlyMode