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) | :: | WaterThermalTankNum |
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 CalcWaterThermalTankStratified(WaterThermalTankNum)
! SUBROUTINE INFORMATION:
! AUTHOR Peter Graham Ellis
! DATE WRITTEN January 2007
! MODIFIED na
! Nov 2011, BAN; modified the use and source outlet temperature calculation
!
! RE-ENGINEERED na
! PURPOSE OF THIS SUBROUTINE:
! Simulates a stratified, multi-node water heater tank with up to two heating elements.
! METHODOLOGY EMPLOYED:
! This model uses a numerical calculation based on the forward Euler method. A heat balance is calculated for each
! node at a sub time step interval of one second. Temperatures and energies change dynamically over the system
! time step. Final node temperatures are reported as final instantaneous values as well as averages over the
! time step. Heat transfer rates are averages over the time step.
! USE STATEMENTS:
USE DataGlobals, ONLY: TimeStep, TimeStepZone, HourOfDay
USE DataHVACGlobals, ONLY: SysTimeElapsed, TimeStepSys
USE FluidProperties, ONLY: GetDensityGlycol, GetSpecificHeatGlycol
IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
! SUBROUTINE ARGUMENT DEFINITIONS:
INTEGER, INTENT(IN) :: WaterThermalTankNum ! Water Heater being simulated
! SUBROUTINE PARAMETER DEFINITIONS:
REAL(r64), PARAMETER :: dt = 1.0d0 ! Sub time step interval (s)
! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
REAL(r64) :: TimeElapsed ! Fraction of the current hour that has elapsed (h)
REAL(r64) :: SecInTimeStep ! Seconds in one timestep (s)
REAL(r64) :: TimeRemaining ! Time remaining in the current timestep (s)
INTEGER :: NumNodes ! Number of stratified nodes
INTEGER :: NodeNum ! Node number index
REAL(r64) :: NodeMass ! Mass of water in a node (kg)
REAL(r64) :: NodeTemp ! Instantaneous node temperature (C)
REAL(r64) :: TempUp ! Temperature of the upper node (C)
REAL(r64) :: TempDn ! Temperature of the lower node (C)
REAL(r64) :: InvMixUp ! Inversion mixing rate with the upper node (kg/s)
REAL(r64) :: InvMixDn ! Inversion mixing rate with the lower node (kg/s)
REAL(r64) :: Cp ! Specific heat of water (J/kg K)
REAL(r64) :: LossCoeff ! Loss coefficient to ambient environment (W/K)
REAL(r64) :: AmbientTemp ! Current ambient air temperature around tank (C)
REAL(r64) :: SetPointTemp1 ! Current set point temperature for heater 1 (C)
REAL(r64) :: SetPointTemp2 ! Current set point temperature for heater 2 (C)
REAL(r64) :: MinTemp1 ! Minimum tank temperature (SetPointTemp1 - DeadbandDeltaTemp1) (C)
REAL(r64) :: MinTemp2 ! Minimum tank temperature (SetPointTemp2 - DeadbandDeltaTemp2) (C)
REAL(r64) :: MaxTemp ! Maximum tank temperature before venting (C)
REAL(r64) :: Quse ! Heating rate due to use side mass flow (W)
REAL(r64) :: Qsource ! Heating rate due to source side mass flow (W)
REAL(r64) :: Qcond ! Heating rate due to vertical conduction between nodes
REAL(r64) :: Qflow ! Heating rate due to fluid flow between inlet and outlet nodes
REAL(r64) :: Qmix ! Heating rate due to temperature inversion mixing between nodes
REAL(r64) :: Qloss ! Heating rate due to ambient environment (W)
REAL(r64) :: Qlosszone ! Heating rate of fraction of losses added to the zone as a gain (W)
REAL(r64) :: Qheat ! Net heating rate for non-temp dependent sources, i.e. heater and parasitics (W)
REAL(r64) :: Qheater1 ! Heating rate of burner or electric heating element 1 (W)
REAL(r64) :: Qheater2 ! Heating rate of burner or electric heating element 2 (W)
REAL(r64) :: Qheater ! Combined heating rate of heater 1 and 2 (W)
REAL(r64) :: Qoffcycfuel ! Fuel consumption rate of off-cycle parasitics (W)
REAL(r64) :: Qoffcycheat ! Heating rate of fraction of off-cycle parasitics added to the tank (W)
REAL(r64) :: Qoncycfuel ! Fuel consumption rate on-cycle parasitics added to the tank (W)
REAL(r64) :: Qoncycheat ! Heating rate of fraction of on-cycle parasitics added to the tank (W)
REAL(r64) :: Qneeded ! Heating rate needed to recover or maintain the setpoint temperature (W)
REAL(r64) :: Qunmet ! The difference between Qneeded and Qheater (W)
REAL(r64) :: Qvent ! Heating rate due to venting because tank exceeded max temperature limit (W)
REAL(r64) :: Qfuel ! Heating rate for fuel consumed (W)
REAL(r64) :: UseInletTemp ! Use side inlet temperature (C)
REAL(r64) :: UseMassFlowRate ! Use side flow rate, including effectiveness factor (kg/s)
REAL(r64) :: SourceInletTemp ! Source side inlet temperature (C)
REAL(r64) :: SourceMassFlowRate ! Source side flow rate, including effectiveness factor (kg/s)
INTEGER :: CycleOnCount1 ! Number of times heater 1 cycles on in the current time step
INTEGER :: CycleOnCount2 ! Number of times heater 2 cycles on in the current time step
REAL(r64) :: Runtime1 ! Time that heater 1 is running (s)
REAL(r64) :: Runtime2 ! Time that heater 2 is running (s)
REAL(r64) :: Runtime ! Time that either heater is running (s)
REAL(r64) :: RTF1 ! Runtime fraction, fraction of timestep that heater 1 is running
REAL(r64) :: RTF2 ! Runtime fraction, fraction of timestep that heater 2 is running
REAL(r64) :: RTF ! Runtime fraction, fraction of timestep that either heater is running
REAL(r64) :: Eloss ! Energy change due to ambient losses over the timestep (J)
REAL(r64) :: Elosszone ! Energy change to the zone due to ambient losses over the timestep (J)
REAL(r64) :: Euse ! Energy change due to use side mass flow over the timestep (J)
REAL(r64) :: Esource ! Energy change due to source side mass flow over the timestep (J)
REAL(r64) :: Eheater1 ! Energy change due to heater 1 over the timestep (J)
REAL(r64) :: Eheater2 ! Energy change due to heater 2 over the timestep (J)
REAL(r64) :: Eoncycfuel ! Fuel energy consumed by on-cycle parasitics over the timestep (J)
REAL(r64) :: Eoffcycfuel ! Fuel energy consumed by off-cycle parasitics over the timestep (J)
REAL(r64) :: Event ! Energy change due to venting over the timestep (J)
REAL(r64) :: Eneeded ! Energy change needed over the timestep (J)
REAL(r64) :: Eunmet ! Energy change unmet over the timestep (J)
REAL(r64) :: Efuel ! Energy change for fuel consumed over the timestep (J)
LOGICAL :: SetPointRecovered ! Flag to indicate when set point is recovered for the first time
INTEGER :: DummyWaterIndex = 1
! FLOW:
TimeElapsed = HourOfDay + TimeStep * TimeStepZone + SysTimeElapsed
IF (WaterThermalTank(WaterThermalTankNum)%TimeElapsed /= TimeElapsed) THEN
! The simulation has advanced to the next system timestep. Save conditions from the end of the previous system
! timestep for use as the initial conditions of each iteration that does not advance the system timestep.
WaterThermalTank(WaterThermalTankNum)%Node%SavedTemp = WaterThermalTank(WaterThermalTankNum)%Node%Temp
WaterThermalTank(WaterThermalTankNum)%SavedHeaterOn1 = WaterThermalTank(WaterThermalTankNum)%HeaterOn1
WaterThermalTank(WaterThermalTankNum)%SavedHeaterOn2 = WaterThermalTank(WaterThermalTankNum)%HeaterOn2
! Save outlet temperatures for demand-side flow control
WaterThermalTank(WaterThermalTankNum)%SavedUseOutletTemp = WaterThermalTank(WaterThermalTankNum)%UseOutletTemp
WaterThermalTank(WaterThermalTankNum)%SavedSourceOutletTemp = WaterThermalTank(WaterThermalTankNum)%SourceOutletTemp
WaterThermalTank(WaterThermalTankNum)%TimeElapsed = TimeElapsed
END IF
WaterThermalTank(WaterThermalTankNum)%Node%Temp = WaterThermalTank(WaterThermalTankNum)%Node%SavedTemp
WaterThermalTank(WaterThermalTankNum)%HeaterOn1 = WaterThermalTank(WaterThermalTankNum)%SavedHeaterOn1
WaterThermalTank(WaterThermalTankNum)%HeaterOn2 = WaterThermalTank(WaterThermalTankNum)%SavedHeaterOn2
SecInTimeStep = TimeStepSys * SecInHour
NumNodes = WaterThermalTank(WaterThermalTankNum)%Nodes
AmbientTemp = WaterThermalTank(WaterThermalTankNum)%AmbientTemp
UseInletTemp = WaterThermalTank(WaterThermalTankNum)%UseInletTemp
SourceInletTemp = WaterThermalTank(WaterThermalTankNum)%SourceInletTemp
SetPointTemp1 = WaterThermalTank(WaterThermalTankNum)%SetPointTemp
MinTemp1 = SetPointTemp1 - WaterThermalTank(WaterThermalTankNum)%DeadbandDeltaTemp
SetPointTemp2 = WaterThermalTank(WaterThermalTankNum)%SetPointTemp2
MinTemp2 = SetPointTemp2 - WaterThermalTank(WaterThermalTankNum)%DeadbandDeltaTemp2
MaxTemp = WaterThermalTank(WaterThermalTankNum)%TankTempLimit
IF (WaterThermalTank(WaterThermalTankNum)%UseSidePlantLoopNum > 0) THEN
Cp = GetSpecificHeatGlycol(PlantLoop(WaterThermalTank(WaterThermalTankNum)%UseSidePlantLoopNum)%FluidName, &
WaterThermalTank(WaterThermalTankNum)%TankTemp, &
PlantLoop(WaterThermalTank(WaterThermalTankNum)%UseSidePlantLoopNum)%FluidIndex, &
'CalcWaterThermalTankStratified')
ELSE
Cp = GetSpecificHeatGlycol('WATER', WaterThermalTank(WaterThermalTankNum)%TankTemp, &
DummyWaterIndex, 'CalcWaterThermalTankStratified')
ENDIF
TempUp = 0.0d0
TempDn = 0.0d0
Eloss = 0.0d0
Elosszone = 0.0d0
Euse = 0.0d0
Esource = 0.0d0
Eheater1 = 0.0d0
Eheater2 = 0.0d0
Event = 0.0d0
Eneeded = 0.0d0
Eunmet = 0.0d0
Efuel = 0.0d0
Eoncycfuel = 0.0d0
Eoffcycfuel = 0.0d0
CycleOnCount1 = 0
CycleOnCount2 = 0
Runtime = 0.0d0
Runtime1 = 0.0d0
Runtime2 = 0.0d0
SetPointRecovered = .FALSE.
IF (WaterThermalTank(WaterThermalTankNum)%InletMode == InletModeFixed) &
CALL CalcNodeMassFlows(WaterThermalTankNum, InletModeFixed)
TimeRemaining = SecInTimeStep
DO WHILE (TimeRemaining > 0.0d0)
IF (WaterThermalTank(WaterThermalTankNum)%InletMode == InletModeSeeking) &
CALL CalcNodeMassFlows(WaterThermalTankNum, InletModeSeeking)
IF ( .not. WaterThermalTank(WaterThermalTankNum)%IsChilledWaterTank) THEN
! Control the first heater element (master)
IF (WaterThermalTank(WaterThermalTankNum)%MaxCapacity > 0.0d0) THEN
NodeNum = WaterThermalTank(WaterThermalTankNum)%HeaterNode1
NodeTemp = WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%Temp
IF (WaterThermalTank(WaterThermalTankNum)%HeaterOn1) THEN
IF (NodeTemp >= SetPointTemp1) THEN
WaterThermalTank(WaterThermalTankNum)%HeaterOn1 = .FALSE.
SetPointRecovered = .TRUE.
END IF
ELSE ! Heater is off
IF (NodeTemp < MinTemp1) THEN
WaterThermalTank(WaterThermalTankNum)%HeaterOn1 = .TRUE.
CycleOnCount1 = CycleOnCount1 + 1
END IF
END IF
END IF
IF (WaterThermalTank(WaterThermalTankNum)%HeaterOn1) THEN
Qheater1 = WaterThermalTank(WaterThermalTankNum)%MaxCapacity
Runtime1 = Runtime1 + dt
ELSE
Qheater1 = 0.0D0
END IF
! Control the second heater element (slave)
IF (WaterThermalTank(WaterThermalTankNum)%MaxCapacity2 > 0.0d0) THEN
IF ((WaterThermalTank(WaterThermalTankNum)%ControlType == PriorityMasterSlave) .AND. &
WaterThermalTank(WaterThermalTankNum)%HeaterOn1) THEN
WaterThermalTank(WaterThermalTankNum)%HeaterOn2 = .FALSE.
ELSE
NodeNum = WaterThermalTank(WaterThermalTankNum)%HeaterNode2
NodeTemp = WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%Temp
IF (WaterThermalTank(WaterThermalTankNum)%HeaterOn2) THEN
IF (NodeTemp >= SetPointTemp2) THEN
WaterThermalTank(WaterThermalTankNum)%HeaterOn2 = .FALSE.
SetPointRecovered = .TRUE.
END IF
ELSE ! Heater is off
IF (NodeTemp < MinTemp2) THEN
WaterThermalTank(WaterThermalTankNum)%HeaterOn2 = .TRUE.
CycleOnCount2 = CycleOnCount2 + 1
END IF
END IF
END IF
END IF
IF (WaterThermalTank(WaterThermalTankNum)%HeaterOn2) THEN
Qheater2 = WaterThermalTank(WaterThermalTankNum)%MaxCapacity2
Runtime2 = Runtime2 + dt
ELSE
Qheater2 = 0.0d0
END IF
ELSE ! chilled water thank, no heating
Qheater1 = 0.0D0
Qheater2 = 0.0D0
ENDIF
IF (WaterThermalTank(WaterThermalTankNum)%HeaterOn1 .OR. WaterThermalTank(WaterThermalTankNum)%HeaterOn2) THEN
Runtime = Runtime + dt
Qfuel = (Qheater1 + Qheater2) / WaterThermalTank(WaterThermalTankNum)%Efficiency
Qoncycfuel = WaterThermalTank(WaterThermalTankNum)%OnCycParaLoad
Qoffcycfuel = 0.0d0
ELSE
Qfuel = 0.0d0
Qoncycfuel = 0.0d0
Qoffcycfuel = WaterThermalTank(WaterThermalTankNum)%OffCycParaLoad
END IF
! Loop through all nodes and simulate heat balance
DO NodeNum = 1, NumNodes
NodeMass = WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%Mass
NodeTemp = WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%Temp
UseMassFlowRate = WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%UseMassFlowRate * &
WaterThermalTank(WaterThermalTankNum)%UseEffectiveness
SourceMassFlowRate = WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%SourceMassFlowRate &
* WaterThermalTank(WaterThermalTankNum)%SourceEffectiveness
! Heat transfer due to fluid flow entering an inlet node
Quse = UseMassFlowRate * Cp * (UseInletTemp - NodeTemp)
Qsource = SourceMassFlowRate * Cp * (SourceInletTemp - NodeTemp)
InvMixUp = 0.0d0
IF (NodeNum > 1) THEN
TempUp = WaterThermalTank(WaterThermalTankNum)%Node(NodeNum - 1)%Temp
IF (TempUp < NodeTemp) InvMixUp = WaterThermalTank(WaterThermalTankNum)%InversionMixingRate
END IF
InvMixDn = 0.0d0
IF (NodeNum < NumNodes) THEN
TempDn = WaterThermalTank(WaterThermalTankNum)%Node(NodeNum + 1)%Temp
IF (TempDn > NodeTemp) InvMixDn = WaterThermalTank(WaterThermalTankNum)%InversionMixingRate
END IF
! Heat transfer due to vertical conduction between nodes
Qcond = WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%CondCoeffUp * (TempUp - NodeTemp) &
+ WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%CondCoeffDn * (TempDn - NodeTemp)
! Heat transfer due to fluid flow between inlet and outlet nodes
Qflow = WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%MassFlowFromUpper * Cp * (TempUp - NodeTemp) &
+ WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%MassFlowFromLower * Cp * (TempDn - NodeTemp)
! Heat transfer due to temperature inversion mixing between nodes
Qmix = InvMixUp * Cp * (TempUp - NodeTemp) + InvMixDn * Cp * (TempDn - NodeTemp)
IF (WaterThermalTank(WaterThermalTankNum)%HeaterOn1 .OR. WaterThermalTank(WaterThermalTankNum)%HeaterOn2) THEN
LossCoeff = WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%OnCycLossCoeff
Qloss = LossCoeff * (AmbientTemp - NodeTemp)
Qlosszone = Qloss * WaterThermalTank(WaterThermalTankNum)%SkinLossFracToZone
Qoncycheat = WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%OnCycParaLoad * &
WaterThermalTank(WaterThermalTankNum)%OnCycParaFracToTank
Qneeded = MAX(- Quse - Qsource - Qloss - Qoncycheat, 0.0d0)
Qheat = Qoncycheat
IF (NodeNum == WaterThermalTank(WaterThermalTankNum)%HeaterNode1) Qheat = Qheat + Qheater1
IF (NodeNum == WaterThermalTank(WaterThermalTankNum)%HeaterNode2) Qheat = Qheat + Qheater2
ELSE
LossCoeff = WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%OffCycLossCoeff
Qloss = LossCoeff * (AmbientTemp - NodeTemp)
Qlosszone = Qloss * WaterThermalTank(WaterThermalTankNum)%SkinLossFracToZone
Qoffcycheat = WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%OffCycParaLoad * &
WaterThermalTank(WaterThermalTankNum)%OffCycParaFracToTank
Qneeded = MAX(- Quse - Qsource - Qloss - Qoffcycheat, 0.0d0)
Qheat = Qoffcycheat
END IF
Qunmet = MAX(Qneeded - Qheater1 - Qheater2, 0.0d0)
! Calculate node heat balance
WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%NewTemp = NodeTemp &
+ (Quse + Qsource + Qcond + Qflow + Qmix + Qloss + Qheat) * dt / (NodeMass * Cp)
IF ( .not. WaterThermalTank(WaterThermalTankNum)%IsChilledWaterTank) THEN
IF ((NodeNum == 1) .AND. (WaterThermalTank(WaterThermalTankNum)%Node(1)%NewTemp > MaxTemp)) THEN
Event = Event + NodeMass * Cp * (MaxTemp - WaterThermalTank(WaterThermalTankNum)%Node(1)%NewTemp)
WaterThermalTank(WaterThermalTankNum)%Node(1)%NewTemp = MaxTemp
END IF
ENDIF
Euse = Euse + Quse * dt
Esource = Esource + Qsource * dt
Eloss = Eloss + Qloss * dt
Elosszone = Elosszone + Qlosszone * dt
Eneeded = Eneeded + Qneeded * dt
Eunmet = Eunmet + Qunmet * dt
END DO ! NodeNum
! Calculation for standard ratings
IF (.NOT. WaterThermalTank(WaterThermalTankNum)%FirstRecoveryDone) THEN
WaterThermalTank(WaterThermalTankNum)%FirstRecoveryFuel = WaterThermalTank(WaterThermalTankNum)%FirstRecoveryFuel &
+ (Qfuel + Qoffcycfuel + Qoncycfuel) * dt
IF (SetpointRecovered) WaterThermalTank(WaterThermalTankNum)%FirstRecoveryDone = .TRUE.
END IF
! Update node temperatures
WaterThermalTank(WaterThermalTankNum)%Node%Temp = WaterThermalTank(WaterThermalTankNum)%Node%NewTemp
WaterThermalTank(WaterThermalTankNum)%Node%TempSum = WaterThermalTank(WaterThermalTankNum)%Node%TempSum &
+ WaterThermalTank(WaterThermalTankNum)%Node%Temp * dt
TimeRemaining = TimeRemaining - dt
END DO ! TimeRemaining > 0.0
Eheater1 = WaterThermalTank(WaterThermalTankNum)%MaxCapacity * Runtime1
Eheater2 = WaterThermalTank(WaterThermalTankNum)%MaxCapacity2 * Runtime2
Efuel = (Eheater1 + Eheater2) / WaterThermalTank(WaterThermalTankNum)%Efficiency
Eoffcycfuel = WaterThermalTank(WaterThermalTankNum)%OffCycParaLoad * (SecInTimeStep - Runtime)
Eoncycfuel = WaterThermalTank(WaterThermalTankNum)%OnCycParaLoad * Runtime
! Calculate average values over the time step based on summed values, Q > 0 is a gain to the tank, Q < 0 is a loss to the tank
Qloss = Eloss / SecInTimeStep
Qlosszone = Elosszone / SecInTimeStep
Quse = Euse / SecInTimeStep
Qsource = Esource / SecInTimeStep
Qheater1 = Eheater1 / SecInTimeStep
Qheater2 = Eheater2 / SecInTimeStep
Qheater = Qheater1 + Qheater2
Qoffcycfuel = Eoffcycfuel / SecInTimeStep
Qoffcycheat = Qoffcycfuel * WaterThermalTank(WaterThermalTankNum)%OffCycParaFracToTank
Qoncycfuel = Eoncycfuel / SecInTimeStep
Qoncycheat = Qoncycfuel * WaterThermalTank(WaterThermalTankNum)%OnCycParaFracToTank
Qvent = Event / SecInTimeStep
Qneeded = Eneeded / SecInTimeStep
Qunmet = Eunmet / SecInTimeStep
RTF = Runtime / SecInTimeStep
RTF1 = Runtime1 / SecInTimeStep
RTF2 = Runtime2 / SecInTimeStep
Qfuel = Efuel / SecInTimeStep
! Calculate average node temperatures over the time step
WaterThermalTank(WaterThermalTankNum)%Node%TempAvg = WaterThermalTank(WaterThermalTankNum)%Node%TempSum / SecInTimeStep
WaterThermalTank(WaterThermalTankNum)%Node%TempSum = 0.0d0 ! Reset for next time step
! Calculate instantaneous and average tank temperature (all nodes have equal mass)
WaterThermalTank(WaterThermalTankNum)%TankTemp = SUM(WaterThermalTank(WaterThermalTankNum)%Node%Temp) / NumNodes
WaterThermalTank(WaterThermalTankNum)%TankTempAvg = SUM(WaterThermalTank(WaterThermalTankNum)%Node%TempAvg) / NumNodes
NodeNum = WaterThermalTank(WaterThermalTankNum)%UseOutletStratNode
IF (NodeNum > 0) WaterThermalTank(WaterThermalTankNum)%UseOutletTemp = WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%TempAvg
! Revised use outlet temperature to ensure energy balance. Assumes a constant CP. CR8341/CR8570
IF (NodeNum > 0) Then
IF (WaterThermalTank(WaterThermalTankNum)%UseMassFlowRate .GT. 0.0d0) Then
WaterThermalTank(WaterThermalTankNum)%UseOutletTemp = WaterThermalTank(WaterThermalTankNum)%UseInletTemp &
* (1.0d0 - WaterThermalTank(WaterThermalTankNum)%UseEffectiveness) &
+ WaterThermalTank(WaterThermalTankNum)%UseOutletTemp &
* WaterThermalTank(WaterThermalTankNum)%UseEffectiveness
End If
End If
NodeNum = WaterThermalTank(WaterThermalTankNum)%SourceOutletStratNode
IF (NodeNum > 0) WaterThermalTank(WaterThermalTankNum)%SourceOutletTemp = &
WaterThermalTank(WaterThermalTankNum)%Node(NodeNum)%TempAvg
! Revised use outlet temperature to ensure energy balance. Assumes a constant CP. CR8341/CR8570
IF (NodeNum > 0) Then
IF (WaterThermalTank(WaterThermalTankNum)%SourceMassFlowRate .GT. 0.0d0) Then
WaterThermalTank(WaterThermalTankNum)%SourceOutletTemp = WaterThermalTank(WaterThermalTankNum)%SourceInletTemp &
* (1.0d0 - WaterThermalTank(WaterThermalTankNum)%SourceEffectiveness) &
+ WaterThermalTank(WaterThermalTankNum)%SourceOutletTemp &
* WaterThermalTank(WaterThermalTankNum)%SourceEffectiveness
End If
End If
WaterThermalTank(WaterThermalTankNum)%LossRate = Qloss
WaterThermalTank(WaterThermalTankNum)%UseRate = Quse
WaterThermalTank(WaterThermalTankNum)%SourceRate = Qsource
WaterThermalTank(WaterThermalTankNum)%OffCycParaRateToTank = Qoffcycheat
WaterThermalTank(WaterThermalTankNum)%OnCycParaRateToTank = Qoncycheat
WaterThermalTank(WaterThermalTankNum)%TotalDemandRate = -Quse - Qsource - Qloss - Qoffcycheat - Qoncycheat
WaterThermalTank(WaterThermalTankNum)%HeaterRate = Qheater
WaterThermalTank(WaterThermalTankNum)%HeaterRate1 = Qheater1
WaterThermalTank(WaterThermalTankNum)%HeaterRate2 = Qheater2
WaterThermalTank(WaterThermalTankNum)%UnmetRate = Qunmet
WaterThermalTank(WaterThermalTankNum)%VentRate = Qvent
WaterThermalTank(WaterThermalTankNum)%NetHeatTransferRate = Quse + Qsource + Qloss + Qoffcycheat + Qoncycheat + Qheater + Qvent
WaterThermalTank(WaterThermalTankNum)%CycleOnCount = CycleOnCount1 + CycleOnCount2
WaterThermalTank(WaterThermalTankNum)%CycleOnCount1 = CycleOnCount1
WaterThermalTank(WaterThermalTankNum)%CycleOnCount2 = CycleOnCount2
WaterThermalTank(WaterThermalTankNum)%RuntimeFraction = RTF
WaterThermalTank(WaterThermalTankNum)%RuntimeFraction1 = RTF1
WaterThermalTank(WaterThermalTankNum)%RuntimeFraction2 = RTF2
WaterThermalTank(WaterThermalTankNum)%FuelRate = Qfuel
WaterThermalTank(WaterThermalTankNum)%OffCycParaFuelRate = Qoffcycfuel
WaterThermalTank(WaterThermalTankNum)%OnCycParaFuelRate = Qoncycfuel
! Add water heater skin losses and venting losses to ambient zone, if specified
IF (WaterThermalTank(WaterThermalTankNum)%AmbientTempZone > 0) &
WaterThermalTank(WaterThermalTankNum)%AmbientZoneGain = -Qlosszone - Qvent
RETURN
END SUBROUTINE CalcWaterThermalTankStratified