SUBROUTINE CalcDetailFlatFinCoolingCoil(CoilNum,CalcMode,FanOpMode,PartLoadRatio)
! SUBROUTINE INFORMATION:
! AUTHOR(S) Russell Taylor / Richard Liesen
! DATE WRITTEN Mar 1997
! MODIFIED Feb 2010, B. Nigusse, FSEC, corrected units inconsistency for tube and fins
! materials thermal conductivties. Now input values in the idf are in {W/(m.K)}
! RE-ENGINEERED Sept 1998
! PURPOSE OF THIS SUBROUTINE:
! This subroutine simulates a chilled water cooling coil. Provided with
! the coil geometry and the flow (i.e. air and water) inlet conditions,
! it will calculate the flow outlet conditions and the total and latent
! heat extraction rates from the air. The coil model has some limitations
! as noted in the code.
! METHODOLOGY EMPLOYED:
! successive substitution, solve coil as if all wet, then
! again if partly or entirely dry
! REFERENCES:
! First found in Type 12 from MODSIM, but now
! programmed directly from Elmahdy, A.H. and Mitalas, G.P. "A
! Simple Model for Cooling and Dehumidifying Coils for Use in
! Calculating Energy Requirements for Buildings" _ASHRAE
! Transactions_ Vol. 83, Part 2, pp. 103-117 (1977).
! OTHER NOTES:
! Routine was originally adapted for use in IBLAST by R.D. Taylor in l993.
! Subsequently rewritten and improved by J.C. Vanderzee in 1994
! Revised and further enanced by R.D. Taylor in Jan 1996
! Re-engineered for EnergyPlus by Richard Liesen PhD in 1998
! USE STATEMENTS:
USE General, ONLY: TrimSigDigits
IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
! SUBROUTINE ARGUMENT DEFINITIONS:
INTEGER, INTENT(IN) :: CoilNum
INTEGER, INTENT(IN) :: CalcMode
INTEGER, INTENT(IN) :: FanOpMode ! fan operating mode
REAL(r64), INTENT(IN) :: PartLoadRatio ! part-load ratio of heating coil
! SUBROUTINE PARAMETER DEFINITIONS:
INTEGER, PARAMETER :: MaxCoolCoilErrs = 5
REAL(r64), PARAMETER :: AirViscosity = 1.846d-5 ! Dynamic Viscosity of Air in kg/(m.s)
REAL(r64), PARAMETER :: ConvK = 1.0d-3 ! Unit conversion factor
REAL(r64), PARAMETER :: unity = 1.0d0
REAL(r64), PARAMETER :: zero = 0.0d0
REAL(r64), PARAMETER :: TubeFoulFactor = 5.0d-2 ! Inside tube fouling factor for water, in m2K/kW
! Changed from m2K/W to m2K/kW for consistency with the
! other parameters in "TubeFoulThermResis" calculation
! INTERFACE BLOCK SPECIFICATIONS
! na
! DERIVED TYPE DEFINITIONS
! na
! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
INTEGER :: CoefPointer
! INTEGER :: CoolCoilErrs = 0
INTEGER :: PartWetIterations
INTEGER :: WaterTempConvgLoop
LOGICAL :: CoilPartWetConvg
LOGICAL :: WaterTempConvg
REAL(r64) :: AirEnthAtRsdInletWaterTemp
REAL(r64) :: AirExitEnthlAtCoilSurfTemp
REAL(r64) :: AirExitCoilSurfTemp
REAL(r64) :: AirReynoldsNo
REAL(r64) :: AirEnthAtWetDryIntrfcSurfTemp
REAL(r64) :: AirSideDrySurfFilmCoef
REAL(r64) :: AirSideWetSurfFilmCoef
REAL(r64) :: AirWetDryInterfcTemp
REAL(r64) :: CoilToAirThermResistDrySurf
REAL(r64) :: CoilToAirThermResistWetSurf
REAL(r64) :: DryAirSpecHeat
REAL(r64) :: DryCoilCoeff1
REAL(r64) :: DryCoilCoeff
REAL(r64) :: DryCoilEfficiency
REAL(r64) :: DryFinEfficncy
REAL(r64) :: DryCoilInThermResist
REAL(r64) :: DrySideEffectiveWaterTemp
REAL(r64) :: EnterAirDewPoint
REAL(r64) :: EnterAirHumRatDiff
REAL(r64) :: WetDryInterSurfTempErrorLast
REAL(r64) :: WetDryInterSurfTempError
REAL(r64) :: expon
REAL(r64) :: FilmCoefEqnFactor
REAL(r64) :: FilmCoefReynldsCorrelatnFact
REAL(r64) :: FinToTotSurfAreaRatio
REAL(r64) :: InCoilSurfTemp
REAL(r64) :: InsdToOutsdThermResistRatio
REAL(r64) :: InSurfTempSatAirEnthl
REAL(r64) :: K1
REAL(r64) :: MeanWaterTemp
REAL(r64) :: MoistAirSpecificHeat
REAL(r64) :: OutCoilSurfTemp
REAL(r64) :: OutSurfTempSatAirEnthl
REAL(r64) :: RaisedInletWaterTemp
REAL(r64) :: RsdInletWaterTempSatAirHumRat
REAL(r64) :: ScaledAirMassFlowRate
REAL(r64) :: ScaledCoilAirThermResistWetSurf
REAL(r64) :: ScaledWaterSpecHeat
REAL(r64) :: ScaledWaterToTubeThermResist
REAL(r64) :: SensToTotEnthDiffRatio
REAL(r64) :: SurfAreaWet
REAL(r64) :: TubeFoulThermResist
REAL(r64) :: TubeWaterVel
REAL(r64) :: UACoilAllWet
REAL(r64) :: UACoilPartWet
REAL(r64) :: UADryCoil
REAL(r64) :: WaterToTubeThermResist
REAL(r64) :: WetAreaChange
REAL(r64) :: WetAreaLast
REAL(r64) :: WetCoilCoeff
REAL(r64) :: WetCoilFinEfficncy
REAL(r64) :: WetDryInterfcAirEnthl
REAL(r64) :: WetDryInterfcSurfTemp
REAL(r64) :: WetDryInterfcWaterTemp
REAL(r64) :: WetFinEfficncy
REAL(r64) :: WetSideEffctvWaterTemp
REAL(r64) :: y
REAL(r64) :: TempAirIn
REAL(r64) :: TempAirOut
REAL(r64) :: InletAirHumRat
REAL(r64) :: OutletAirHumRat
REAL(r64) :: InletAirEnthalpy
REAL(r64) :: OutletAirEnthalpy
REAL(r64) :: WaterMassFlowRate
REAL(r64) :: AirMassFlow
REAL(r64) :: TempWaterIn
REAL(r64) :: TempWaterOut
REAL(r64) :: TotWaterCoilLoad
REAL(r64) :: SenWaterCoilLoad
REAL(r64) :: AirDensity
REAL(r64) :: AirVelocity
REAL(r64) :: denom
REAL(r64) :: rho
REAL(r64) :: Cp
! Set derived type variables to shorter local variables
TempAirIn = WaterCoil(CoilNum)%InletAirTemp
InletAirHumRat = WaterCoil(CoilNum)%InletAirHumRat
TempWaterIn = WaterCoil(CoilNum)%InletWaterTemp
! adjust mass flow rates for cycling fan cycling coil operation
IF(FanOpMode .EQ. CycFanCycCoil)THEN
IF(PartLoadRatio .GT. 0.0d0)THEN
AirMassFlow = WaterCoil(CoilNum)%InletAirMassFlowRate/PartLoadRatio
WaterMassFlowRate = MIN(WaterCoil(CoilNum)%InletWaterMassFlowRate/PartLoadRatio, &
WaterCoil(CoilNum)%MaxWaterMassFlowRate)
ELSE
AirMassFlow = 0.0d0
WaterMassFlowRate = 0.0d0
END IF
ELSE
AirMassFlow = WaterCoil(CoilNum)%InletAirMassFlowRate
WaterMassFlowRate = WaterCoil(CoilNum)%InletWaterMassFlowRate
END IF
IF (WaterMassFlowRate.LT.WaterCoil(CoilNum)%MaxWaterMassFlowRate * MinWaterMassFlowFrac) THEN
WaterMassFlowRate = 0.0d0
END IF
IF (TempAirIn.LE.TempWaterIn) THEN
WaterMassFlowRate = 0.0d0
END IF
WetDryInterfcAirEnthl=0.0d0
OutletAirEnthalpy=0.0d0
InletAirEnthalpy=0.0d0
!Warning and error messages for large flow rates for the given user input geometry
AirDensity = PsyRhoAirFnPbTdbW(OutBaroPress,TempAirIn,InletAirHumRat, 'CalcDetailFlatFinCoolingCoil')
IF(AirMassFlow > (5.0*WaterCoil(CoilNum)%MinAirFlowArea/AirDensity) .AND. CoilWarningOnceFlag(CoilNum)) THEN
CALL ShowWarningError('Coil:Cooling:Water:DetailedGeometry in Coil ='//TRIM(WaterCoil(coilNum)%Name))
CALL ShowContinueError('Air Flow Rate Velocity has greatly exceeded upper design guidelines of ~2.5 m/s')
CALL ShowContinueError('Air MassFlowRate[kg/s]='//TRIM(TrimSigDigits(AirMassFlow,6)))
AirVelocity=AirMassFlow*AirDensity/WaterCoil(CoilNum)%MinAirFlowArea
CALL ShowContinueError('Air Face Velocity[m/s]='//TRIM(TrimSigDigits(AirVelocity,6)))
CALL ShowContinueError('Approximate MassFlowRate limit for Face Area[kg/s]=' &
//TRIM(TrimSigDigits(2.5d0*WaterCoil(CoilNum)%MinAirFlowArea/AirDensity,6)))
CALL ShowContinueError('Coil:Cooling:Water:DetailedGeometry could be resized/autosized to handle capacity')
CoilWarningOnceFlag(CoilNum) = .False.
Else IF(AirMassFlow > (44.7d0*WaterCoil(CoilNum)%MinAirFlowArea/AirDensity)) THEN
CALL ShowSevereError('Coil:Cooling:Water:DetailedGeometry in Coil ='//TRIM(WaterCoil(coilNum)%Name))
CALL ShowContinueError('Air Flow Rate Velocity is > 100MPH (44.7m/s) and simulation cannot continue')
CALL ShowContinueError('Air Mass Flow Rate[kg/s]='//TRIM(TrimSigDigits(AirMassFlow,6)))
AirVelocity=AirMassFlow*AirDensity/WaterCoil(CoilNum)%MinAirFlowArea
CALL ShowContinueError('Air Face Velocity[m/s]='//TRIM(TrimSigDigits(AirVelocity,6)))
CALL ShowContinueError('Approximate MassFlowRate limit for Face Area[kg/s]=' &
//TRIM(TrimSigDigits(2.5d0*WaterCoil(CoilNum)%MinAirFlowArea/AirDensity,6)))
CALL ShowFatalError('Coil:Cooling:Water:DetailedGeometry needs to be resized/autosized to handle capacity')
END IF
! If Coil is Scheduled ON then do the simulation
IF(((GetCurrentScheduleValue(WaterCoil(CoilNum)%SchedPtr) .gt. 0.0d0) .AND. (WaterMassFlowRate .GT. 0.0d0) &
.AND. (AirMassFlow .GE. MinAirMassFlow)) .OR. (CalcMode == DesignCalc)) Then
! transfer inputs to simulation variables and calculate
! known thermodynamic functions
! All coil calcs are done in KJoules. Convert to KJ here and then convert
! back to Joules at the end of the Subroutine.
DryAirSpecHeat = PsyCpAirFnWTdb(zero,TempAirIn, 'CalcDetailFlatFinCoolingCoil') * ConvK
MoistAirSpecificHeat = PsyCpAirFnWTdb(InletAirHumRat, TempAirIn, 'CalcDetailFlatFinCoolingCoil') * ConvK
InletAirEnthalpy = WaterCoil(CoilNum)%InletAirEnthalpy * ConvK
EnterAirDewPoint = PsyTdpFnWPb(InletAirHumRat, OutBaroPress, 'CalcDetailFlatFinCoolingCoil')
!
! Ratio of secondary (fin) to total (secondary plus primary) surface areas
FinToTotSurfAreaRatio = WaterCoil(CoilNum)%FinSurfArea / &
WaterCoil(CoilNum)%TotCoilOutsideSurfArea
!
! known water and air flow parameters:
!
rho = GetDensityGlycol(PlantLoop(WaterCoil(CoilNum)%WaterLoopNum)%FluidName, &
TempWaterIn, &
PlantLoop(WaterCoil(CoilNum)%WaterLoopNum)%FluidIndex, &
'CalcDetailFlatFinCoolingCoil')
! water flow velocity - assuming number of water circuits = NumOfTubesPerRow
TubeWaterVel = WaterMassFlowRate * 4.d0 / (WaterCoil(CoilNum)%NumOfTubesPerRow * &
rho * Pi * WaterCoil(CoilNum)%TubeInsideDiam * &
WaterCoil(CoilNum)%TubeInsideDiam)
! air mass flow rate per unit area
ScaledAirMassFlowRate = (1.d0 + InletAirHumRat) * AirMassFlow/WaterCoil(CoilNum)%MinAirFlowArea
! air flow Reynold's Number
AirReynoldsNo = WaterCoil(CoilNum)%CoilEffectiveInsideDiam * ScaledAirMassFlowRate / AirViscosity
!
! heat transfer coefficients and resistance components:
! inside (water)
WaterToTubeThermResist = WaterCoil(CoilNum)%TubeInsideDiam**0.2d0/(WaterCoil(CoilNum)%TotTubeInsideArea &
* 1.429d0 * TubeWaterVel**0.8d0)
! metal and fouling
TubeFoulThermResist = (0.5d0 * (WaterCoil(CoilNum)%TubeOutsideDiam - WaterCoil(CoilNum)%TubeInsideDiam) &
/ (ConvK * WaterCoil(CoilNum)%TubeThermConductivity) + TubeFoulFactor) / &
WaterCoil(CoilNum)%TotTubeInsideArea
!
! outside (wet and dry coil)
!
FilmCoefEqnFactor = WaterCoil(CoilNum)%GeometryCoef1 * AirReynoldsNo**WaterCoil(CoilNum)%GeometryCoef2
! (1.23 is 1/Prandt(air)**(2/3))
AirSideDrySurfFilmCoef = 1.23d0 * FilmCoefEqnFactor * MoistAirSpecificHeat * &
ScaledAirMassFlowRate
FilmCoefReynldsCorrelatnFact = 1.425d0 + AirReynoldsNo * (-0.51d-3 + &
AirReynoldsNo * 0.263d-6)
!
! NOTE: the equation for FilmCoefReynldsCorrelatnFact generates valid results over
! a limited range of Air Reynolds Numbers as indicated by
! deleted code below. Reynolds Numbers outside this range
! may result in inaccurate results or failure of the coil
! simulation to obtain a solution
!
! Deleted code by J.C. Vanderzee
!
AirSideWetSurfFilmCoef = FilmCoefReynldsCorrelatnFact * AirSideDrySurfFilmCoef
!-- need wet fin efficiency for outside
RaisedInletWaterTemp = TempWaterIn + 0.5d0
! By this statement the Inlet Air enthalpy will never be equal to AirEnthAtRsdInletWaterTemp
If((RaisedInletWaterTemp-TempAirIn) .LT. 0.000001d0) Then
RaisedInletWaterTemp=TempWaterIn+0.3d0
End If
IF (TempAirIn < RaisedInletWaterTemp) THEN
RaisedInletWaterTemp=TempAirIn - .3d0
ENDIF
RsdInletWaterTempSatAirHumRat = PsyWFnTdbRhPb(RaisedInletWaterTemp, unity, OutBaroPress, 'CalcDetailFlatFinCoolingCoil')
AirEnthAtRsdInletWaterTemp = PsyHFnTdbW(RaisedInletWaterTemp, &
RsdInletWaterTempSatAirHumRat, 'CalcDetailFlatFinCoolingCoil') * ConvK
SensToTotEnthDiffRatio = DryAirSpecHeat * (TempAirIn - RaisedInletWaterTemp) / &
(InletAirEnthalpy - AirEnthAtRsdInletWaterTemp)
EnterAirHumRatDiff = InletAirHumRat - RsdInletWaterTempSatAirHumRat
DryFinEfficncy = 0.5d0 * (WaterCoil(CoilNum)%EffectiveFinDiam - WaterCoil(CoilNum)%TubeOutsideDiam) * &
SQRT(2.d0 * AirSideWetSurfFilmCoef / (ConvK * WaterCoil(CoilNum)%FinThermConductivity * &
WaterCoil(CoilNum)%FinThickness))
IF (EnterAirHumRatDiff .LT. 0) THEN
! note that this condition indicates dry coil
EnterAirHumRatDiff = -EnterAirHumRatDiff
SensToTotEnthDiffRatio = abs(SensToTotEnthDiffRatio)
END IF
IF (EnterAirHumRatDiff > 1.0d0) EnterAirHumRatDiff =1.0d0
IF (EnterAirHumRatDiff < 0.00001d0) EnterAirHumRatDiff =0.00001d0
IF (DryFinEfficncy > 1.0d0) DryFinEfficncy=1.0d0
IF (DryFinEfficncy < 0.00001d0) DryFinEfficncy=0.00001d0
IF (TempAirIn .GT. 48.d0/1.8d0) THEN
WetFinEfficncy=EXP(-0.41718d0) * SensToTotEnthDiffRatio**(0.09471d0) * &
EnterAirHumRatDiff**(0.0108d0) * DryFinEfficncy**(-0.50303d0)
ELSE
WetFinEfficncy=EXP(-0.3574d0) * SensToTotEnthDiffRatio**(0.16081d0) * &
EnterAirHumRatDiff**(0.01995d0) * DryFinEfficncy**(-0.52951d0)
END IF
IF (WetFinEfficncy > 1.0d0) WetFinEfficncy=0.99d0
IF (WetFinEfficncy < 0.0d0) WetFinEfficncy=0.001d0
!
! wet coil fin efficiency
!
WetCoilFinEfficncy = 1.d0 + FinToTotSurfAreaRatio * (WetFinEfficncy - 1.d0)
!
! wet coil outside thermal resistance = [1/UA] (wet coil)
!
CoilToAirThermResistWetSurf = MoistAirSpecificHeat / (WaterCoil(CoilNum)%TotCoilOutsideSurfArea * &
AirSideWetSurfFilmCoef * WetCoilFinEfficncy)
!-- and dry fin efficiency
DryFinEfficncy = 0.5d0 * (WaterCoil(CoilNum)%EffectiveFinDiam - WaterCoil(CoilNum)%TubeOutsideDiam) * &
SQRT(2.d0 * AirSideDrySurfFilmCoef / (ConvK * WaterCoil(CoilNum)%FinThermConductivity * &
WaterCoil(CoilNum)%FinThickness))
!
! NOTE: The same caveats on the validity of the FilmCoefReynldsCorrelatnFact equation
! hold for the DryFinEfficncy equation. Values of DryFinEfficncy outside the
! specified range of validity are not guaranteed to
! produce results
!
! Deleted code by J.C. Vanderzee
!
!
! dry coil fin efficiency
!
DryCoilEfficiency = 0.0d0
DO CoefPointer=1,5
DryCoilEfficiency = DryCoilEfficiency + WaterCoil(CoilNum)%DryFinEfficncyCoef(CoefPointer) * &
DryFinEfficncy**(CoefPointer-1)
END DO ! CoefPointer
DryCoilEfficiency = 1.d0 + FinToTotSurfAreaRatio * (DryCoilEfficiency - 1.d0)
!
! dry coil outside thermal resistance = [1/UA] (dry coil)
!
CoilToAirThermResistDrySurf = 1.d0 / (WaterCoil(CoilNum)%TotCoilOutsideSurfArea * AirSideDrySurfFilmCoef * &
DryCoilEfficiency)
!
! definitions made to simplify some of the expressions used below
Cp = GetSpecificHeatGlycol(PlantLoop(WaterCoil(CoilNum)%WaterLoopNum)%FluidName, &
TempWaterIn, &
PlantLoop(WaterCoil(CoilNum)%WaterLoopNum)%FluidIndex, &
'CalcDetailFlatFinCoolingCoil')
ScaledWaterSpecHeat = WaterMassFlowRate * Cp * ConvK / &
AirMassFlow
DryCoilCoeff1 = 1.0d0 / (AirMassFlow * MoistAirSpecificHeat) - 1.0d0/ &
(WaterMassFlowRate * Cp * ConvK)
!
! perform initialisations for all wet solution
!
WetSideEffctvWaterTemp = WaterCoil(CoilNum)%MeanWaterTempSaved + &
(TempWaterIn - WaterCoil(CoilNum)%InWaterTempSaved)
WaterTempConvgLoop = 0
WaterTempConvg = .FALSE.
!
! Loop to solve coil as if all wet, converges on MeanWaterTemp eq WetSideEffctvWaterTemp
! if conv=.TRUE. at any time program exits loop and proceeds
! to part wet / part dry solution
!
DO WHILE (WaterTempConvgLoop .LT. 8 .and. .not. WaterTempConvg)
WaterTempConvgLoop = WaterTempConvgLoop + 1
ScaledWaterToTubeThermResist = WaterToTubeThermResist/(1.d0 + 0.0146d0 * &
WetSideEffctvWaterTemp)
ScaledCoilAirThermResistWetSurf = CoilToAirThermResistWetSurf / WaterCoil(CoilNum)%SatEnthlCurveSlope
UACoilAllWet = 1.0d0 / (WaterCoil(CoilNum)%SatEnthlCurveSlope * (TubeFoulThermResist + &
ScaledWaterToTubeThermResist + ScaledCoilAirThermResistWetSurf))
!
! prevents floating point error when taking exponential
! of a very large number
!
expon = UACoilAllWet * (1.0d0 / AirMassFlow - WaterCoil(CoilNum)%SatEnthlCurveSlope / &
(WaterMassFlowRate * Cp * ConvK))
IF (expon < 20) THEN !CR7189 changed from ABS(expon) < 20
! negative expon can happen, but lead to tiny WetCoilCoef that aren't a problem
WetCoilCoeff = EXP(expon)
! following appears similar to eq. 320 in Eng Ref but neglects K1 term
TempWaterOut =((1.0d0 - WetCoilCoeff) * (InletAirEnthalpy - WaterCoil(CoilNum)%SatEnthlCurveConstCoef) + &
WetCoilCoeff * TempWaterIn * &
(WaterCoil(CoilNum)%SatEnthlCurveSlope - ScaledWaterSpecHeat)) / &
(WaterCoil(CoilNum)%SatEnthlCurveSlope - WetCoilCoeff * ScaledWaterSpecHeat)
ELSE
! following appears to be same as above with equation simplified to use only significant terms when WetCoilCoeff very large
TempWaterOut = ((InletAirEnthalpy - WaterCoil(CoilNum)%SatEnthlCurveConstCoef) - &
TempWaterIn * (WaterCoil(CoilNum)%SatEnthlCurveSlope - &
ScaledWaterSpecHeat)) / ScaledWaterSpecHeat
END IF
! above is inverted form of WaterMassFlowRate*cpw*(TempWaterOut-TempWaterIn) = UA(LMHD)
! note simplification that hsat = WaterCoil(CoilNum)%SatEnthlCurveConstCoef + &
! WaterCoil(CoilNum)%SatEnthlCurveSlope*WetSideEffctvWaterTemp
MeanWaterTemp = 0.5d0 * (TempWaterIn + TempWaterOut)
OutletAirEnthalpy = InletAirEnthalpy - (TempWaterOut - TempWaterIn) * ScaledWaterSpecHeat
InsdToOutsdThermResistRatio = (TubeFoulThermResist + ScaledWaterToTubeThermResist) / &
ScaledCoilAirThermResistWetSurf
InCoilSurfTemp = UACoilAllWet * ScaledCoilAirThermResistWetSurf * &
(WaterCoil(CoilNum)%SatEnthlCurveSlope * TempWaterIn + &
(OutletAirEnthalpy - WaterCoil(CoilNum)%SatEnthlCurveConstCoef) * &
InsdToOutsdThermResistRatio)
OutCoilSurfTemp = UACoilAllWet * ScaledCoilAirThermResistWetSurf * &
(WaterCoil(CoilNum)%SatEnthlCurveSlope * TempWaterOut + &
(InletAirEnthalpy - WaterCoil(CoilNum)%SatEnthlCurveConstCoef) * &
InsdToOutsdThermResistRatio)
IF (abs(MeanWaterTemp - WetSideEffctvWaterTemp) .GT. 0.01d0) THEN
WetSideEffctvWaterTemp = MeanWaterTemp
InSurfTempSatAirEnthl = PsyHFnTdbRhPb(InCoilSurfTemp, unity, OutBaroPress, 'CalcDetailFlatFinCoolingCoil') * ConvK
OutSurfTempSatAirEnthl = PsyHFnTdbRhPb(OutCoilSurfTemp, unity, OutBaroPress, 'CalcDetailFlatFinCoolingCoil') *ConvK
WaterCoil(CoilNum)%SatEnthlCurveSlope = (OutSurfTempSatAirEnthl - &
InSurfTempSatAirEnthl) / (OutCoilSurfTemp - &
InCoilSurfTemp)
WaterCoil(CoilNum)%SatEnthlCurveConstCoef = InSurfTempSatAirEnthl - WaterCoil(CoilNum)%SatEnthlCurveSlope * &
InCoilSurfTemp
ELSE
WaterTempConvg = .TRUE.
END IF
END DO ! End of iteration loop to get MeanWaterTemp=WetSideEffctvWaterTemp
!
! if 8 CoolCoilErrs are reached without convergence and the
! predicted coil surface temperature at the outlet is less than
! the dew point coil is apparently all wet but a solution
! cannot be obtained
!
IF (.not. WaterTempConvg .and. .not. WarmupFlag .and. (OutCoilSurfTemp .LT. EnterAirDewPoint)) THEN
CALL ShowRecurringWarningErrorAtEnd(TRIM(WaterCoil(CoilNum)%Name)// &
' not converged (8 iterations) due to "Wet Convergence" conditions.',WaterTempCoolCoilErrs(CoilNum), &
abs(MeanWaterTemp - WetSideEffctvWaterTemp),abs(MeanWaterTemp - WetSideEffctvWaterTemp))
! CoolCoilErrs = CoolCoilErrs + 1
! IF (CoolCoilErrs .LE. MaxCoolCoilErrs) THEN
! CALL ShowWarningError('tp12c0: not converged in 8 CoolCoilErrs')
! END IF
END IF
WaterCoil(CoilNum)%MeanWaterTempSaved = MeanWaterTemp
!
! now simulate wet dry coil - test outlet condition from all
! wet case to give an idea of the expected solution
!
PartWetIterations = 0
WetDryInterSurfTempError = 0.0d0
CoilPartWetConvg = .FALSE.
!
! Surface temp at coil water outlet (air inlet) is less than
! the dew point - Coil must be completely wet so no need to
! simulate wet/dry case
!
IF (OutCoilSurfTemp .LT. EnterAirDewPoint) THEN
CoilPartWetConvg = .TRUE.
WaterCoil(CoilNum)%SurfAreaWetFraction = 1.0d0
TotWaterCoilLoad = AirMassFlow*(InletAirEnthalpy - OutletAirEnthalpy)
AirWetDryInterfcTemp = TempAirIn
WetDryInterfcAirEnthl = InletAirEnthalpy
!
! Surface temperature at coil water inlet is greater than the
! dewpoint - coil cannot be all wet but may be all dry -
! initialise with all dry solution
!
ELSE IF (InCoilSurfTemp .GT. EnterAirDewPoint) THEN
SurfAreaWet = 0.0d0
WaterCoil(CoilNum)%SurfAreaWetFraction = 0.0d0
WetDryInterfcWaterTemp = TempWaterIn
TempWaterOut = WaterCoil(CoilNum)%OutWaterTempSaved + (TempWaterIn - WaterCoil(CoilNum)%InWaterTempSaved)
WetAreaLast = 0.05d0 * WaterCoil(CoilNum)%TotCoilOutsideSurfArea
!
! General case - must be part-wet/part-dry - initialise
! accordingly with some non-zero wet area
!
ELSE
IF (WaterCoil(CoilNum)%SurfAreaWetSaved .ne. 0.0d0) THEN
SurfAreaWet = WaterCoil(CoilNum)%SurfAreaWetSaved
ELSE
SurfAreaWet = 0.8d0 * WaterCoil(CoilNum)%TotCoilOutsideSurfArea * (EnterAirDewPoint - &
InCoilSurfTemp) / (OutCoilSurfTemp - InCoilSurfTemp)
END IF
WetDryInterfcWaterTemp = TempWaterIn + EnterAirDewPoint - &
InCoilSurfTemp
WetAreaLast = 0.0d0
END IF
! Loop to solve partly wet coil, converges on wet area and
! boundary temperature at dew point
! Dry coil is special case with zero wet area, converges on
! mean water temperature
DO WHILE (PartWetIterations .LT. 40 .and. .not. CoilPartWetConvg)
PartWetIterations = PartWetIterations + 1
!
! effective water temp on dry side of coil
!
DrySideEffectiveWaterTemp = 0.5d0 * (TempWaterOut + WetDryInterfcWaterTemp)
!
! tube inside thermal resistance
!
DryCoilInThermResist = WaterToTubeThermResist / (1.0d0 + 0.0146d0 * DrySideEffectiveWaterTemp)
!
! overall UA, from water to air, of dry portion of coil
!
UADryCoil = (WaterCoil(CoilNum)%TotCoilOutsideSurfArea - SurfAreaWet) / (WaterCoil(CoilNum)%TotCoilOutsideSurfArea * &
(TubeFoulThermResist + DryCoilInThermResist + CoilToAirThermResistDrySurf))
! This is a numerical trap for a very small number in the EXP function that is approaching zero
If((UADryCoil*DryCoilCoeff1) .lt. -60.0d0) Then
DryCoilCoeff = 0.0d0
Else
DryCoilCoeff = EXP(UADryCoil*DryCoilCoeff1)
End If
K1 = WaterMassFlowRate * Cp * ConvK * (DryCoilCoeff - 1.0d0) / &
(WaterMassFlowRate * Cp * ConvK * DryCoilCoeff &
- AirMassFlow * MoistAirSpecificHeat)
IF (SurfAreaWet .ne. 0) THEN
WaterCoil(CoilNum)%SurfAreaWetFraction = SurfAreaWet / WaterCoil(CoilNum)%TotCoilOutsideSurfArea
!
! effective water temp on wet side of coil
!
WetSideEffctvWaterTemp = 0.5d0 * (TempWaterIn + WetDryInterfcWaterTemp)
!
! tube inside thermal resistance
!
ScaledWaterToTubeThermResist = WaterToTubeThermResist / (1.0d0 + 0.0146d0 * WetSideEffctvWaterTemp)
ScaledCoilAirThermResistWetSurf = CoilToAirThermResistWetSurf / &
WaterCoil(CoilNum)%EnthVsTempCurveAppxSlope
!
! overall UA, from water to air, of wet portion of coil
!
UACoilAllWet = 1.0d0 / (WaterCoil(CoilNum)%EnthVsTempCurveAppxSlope * (TubeFoulThermResist + &
ScaledWaterToTubeThermResist + &
ScaledCoilAirThermResistWetSurf))
UACoilPartWet = WaterCoil(CoilNum)%SurfAreaWetFraction * UACoilAllWet
expon=UACoilPartWet * (1.0d0 / AirMassFlow - WaterCoil(CoilNum)%EnthVsTempCurveAppxSlope / &
(WaterMassFlowRate * Cp * ConvK))
!
! prevents floating point error when taking exponential
! of a very large number
!
IF (expon.LT.20) THEN
WetCoilCoeff = EXP(expon)
! write(outputfiledebug,*) ' wcc=',wetcoilcoeff
denom=(WaterCoil(CoilNum)%EnthVsTempCurveAppxSlope - &
WetCoilCoeff * ScaledWaterSpecHeat - (1.0d0 - WetCoilCoeff) * K1 * &
MoistAirSpecificHeat)
! write(outputfiledebug,*) ' denom=',denom
! WetDryInterfcWaterTemp = ((1.0 - WetCoilCoeff) * (InletAirEnthalpy - WaterCoil(CoilNum)%EnthVsTempCurveConst - K1 * &
! MoistAirSpecificHeat * TempAirIn) + WetCoilCoeff * &
! TempWaterIn * (WaterCoil(CoilNum)%EnthVsTempCurveAppxSlope - &
! ScaledWaterSpecHeat)) / (WaterCoil(CoilNum)%EnthVsTempCurveAppxSlope - &
! WetCoilCoeff * ScaledWaterSpecHeat - (1.0 - WetCoilCoeff) * K1 * &
! MoistAirSpecificHeat)
WetDryInterfcWaterTemp = ((1.0d0 - WetCoilCoeff) * (InletAirEnthalpy - WaterCoil(CoilNum)%EnthVsTempCurveConst - K1 * &
MoistAirSpecificHeat * TempAirIn) + WetCoilCoeff * &
TempWaterIn * (WaterCoil(CoilNum)%EnthVsTempCurveAppxSlope - &
ScaledWaterSpecHeat)) / denom
ELSE
!
! approximation to equation for WetDryInterfcWaterTemp when WetCoilCoeff-->inf.
!
WetDryInterfcWaterTemp = (TempWaterIn * (WaterCoil(CoilNum)%EnthVsTempCurveAppxSlope - &
ScaledWaterSpecHeat) - &
(InletAirEnthalpy - WaterCoil(CoilNum)%EnthVsTempCurveConst - K1 * &
MoistAirSpecificHeat * TempAirIn)) &
/ (K1 * MoistAirSpecificHeat - ScaledWaterSpecHeat)
END IF
END IF
!
! air temperature at wet-dry interface
!
AirWetDryInterfcTemp = TempAirIn - (TempAirIn - &
WetDryInterfcWaterTemp) * K1
!
! coil surface temperature at wet-dry interface
!
WetDryInterfcSurfTemp = WetDryInterfcWaterTemp + (AirWetDryInterfcTemp - &
WetDryInterfcWaterTemp) * (TubeFoulThermResist + &
DryCoilInThermResist) / (TubeFoulThermResist + DryCoilInThermResist + &
CoilToAirThermResistDrySurf)
IF (SurfAreaWet .ne. 0) THEN
WetDryInterfcAirEnthl = InletAirEnthalpy - MoistAirSpecificHeat * &
(TempAirIn - AirWetDryInterfcTemp)
!
! conservation of energy - wet portion of coil
!
OutletAirEnthalpy = WetDryInterfcAirEnthl - WaterMassFlowRate * &
Cp * ConvK * &
(WetDryInterfcWaterTemp - TempWaterIn) / &
AirMassFlow
!
! ratio of inside to outside thermal resistance
!
InsdToOutsdThermResistRatio = (TubeFoulThermResist + &
ScaledWaterToTubeThermResist) / &
ScaledCoilAirThermResistWetSurf
!
! coil surface temperature at water inlet (air outlet)
!
InCoilSurfTemp = UACoilAllWet * ScaledCoilAirThermResistWetSurf * &
(WaterCoil(CoilNum)%EnthVsTempCurveAppxSlope * TempWaterIn + (OutletAirEnthalpy - &
WaterCoil(CoilNum)%EnthVsTempCurveConst) * &
InsdToOutsdThermResistRatio)
WetDryInterSurfTempErrorLast = WetDryInterSurfTempError
!
! in part-wet/part-dry solution EnterAirDewPoint=WetDryInterfcSurfTemp drives WetDryInterSurfTempError->0
!
WetDryInterSurfTempError = EnterAirDewPoint - WetDryInterfcSurfTemp
ELSE
!
! dry coil solution
!
WetDryInterfcAirEnthl = 0.0d0
OutletAirEnthalpy = InletAirEnthalpy - MoistAirSpecificHeat * &
(TempAirIn - AirWetDryInterfcTemp)
END IF
!
! total cooling = change in air enmthalpy across coil
!
TotWaterCoilLoad = AirMassFlow * (InletAirEnthalpy - &
OutletAirEnthalpy)
!
! conservation of energy on water stream gives water outlet
! temperature
!
TempWaterOut = WaterMassFlowRate * Cp * ConvK ! Temp for next calc
TempWaterOut = MIN(TempWaterIn + TotWaterCoilLoad/TempWaterOut, TempAirIn)
!
! update estimate of coil wet area
!
IF (SurfAreaWet .EQ. 0) THEN
MeanWaterTemp = 0.5d0 * (TempWaterOut + WetDryInterfcWaterTemp)
IF (EnterAirDewPoint .GT. WetDryInterfcSurfTemp) THEN
SurfAreaWet = 0.5d0 * WetAreaLast
ELSE IF (ABS(MeanWaterTemp - DrySideEffectiveWaterTemp) .LE. .00002d0) THEN
CoilPartWetConvg = .TRUE.
END IF
ELSE IF(ABS(WetDryInterSurfTempError) .GT. .00002d0 .OR. ABS(SurfAreaWet - WetAreaLast) / &
WaterCoil(CoilNum)%TotCoilOutsideSurfArea .GT. .00001d0)THEN
IF (WetAreaLast .EQ. 0) THEN
WetAreaLast = SurfAreaWet
SurfAreaWet = SurfAreaWet + 0.4d0 * WaterCoil(CoilNum)%TotCoilOutsideSurfArea * WetDryInterSurfTempError / &
(OutCoilSurfTemp - InCoilSurfTemp)
ELSE IF (WetDryInterSurfTempError .ne. WetDryInterSurfTempErrorLast) THEN
WetAreaChange = SurfAreaWet - WetAreaLast
WetAreaLast = SurfAreaWet
SurfAreaWet = SurfAreaWet - 0.8d0 * WetDryInterSurfTempError * WetAreaChange / &
(WetDryInterSurfTempError - WetDryInterSurfTempErrorLast)
END IF
IF (SurfAreaWet .GE. WaterCoil(CoilNum)%TotCoilOutsideSurfArea) THEN
SurfAreaWet = WaterCoil(CoilNum)%TotCoilOutsideSurfArea
MeanWaterTemp = 0.5d0 * (TempWaterIn + WetDryInterfcWaterTemp)
IF (WetAreaLast .EQ. WaterCoil(CoilNum)%TotCoilOutsideSurfArea .and. abs(MeanWaterTemp - &
WetSideEffctvWaterTemp) .LE. .00002d0) THEN
CoilPartWetConvg = .TRUE.
END IF
END IF
IF (SurfAreaWet .LE. 0) THEN
SurfAreaWet = 0.0d0
WaterCoil(CoilNum)%SurfAreaWetFraction = 0.0d0
WetDryInterfcWaterTemp = TempWaterIn
END IF
InSurfTempSatAirEnthl = PsyHFnTdbRhPb(InCoilSurfTemp, unity, OutBaroPress, 'CalcDetailFlatFinCoolingCoil') * ConvK
IF ((EnterAirDewPoint - InCoilSurfTemp) .GE. .0001d0) THEN
AirEnthAtWetDryIntrfcSurfTemp = PsyHFnTdbRhPb(EnterAirDewPoint, unity, OutBaroPress, &
'CalcDetailFlatFinCoolingCoil')*ConvK
WaterCoil(CoilNum)%EnthVsTempCurveAppxSlope = (AirEnthAtWetDryIntrfcSurfTemp - &
InSurfTempSatAirEnthl) / &
(EnterAirDewPoint - InCoilSurfTemp)
ELSE
AirEnthAtWetDryIntrfcSurfTemp = PsyHFnTdbRhPb(InCoilSurfTemp + 0.0001d0, unity, &
OutBaroPress, 'CalcDetailFlatFinCoolingCoil') * ConvK
WaterCoil(CoilNum)%EnthVsTempCurveAppxSlope = (AirEnthAtWetDryIntrfcSurfTemp - &
InSurfTempSatAirEnthl) / 0.0001d0
END IF
WaterCoil(CoilNum)%EnthVsTempCurveConst = InSurfTempSatAirEnthl - WaterCoil(CoilNum)%EnthVsTempCurveAppxSlope * &
InCoilSurfTemp
ELSE
CoilPartWetConvg = .TRUE.
END IF
END DO
!
! error checking to see if convergence has been achieved
!
IF (.not. CoilPartWetConvg .and. .not. WarmupFlag) THEN
CALL ShowRecurringWarningErrorAtEnd(TRIM(WaterCoil(CoilNum)%Name)// &
' not converged (40 iterations) due to "Partial Wet Convergence" conditions.',PartWetCoolCoilErrs(CoilNum))
! CoolCoilErrs = CoolCoilErrs + 1
! IF (CoolCoilErrs .LE. MaxCoolCoilErrs) THEN
! CALL ShowWarningError('tp12c0: not converged in 20 CoolCoilErrs')
! END IF
END IF
IF (WaterCoil(CoilNum)%SurfAreaWetFraction .GT. 0 .and. WaterCoil(CoilNum)%SurfAreaWetFraction .LT. 1) THEN
WaterCoil(CoilNum)%SurfAreaWetSaved= SurfAreaWet
END IF
!
! calculate TempAirOut, OutletAirHumRat, and SensCoolRate based on equations from
! TYPE12 and the ASHRAE toolkit
!
IF (WaterCoil(CoilNum)%SurfAreaWetFraction .EQ. 0) THEN
!
! dry coil
!
TempAirOut = TempAirIn - TotWaterCoilLoad / (AirMassFlow * &
MoistAirSpecificHeat)
OutletAirHumRat = InletAirHumRat
SenWaterCoilLoad = TotWaterCoilLoad
ELSE
!
! coil effectiveness
expon = WaterCoil(CoilNum)%SurfAreaWetFraction / (CoilToAirThermResistWetSurf * AirMassFlow)
y = 0.0d0
IF (expon .LT. 20.d0) y=EXP(-expon)
AirExitEnthlAtCoilSurfTemp = WetDryInterfcAirEnthl - (WetDryInterfcAirEnthl - &
OutletAirEnthalpy) / (1.0d0 - y)
AirExitCoilSurfTemp=AirExitEnthlAtCoilSurfTemp/ConvK ! TEmporary calc
AirExitCoilSurfTemp=PsyTsatFnHPb(AirExitCoilSurfTemp,OutBaroPress)
!
! Implementation of epsilon*NTU method
TempAirOut = AirExitCoilSurfTemp + (AirWetDryInterfcTemp - AirExitCoilSurfTemp) * y
OutletAirHumRat = PsyWFnTdbH(TempAirOut, 1000.d0 * OutletAirEnthalpy, 'CalcDetailFlatFinCoolingCoil')
SenWaterCoilLoad = AirMassFlow * (PsyCpAirFnWTdb(InletAirHumRat, TempAirIn, 'CalcDetailFlatFinCoolingCoil') * TempAirIn - &
PsyCpAirFnWTdb(OutletAirHumRat, TempAirOut, 'CalcDetailFlatFinCoolingCoil') * &
TempAirOut) * ConvK
END IF
IF(FanOpMode .EQ. CycFanCycCoil)THEN
TotWaterCoilLoad = TotWaterCoilLoad*PartLoadRatio
SenWaterCoilLoad = SenWaterCoilLoad*PartLoadRatio
END IF
! Set the outlet conditions
WaterCoil(CoilNum)%TotWaterCoolingCoilRate = TotWaterCoilLoad * 1000.0d0
WaterCoil(CoilNum)%SenWaterCoolingCoilRate = SenWaterCoilLoad * 1000.0d0
WaterCoil(CoilNum)%OutletAirTemp = TempAirOut
WaterCoil(CoilNum)%OutletWaterTemp = TempWaterOut
WaterCoil(CoilNum)%OutletAirEnthalpy = OutletAirEnthalpy * 1000.0d0
WaterCoil(CoilNum)%OutletAirHumRat = OutletAirHumRat
!The CoolingCoilLoad is the change in the enthalpy of the water
WaterCoil(CoilNum)%OutletWaterEnthalpy = WaterCoil(CoilNum)%InletWaterEnthalpy + &
WaterCoil(CoilNum)%TotWaterCoolingCoilRate/WaterCoil(CoilNum)%InletWaterMassFlowRate
!This WaterCoil does not change the Mass Flow across the component
WaterCoil(CoilNum)%OutletAirMassFlowRate = WaterCoil(CoilNum)%InletAirMassFlowRate
WaterCoil(CoilNum)%OutletWaterMassFlowRate = WaterCoil(CoilNum)%InletWaterMassFlowRate
Else
! If Coil is scheduled OFF then Outlet conditions are set to Inlet Conditions
WaterCoil(CoilNum)%TotWaterCoolingCoilRate = 0.0d0
WaterCoil(CoilNum)%SenWaterCoolingCoilRate = 0.0d0
TempAirOut=TempAirIn
TempWaterOut =TempWaterIn
! set the outlet conditions to the coil derived type
WaterCoil(CoilNum)%OutletAirTemp = TempAirOut
WaterCoil(CoilNum)%OutletWaterTemp = TempWaterOut
WaterCoil(CoilNum)%OutletAirEnthalpy = WaterCoil(CoilNum)%InletAirEnthalpy
WaterCoil(CoilNum)%OutletAirHumRat = WaterCoil(CoilNum)%InletAirHumRat
!The CoolingCoilLoad is the change in the enthalpy of the water
WaterCoil(CoilNum)%OutletWaterEnthalpy = WaterCoil(CoilNum)%InletWaterEnthalpy
!This WaterCoil does not change the Mass Flow across the component
WaterCoil(CoilNum)%OutletAirMassFlowRate = WaterCoil(CoilNum)%InletAirMassFlowRate
WaterCoil(CoilNum)%OutletWaterMassFlowRate = 0.0d0
End If
!Save some of the Values for next Time step
WaterCoil(CoilNum)%InWaterTempSaved = TempWaterIn
WaterCoil(CoilNum)%OutWaterTempSaved = TempWaterOut
RETURN
END SUBROUTINE CalcDetailFlatFinCoolingCoil