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 CalcStandardRatings(WaterThermalTankNum)
! SUBROUTINE INFORMATION:
! AUTHOR Peter Graham Ellis
! DATE WRITTEN January 2005
! MODIFIED R. Raustad, July 2005 - added HPWH to ratings procedure
! RE-ENGINEERED na
! PURPOSE OF THIS SUBROUTINE:
! Calculates the water heater standard ratings, such as Energy Factor and Recovery Efficiency. Results are written
! to the EIO file. Standard ratings are not calculated for storage-only tanks, i.e., MaxCapacity = 0.
! METHODOLOGY EMPLOYED:
! Water heater inputs are set to the specified test conditions. For HPWHs, the heating capacity and COP are assumed
! to be the primary element in the water heater and are used during the rating procedure. CalcWaterThermalTankMixed
! is iteratively called in a self-contained, 24 hour simulation of the standard test procedure.
! REFERENCES:
! Title 10, Code of Federal Regulations, Part 430- Energy Conservation Program for Consumer Products, Appendix E to
! Subpart B- Uniform Test Procedure for Measuring the Energy Consumption of Water Heaters, January 1, 2004.
! USE STATEMENTS:
USE Psychrometrics, ONLY: RhoH2O, CPHW, PsyRhoAirFnPbTdbW, PsyTwbFnTdbWPb , PsyHFnTdbW
USE DataGlobals, ONLY: InitConvTemp
USE DataInterfaces, ONLY: ShowWarningError, ShowContinueError
USE CurveManager, ONLY: CurveValue
USE DXCoils, ONLY: HPWHHeatingCapacity, HPWHHeatingCOP, SimDXCoil
USE Fans, ONLY: SimulateFanComponents
USE DataLoopNode, ONLY: Node
USE DataEnvironment, ONLY: OutBaroPress
USE DataHVACGlobals, ONLY: TimeStepSys, HPWHInletDBTemp, HPWHInletWBTemp, HPWHCrankcaseDBTemp, DXCoilTotalCapacity, &
BlowThru, CycFanCycCoil
USE OutputReportPredefined
USE General, ONLY: TrimSigDigits
IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
! SUBROUTINE ARGUMENT DEFINITIONS:
INTEGER, INTENT(IN) :: WaterThermalTankNum
! SUBROUTINE PARAMETER DEFINITIONS:
! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
REAL(r64) :: TotalDrawMass ! Total mass of hot water drawn during the test (kg), equivalent to 64.3 gallons
REAL(r64) :: DrawMass ! Mass of a single draw of hot water (kg)
REAL(r64) :: SecInTimeStep ! Seconds per timestep, depends on user-specified system timestep (s)
REAL(r64) :: DrawMassFlowRate ! Mass flow rate of all test draw (m3/s)
INTEGER :: TimeStepPerHour ! Number of timesteps per hour
INTEGER :: Step ! Current timestep in the self-contained water heater simulation
REAL(r64) :: FuelEnergy ! Cumulative fuel energy used to heat the tank (J)
REAL(r64) :: MaxCapacity ! Maximum heating capacity (W)
REAL(r64) :: RecoveryEfficiency ! Standard water heater rating
REAL(r64) :: EnergyFactor ! Standard water heater rating
INTEGER :: HPNum ! index to heat pump water heater
REAL(r64) :: MdotAir ! air mass flow rate through HP water heater evaporator (kg/s)
REAL(r64) :: MdotWater ! water mass flow rate through HP water heater condenser (kg/s)
REAL(r64) :: AmbientHumRat ! used during HPWH rating procedure
REAL(r64) :: RatedDXCoilTotalCapacity ! used during HPWH rating procedure
LOGICAL :: FirstTimeFlag ! used during HPWH rating procedure
CHARACTER(len=MaxNameLength) :: equipName
Logical, SAVE :: MyOneTimeSetupFlag = .true. ! one time setup flag
If (AlreadyRated(WaterThermalTankNum)) Then ! bail we already did this one
RETURN
ENDIF
! FLOW:
IF (WaterThermalTank(WaterThermalTankNum)%MaxCapacity > 0.0d0 .OR. WaterThermalTank(WaterThermalTankNum)%HeatPumpNum .GT. 0) THEN
! Set test conditions
WaterThermalTank(WaterThermalTankNum)%AmbientTemp = 19.7222d0 ! 67.5 F
WaterThermalTank(WaterThermalTankNum)%UseInletTemp = 14.4444d0 ! 58 F
WaterThermalTank(WaterThermalTankNum)%SetpointTemp = 57.2222d0 ! 135 F
WaterThermalTank(WaterThermalTankNum)%SetPointTemp2 = 57.2222d0 ! 135 F
WaterThermalTank(WaterThermalTankNum)%TankTemp = 57.2222d0 ! Initialize tank temperature
IF (WaterThermalTank(WaterThermalTankNum)%Nodes > 0) WaterThermalTank(WaterThermalTankNum)%Node%Temp = 57.2222d0
TotalDrawMass = 0.243402d0 * RhoH2O(InitConvTemp) ! 64.3 gal * rho
DrawMass = TotalDrawMass / 6.0d0 ! 6 equal draws
SecInTimeStep = TimeStepSys * SecInHour
DrawMassFlowRate = DrawMass / SecInTimeStep
FuelEnergy = 0.0d0
FirstTimeFlag = .TRUE.
TimeStepPerHour = INT(1.0d0 / TimeStepSys)
! Simulate 24 hour test
DO Step = 1, TimeStepPerHour * 24
IF (Step == 1 .OR. & ! Hour 1
Step == (1 + TimeStepPerHour) .OR. & ! Hour 2
Step == (1 + TimeStepPerHour * 2) .OR. & ! Hour 3
Step == (1 + TimeStepPerHour * 3) .OR. & ! Hour 4
Step == (1 + TimeStepPerHour * 4) .OR. & ! Hour 5
Step == (1 + TimeStepPerHour * 5)) THEN ! Hour 6
WaterThermalTank(WaterThermalTankNum)%UseMassFlowRate = DrawMassFlowRate
ELSE
WaterThermalTank(WaterThermalTankNum)%UseMassFlowRate = 0.0d0
END IF
WaterThermalTank(WaterThermalTankNum)%SavedTankTemp = WaterThermalTank(WaterThermalTankNum)%TankTemp
WaterThermalTank(WaterThermalTankNum)%SavedMode = WaterThermalTank(WaterThermalTankNum)%Mode
IF (WaterThermalTank(WaterThermalTankNum)%Nodes > 0) THEN
WaterThermalTank(WaterThermalTankNum)%Node%SavedTemp = WaterThermalTank(WaterThermalTankNum)%Node%Temp
WaterThermalTank(WaterThermalTankNum)%SavedHeaterOn1 = WaterThermalTank(WaterThermalTankNum)%HeaterOn1
WaterThermalTank(WaterThermalTankNum)%SavedHeaterOn2 = WaterThermalTank(WaterThermalTankNum)%HeaterOn2
END IF
IF(WaterThermalTank(WaterThermalTankNum)%HeatPumpNum .EQ. 0) THEN
SELECT CASE (WaterThermalTank(WaterThermalTankNum)%TypeNum)
CASE (MixedWaterHeater)
CALL CalcWaterThermalTankMixed(WaterThermalTankNum)
CASE (StratifiedWaterHeater)
CALL CalcWaterThermalTankStratified(WaterThermalTankNum)
CASE DEFAULT
! Unhandled water heater type
END SELECT
ELSE
HPNum = WaterThermalTank(WaterThermalTankNum)%HeatPumpNum
AmbientHumRat = 0.00717d0 ! Humidity ratio at 67.5 F / 50% RH
! set the heat pump air- and water-side mass flow rate
MdotWater = HPWaterHeater(HPNum)%OperatingWaterFlowRate * RhoH2O(WaterThermalTank(WaterThermalTankNum)%TankTemp)
MdotAir = HPWaterHeater(HPNum)%OperatingAirFlowRate * &
PsyRhoAirFnPbTdbW(OutBaroPress,WaterThermalTank(WaterThermalTankNum)%AmbientTemp, AmbientHumRat)
! set the condenser inlet node mass flow rate and temperature
Node(HPWaterHeater(HPNum)%CondWaterInletNode)%MassFlowRate = MdotWater
Node(HPWaterHeater(HPNum)%CondWaterInletNode)%Temp = WaterThermalTank(WaterThermalTankNum)%TankTemp
! initialize temperatures for HPWH DX Coil heating capacity and COP curves
HPWHInletDBTemp = WaterThermalTank(WaterThermalTankNum)%AmbientTemp
HPWHInletWBTemp = PsyTwbFnTdbWPb(HPWHInletDBTemp,AmbientHumRat,OutBaroPress)
! set up full air flow on DX coil inlet node
IF(HPWaterHeater(HPNum)%InletAirMixerNode .GT. 0) THEN
Node(HPWaterHeater(HPNum)%InletAirMixerNode)%MassFlowRate = MdotAir
Node(HPWaterHeater(HPNum)%InletAirMixerNode)%MassFlowRateMaxAvail = MdotAir
Node(HPWaterHeater(HPNum)%InletAirMixerNode)%Temp = WaterThermalTank(WaterThermalTankNum)%AmbientTemp
Node(HPWaterHeater(HPNum)%InletAirMixerNode)%HumRat = AmbientHumRat
Node(HPWaterHeater(HPNum)%InletAirMixerNode)%Enthalpy = &
PsyHFnTdbW(WaterThermalTank(WaterThermalTankNum)%AmbientTemp,AmbientHumRat)
ELSE
IF(HPWaterHeater(HPNum)%OutsideAirNode .EQ. 0)THEN
Node(HPWaterHeater(HPNum)%HeatPumpAirInletNode)%MassFlowRate = MdotAir
Node(HPWaterHeater(HPNum)%HeatPumpAirInletNode)%MassFlowRateMaxAvail = MdotAir
Node(HPWaterHeater(HPNum)%HeatPumpAirInletNode)%Temp = &
WaterThermalTank(WaterThermalTankNum)%AmbientTemp
Node(HPWaterHeater(HPNum)%HeatPumpAirInletNode)%HumRat = AmbientHumRat
Node(HPWaterHeater(HPNum)%HeatPumpAirInletNode)%Enthalpy = &
PsyHFnTdbW(WaterThermalTank(WaterThermalTankNum)%AmbientTemp,AmbientHumRat)
ELSE
Node(HPWaterHeater(HPNum)%OutsideAirNode)%MassFlowRate = MdotAir
Node(HPWaterHeater(HPNum)%OutsideAirNode)%MassFlowRateMaxAvail = MdotAir
Node(HPWaterHeater(HPNum)%OutsideAirNode)%Temp = WaterThermalTank(WaterThermalTankNum)%AmbientTemp
Node(HPWaterHeater(HPNum)%OutsideAirNode)%HumRat = AmbientHumRat
Node(HPWaterHeater(HPNum)%OutsideAirNode)%Enthalpy = &
PsyHFnTdbW(WaterThermalTank(WaterThermalTankNum)%AmbientTemp,AmbientHumRat)
END IF
END IF
HPWHCrankcaseDBTemp = WaterThermalTank(WaterThermalTankNum)%AmbientTemp
! simulate the HPWH coil/fan to find heating capacity
IF(HPWaterHeater(HPNum)%FanPlacement .EQ. BlowThru) THEN
CALL SimulateFanComponents(HPWaterHeater(HPNum)%FanName, .TRUE. ,HPWaterHeater(HPNum)%FanNum)
! CALL SimDXCoil(HPWaterHeater(HPNum)%DXCoilName, CompOp, .TRUE.,PartLoadRatio, HPWaterHeater(HPNum)%DXCoilNum,FanOpMode)
CALL SimDXCoil(HPWaterHeater(HPNum)%DXCoilName, 1, .TRUE., 1.0d0, HPWaterHeater(HPNum)%DXCoilNum,CycFanCycCoil)
CALL SimulateFanComponents(HPWaterHeater(HPNum)%FanName, .TRUE. ,HPWaterHeater(HPNum)%FanNum)
CALL SimDXCoil(HPWaterHeater(HPNum)%DXCoilName, 1, .TRUE., 1.0d0, HPWaterHeater(HPNum)%DXCoilNum,CycFanCycCoil)
ELSE
CALL SimDXCoil(HPWaterHeater(HPNum)%DXCoilName, 1, .TRUE., 1.0d0, HPWaterHeater(HPNum)%DXCoilNum,CycFanCycCoil)
CALL SimulateFanComponents(HPWaterHeater(HPNum)%FanName, .TRUE. ,HPWaterHeater(HPNum)%FanNum)
CALL SimDXCoil(HPWaterHeater(HPNum)%DXCoilName, 1, .TRUE., 1.0d0, HPWaterHeater(HPNum)%DXCoilNum,CycFanCycCoil)
CALL SimulateFanComponents(HPWaterHeater(HPNum)%FanName, .TRUE. ,HPWaterHeater(HPNum)%FanNum)
END IF
IF(FirstTimeFlag)THEN
RatedDXCoilTotalCapacity = DXCoilTotalCapacity
FirstTimeFlag = .FALSE.
END IF
! Switch the HPWH info with the tank info and call CalcWaterThermalTankMixed to get Standard Rating
! (backup element is assumed to be disabled during the rating procedure)
WaterThermalTank(WaterThermalTankNum)%SourceMassFlowRate = 0.0d0
WaterThermalTank(WaterThermalTankNum)%MaxCapacity = HPWHHeatingCapacity
WaterThermalTank(WaterThermalTankNum)%MinCapacity = HPWHHeatingCapacity
WaterThermalTank(WaterThermalTankNum)%Efficiency = HPWHHeatingCOP !* WaterHeater(WaterHeaterNum)%Efficiency
WaterThermalTank(WaterThermalTankNum)%OnCycParaLoad = HPWaterHeater(HPNum)%OnCycParaLoad
WaterThermalTank(WaterThermalTankNum)%OffCycParaLoad = HPWaterHeater(HPNum)%OffCycParaLoad
WaterThermalTank(WaterThermalTankNum)%OffCycParaFracToTank = 0.0d0
WaterThermalTank(WaterThermalTankNum)%OnCycParaFracToTank = 0.0d0
WaterThermalTank(WaterThermalTankNum)%PLFCurve = HPWaterHeater(HPNum)%DXCoilPLFFPLR
SELECT CASE (WaterThermalTank(WaterThermalTankNum)%TypeNum)
CASE (MixedWaterHeater)
IF (WaterThermalTank(WaterThermalTankNum)%Efficiency .GT. 0.0d0) &
CALL CalcWaterThermalTankMixed(WaterThermalTankNum)
CASE (StratifiedWaterHeater)
IF (WaterThermalTank(WaterThermalTankNum)%Efficiency .GT. 0.0d0) &
CALL CalcWaterThermalTankStratified(WaterThermalTankNum)
CASE DEFAULT
! Unhandled water heater type
END SELECT
! reset the water heater data to original values
WaterThermalTank(WaterThermalTankNum)%MaxCapacity = HPWaterHeater(HPNum)%BackupElementCapacity
WaterThermalTank(WaterThermalTankNum)%MinCapacity = HPWaterHeater(HPNum)%BackupElementCapacity
WaterThermalTank(WaterThermalTankNum)%Efficiency = HPWaterHeater(HPNum)%BackupElementEfficiency
WaterThermalTank(WaterThermalTankNum)%OnCycParaLoad = HPWaterHeater(HPNum)%WHOnCycParaLoad
WaterThermalTank(WaterThermalTankNum)%OffCycParaLoad = HPWaterHeater(HPNum)%WHOffCycParaLoad
WaterThermalTank(WaterThermalTankNum)%OnCycParaFracToTank = HPWaterHeater(HPNum)%WHOnCycParaFracToTank
WaterThermalTank(WaterThermalTankNum)%OffCycParaFracToTank = HPWaterHeater(HPNum)%WHOffCycParaFracToTank
WaterThermalTank(WaterThermalTankNum)%PLFCurve = HPWaterHeater(HPNum)%WHPLFCurve
END IF
FuelEnergy = FuelEnergy + (WaterThermalTank(WaterThermalTankNum)%FuelRate + &
WaterThermalTank(WaterThermalTankNum)%OffCycParaFuelRate + &
WaterThermalTank(WaterThermalTankNum)%OnCycParaFuelRate) * SecInTimeStep
END DO ! Step
IF (WaterThermalTank(WaterThermalTankNum)%FirstRecoveryDone .AND. &
WaterThermalTank(WaterThermalTankNum)%FirstRecoveryFuel > 0.0d0) THEN
! Calculate Recovery Efficiency based on energy used to recover from the first draw
! FirstRecoveryFuel is recorded inside the CalcWaterThermalTank subroutine
RecoveryEfficiency = DrawMass * CPHW(57.2222d0) * (57.2222d0 - 14.4444d0) / &
WaterThermalTank(WaterThermalTankNum)%FirstRecoveryFuel
! Calculate Energy Factor based on total energy (including parasitics) used over entire test
EnergyFactor = TotalDrawMass * CPHW(57.2222d0) * (57.2222d0 - 14.4444d0) / FuelEnergy
ELSE
RecoveryEfficiency = 0.0d0
EnergyFactor = 0.0d0
CALL ShowWarningError('Water heater = '//TRIM(WaterThermalTank(WaterThermalTankNum)%Name)// &
': Recovery Efficiency and Energy Factor could not be calculated during the test for standard ratings')
CALL ShowContinueError('Setpoint was never recovered and/or heater never turned on')
END IF
ELSE
! Storage-only tank
RecoveryEfficiency = 0.0d0
EnergyFactor = 0.0d0
END IF ! WaterThermalTank(WaterThermalTankNum)%MaxCapacity > 0.0
!create predefined report
! Store values for the input verification and summary report
IF(WaterThermalTank(WaterThermalTankNum)%HeatPumpNum .EQ. 0)THEN
equipName = WaterThermalTank(WaterThermalTankNum)%Name
CALL PreDefTableEntry(pdchSWHType,equipName,WaterThermalTank(WaterThermalTankNum)%Type)
CALL PreDefTableEntry(pdchSWHVol,equipName,WaterThermalTank(WaterThermalTankNum)%Volume)
CALL PreDefTableEntry(pdchSWHHeatIn,equipName,WaterThermalTank(WaterThermalTankNum)%MaxCapacity)
CALL PreDefTableEntry(pdchSWHThEff,equipName,WaterThermalTank(WaterThermalTankNum)%Efficiency)
CALL PreDefTableEntry(pdchSWHRecEff,equipName,RecoveryEfficiency)
CALL PreDefTableEntry(pdchSWHEnFac,equipName,EnergyFactor)
ELSE
equipName = HPWaterHeater(WaterThermalTank(WaterThermalTankNum)%HeatPumpNum)%Name
CALL PreDefTableEntry(pdchSWHType,equipName,HPWaterHeater(WaterThermalTank(WaterThermalTankNum)%HeatPumpNum)%Type)
CALL PreDefTableEntry(pdchSWHVol,equipName,WaterThermalTank(WaterThermalTankNum)%Volume)
CALL PreDefTableEntry(pdchSWHHeatIn,equipName,HPWHHeatingCapacity)
CALL PreDefTableEntry(pdchSWHThEff,equipName,WaterThermalTank(WaterThermalTankNum)%Efficiency)
CALL PreDefTableEntry(pdchSWHRecEff,equipName,RecoveryEfficiency)
CALL PreDefTableEntry(pdchSWHEnFac,equipName,EnergyFactor)
END IF
! Write test results
IF(WaterThermalTank(WaterThermalTankNum)%HeatPumpNum .EQ. 0)THEN
IF (WaterThermalTank(WaterThermalTankNum)%TypeNum == StratifiedWaterHeater) THEN
IF (WaterThermalTank(WaterThermalTankNum)%ControlType == PriorityMasterSlave) THEN
MaxCapacity = MAX(WaterThermalTank(WaterThermalTankNum)%MaxCapacity, WaterThermalTank(WaterThermalTankNum)%MaxCapacity2)
ELSE ! PrioritySimultaneous
MaxCapacity = WaterThermalTank(WaterThermalTankNum)%MaxCapacity + WaterThermalTank(WaterThermalTankNum)%MaxCapacity2
END IF
ELSE ! WaterHeaterMixed
MaxCapacity = WaterThermalTank(WaterThermalTankNum)%MaxCapacity
END IF
WRITE(OutputFileInits,720) TRIM(WaterThermalTank(WaterThermalTankNum)%Type), TRIM(WaterThermalTank(WaterThermalTankNum)%Name), &
TRIM(TrimSigDigits(WaterThermalTank(WaterThermalTankNum)%Volume,4)), &
TRIM(TrimSigDigits(MaxCapacity,1)), &
TRIM(TrimSigDigits(RecoveryEfficiency,3)), &
TRIM(TrimSigDigits(EnergyFactor,4))
ELSE
WRITE(OutputFileInits,721) TRIM(HPWaterHeater(WaterThermalTank(WaterThermalTankNum)%HeatPumpNum)%Type), &
TRIM(HPWaterHeater(WaterThermalTank(WaterThermalTankNum)%HeatPumpNum)%Name), &
TRIM(TrimSigDigits(WaterThermalTank(WaterThermalTankNum)%Volume,4)), &
TRIM(TrimSigDigits(HPWHHeatingCapacity,1)), &
TRIM(TrimSigDigits(RecoveryEfficiency,3)), &
TRIM(TrimSigDigits(EnergyFactor,4)), &
TRIM(TrimSigDigits(RatedDXCoilTotalCapacity,0))
END IF
720 FORMAT('Water Heater Information',6(',',A))
721 FORMAT('Heat Pump Water Heater Information',7(',',A))
AlreadyRated(WaterThermalTankNum) = .TRUE.
RETURN
END SUBROUTINE CalcStandardRatings