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