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) | :: | OAUnitNum | |||
character(len=*), | intent(in) | :: | EquipType | |||
character(len=*), | intent(in) | :: | EquipName | |||
integer, | intent(in) | :: | EquipNum | |||
integer, | intent(in) | :: | CompTypeNum | |||
logical, | intent(in) | :: | FirstHVACIteration | |||
integer, | intent(inout) | :: | CompIndex | |||
logical, | intent(in) | :: | Sim |
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 SimOutdoorAirEquipComps(OAUnitNum,EquipType,EquipName,EquipNum,CompTypeNum,FirstHVACIteration,CompIndex,Sim)
! SUBROUTINE INFORMATION:
! AUTHOR Young Tae Chae, Rick Strand
! DATE WRITTEN June 2008
! MODIFIED
! RE-ENGINEERED na
! PURPOSE OF THIS SUBROUTINE:
! Outdoor air unit has various coil options. This subroutine defines the coil loads and execute
! to simulate each components
!
! METHODOLOGY EMPLOYED:
! REFERENCES:
! USE STATEMENTS:
USE DataZoneEnergyDemands
USE DataEnvironment, ONLY : OutDryBulbTemp, OutWetBulbTemp, EnvironmentName, CurMnDy, OutBaroPress
USE DataHeatBalance, ONLY : MRT
USE DataHeatBalFanSys, ONLY : MAT,ZoneAirHumRat
USE DataHVACGlobals, ONLY : SmallLoad
USE DataLoopNode, ONLY : Node
USE ScheduleManager, ONLY : GetCurrentScheduleValue
USE General, ONLY : TrimSigDigits
USE NodeInputManager, ONLY : GetOnlySingleNode
Use Fans, Only:SimulateFanComponents
Use WaterCoils, Only:SimulateWaterCoilComponents
Use HeatingCoils, Only:SimulateHeatingCoilComponents
Use HeatRecovery, Only: SimHeatRecovery
Use DesiccantDehumidifiers, Only:SimDesiccantDehumidifier
Use HVACHXAssistedCoolingCoil, Only:SimHXAssistedCoolingCoil
Use HVACDXSystem, Only: SimDXCoolingSystem
Use HVACDXHeatPumpSystem, Only: SimDXHeatPumpSystem
Use SteamCoils, Only:SimulateSteamCoilComponents
Use DataInterfaces, Only:ControlCompOutput
USE HVACUnitarySystem, ONLY:SimUnitarySystem
! Use TranspiredCollector, Only:SimTranspiredCollector
! Use EvaporativeCoolers, Only:SimEvapCooler
! USE PhotovoltaicThermalCollectors, ONLY:SimPVTcollectors, CalledFromOutsideAirSystem
IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
! SUBROUTINE ARGUMENT DEFINITIONS:
LOGICAL, INTENT (IN) :: FirstHVACIteration
CHARACTER(len=*), INTENT (IN) :: EquipType ! the component type
CHARACTER(len=*), INTENT (IN) :: EquipName ! the component Name
INTEGER, INTENT(IN) :: CompTypeNum ! Component Type -- Integerized for this module
INTEGER, INTENT(IN) :: EquipNum
INTEGER, INTENT(IN) :: OAUnitNum ! actual outdoor air unit num
INTEGER, INTENT(INOUT) :: CompIndex
LOGICAL, INTENT(IN) :: Sim ! if TRUE, simulate component
! SUBROUTINE PARAMETER DEFINITIONS: None
! INTERFACE BLOCK DEFINITIONS:
! see use DataInterfaces
! DERIVED TYPE DEFINITIONS: None
! SUBROUTINE LOCAL VARIABLE DEFINITIONS
INTEGER :: OperatingMode
REAL(r64) :: OAMassFlow
REAL(r64) :: QCompReq
INTEGER :: UnitNum
REAL(r64) :: MaxWaterFlow
REAL(r64) :: MinWaterFlow
INTEGER :: ControlNode
INTEGER :: CoilInletNode
INTEGER :: OutletNode
REAL(r64) :: CpAirZn
INTEGER :: AirOutletNode
INTEGER :: CoilWaterInletNode
INTEGER :: SimCompNum
INTEGER :: OpMode
INTEGER :: EquipTypeNum
INTEGER :: WCCoilInletNode
INTEGER :: WCCoilOutletNode
INTEGER :: WCCoilContNode
INTEGER :: WHCoilInletNode
INTEGER :: WHCoilOutletNode
INTEGER :: WHCoilContNode
INTEGER :: SHCoilInletNode
INTEGER :: SHCoilOutletNode
REAL(r64) :: Qcoilout
REAL(r64) :: QUnitOut
INTEGER :: DXSystemIndex =0
REAL(r64) :: CompAirOutTemp
REAL(r64) :: Faneffect
LOGICAL :: DrawFan !fan position If .True., the temperature increasing by fan operating is considered
REAL(r64) :: Dxsystemouttemp
REAL(r64) :: DXsystemInlettemp
LOGICAL :: ErrorsFound=.FALSE. ! Set to true if errors in input, fatal at end of routine
LOGICAL :: HeatActive=.FALSE.
LOGICAL :: CoolActive=.FALSE.
! Flow!
UnitNum = OAUnitNum
CompAirOutTemp = OutAirUnit(OAUnitNum)%CompOutSetTemp
OPmode = OutAirUnit(OAUnitNum)%OperatingMode
SimCompNum = EquipNum
EquipTypeNum = OutAirUnit(OAUnitNum)%OAEquip(SimCompNum)%ComponentType_Num
OAMassFlow = OutAirUnit(OAUnitNum)%OutAirMassFlow
DrawFan = OutAirUnit(OAUnitNum)%FanEffect
DXSystemIndex = 0
!check the fan positioning
IF (DrawFan) THEN
Faneffect = OutAirUnit(OAUnitNum)%FanCorTemp ! Heat effect by fan
ELSE
Faneffect = 0.0d0
END IF
! checking equipment index
SELECT CASE(EquipTypeNum)
! Heat recovery
CASE(HeatXchngr) ! 'HeatExchanger:AirToAir:FlatPlate', 'HeatExchanger:AirToAir:SensibleAndLatent',
! 'HeatExchanger:Desiccant:BalancedFlow'
IF (Sim) Then
CALL SimHeatRecovery(EquipName,FirstHVACIteration,CompIndex, ContFanCycCoil, &
EconomizerFlag=.FALSE., &
HighHumCtrlFlag=.FALSE.)
END IF
! Desiccant Dehumidifier
CASE(Desiccant) ! 'Dehumidifier:Desiccant:NoFans'
IF (Sim) Then
CALL SimDesiccantDehumidifier(EquipName,FirstHVACIteration,CompIndex)
END IF
CASE(WaterCoil_SimpleHeat) ! ('Coil:Heating:Water')
IF (Sim) Then
ControlNode = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%CoilWaterInletNode
MaxWaterFlow = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%MaxWaterMassFlow
MinWaterFlow = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%MinWaterMassFlow
!On the first HVAC iteration the system values are given to the controller, but after that
! the demand limits are in place and there needs to be feedback to the Zone Equipment
IF((.not. FirstHVACIteration) .and. (ControlNode > 0)) Then
MaxWaterFlow = Node(ControlNode)%MassFlowRateMaxAvail
MinWaterFlow = Node(ControlNode)%MassFlowRateMinAvail
END IF
WHCoilInletNode =OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%CoilAirInletNode
WHCoilOutletNode=OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%CoilAirOutletNode
CpAirZn = PsyCpAirFnWTdb(Node(WHCoilInletNode)%HumRat,Node(WHCoilInletNode)%Temp)
IF((OPMode == NeutralMode).OR.(OPMode == CoolingMode)&
.OR.(Node(WHCoilInletNode)%Temp > CompAirOutTemp) ) THEN
QCompReq=0.0d0
ELSE
QCompReq=CpAirZn*OAMassFlow*((CompAirOutTemp-Node(WHCoilInletNode)%Temp)-faneffect)
IF (ABS(QCompReq) < SmallLoad) QCompReq = 0.d0
IF (QCompReq < 0.d0) QCompReq = 0.d0 ! coil can heat only
END IF
CALL ControlCompOutput(CompName=OutAirUnit(OAUnitNum)%Name, CompType=cMO_OutdoorAirUnit,CompNum=UnitNum, &
FirstHVACIteration=FirstHVACIteration,QZnReq=QCompReq, &
ActuatedNode=ControlNode,MaxFlow=MaxWaterFlow, &
MinFlow=MinWaterFlow,ControlOffSet=0.0001d0,Action=2, &
ControlCompTypeNum=OutAirUnit(OAUnitNum)%ControlCompTypeNum,&
CompErrIndex=OutAirUnit(OAUnitNum)%CompErrIndex,EquipIndex=SimCompNum,&
LoopNum = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%LoopNum,&
LoopSide = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%LoopSideNum,&
BranchIndex = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%BranchNum)
END IF
CASE(SteamCoil_AirHeat) ! 'Coil:Heating:Steam'
IF (Sim) Then
Call CalcOAUnitCoilComps(unitnum,FirstHVACIteration,SimCompNum,QunitOut)
END IF
CASE(Coil_ElectricHeat) ! 'Coil:Heating:Electric'
IF (Sim) Then
! stand-alone coils are temperature controlled (do not pass QCoilReq in argument list, QCoilReq overrides temp SP)
Call CalcOAUnitCoilComps(unitnum,FirstHVACIteration,SimCompNum,QunitOut)
END IF
CASE(Coil_GasHeat) ! 'Coil:Heating:Gas'
IF (Sim) Then
! stand-alone coils are temperature controlled (do not pass QCoilReq in argument list, QCoilReq overrides temp SP)
Call CalcOAUnitCoilComps(unitnum,FirstHVACIteration,SimCompNum,QunitOut)
END IF
! water cooling coil Types
CASE(WaterCoil_Cooling) ! 'Coil:Cooling:Water'
IF (Sim) Then
ControlNode = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%CoilWaterInletNode
MaxWaterFlow = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%MaxWaterMassFlow
MinWaterFlow = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%MinWaterMassFlow
! On the first HVAC iteration the system values are given to the controller, but after that
! the demand limits are in place and there needs to be feedback to the Zone Equipment
If((.not. FirstHVACIteration) .and. (ControlNode > 0)) Then
MaxWaterFlow = Node(ControlNode)%MassFlowRateMaxAvail
MinWaterFlow = Node(ControlNode)%MassFlowRateMinAvail
END IF
WCCoilInletNode=OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%CoilAirInletNode
WCCoilOutletNode=OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%CoilAirOutletNode
CpAirZn = PsyCpAirFnWTdb(Node(WCCoilInletNode)%HumRat,Node(WCCoilInletNode)%Temp)
OAMassFlow = OutAirUnit(OAUnitNum)%OutAirMassFlow
IF((OPMode == NeutralMode).OR.(OPMode == HeatingMode) &
.OR.(Node(WCCoilInletNode)%Temp<CompAirOutTemp)) THEN
QCompReq=0.0d0
Node(WCCoilOutletNode)%Temp=Node(WCCoilInletNode)%Temp
Node(WCCoilOutletNode)%HumRat=Node(WCCoilInletNode)%HumRat
Node(WCCoilOutletNode)%MassFlowRate=Node(WCCoilInletNode)%MassFlowRate
ELSE
QCompReq=CpAirZn*OAMassFlow*((CompAirOutTemp-Node(WCCoilInletNode)%Temp)-faneffect)
IF (ABS(QCompReq) < SmallLoad) QCompReq = 0.d0
IF (QCompReq > 0.d0) QCompReq = 0.d0 ! coil can cool only
END IF
CALL ControlCompOutput(CompName=OutAirUnit(OAUnitNum)%Name, CompType=cMO_OutdoorAirUnit,CompNum=UnitNum, &
FirstHVACIteration=FirstHVACIteration,QZnReq=QCompReq, &
ActuatedNode=ControlNode,MaxFlow=MaxWaterFlow, &
MinFlow=MinWaterFlow,ControlOffSet=0.001d0,Action=1, &
ControlCompTypeNum=OutAirUnit(OAUnitNum)%ControlCompTypeNum,&
CompErrIndex=OutAirUnit(OAUnitNum)%CompErrIndex,EquipIndex=SimCompNum,&
LoopNum = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%LoopNum,&
LoopSide = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%LoopSideNum,&
BranchIndex = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%BranchNum)
END IF
CASE(WaterCoil_DetailedCool) ! 'Coil:Cooling:Water:DetailedGeometry'
IF (Sim) Then
ControlNode = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%CoilWaterInletNode
MaxWaterFlow = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%MaxWaterMassFlow
MinWaterFlow = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%MinWaterMassFlow
!On the first HVAC iteration the system values are given to the controller, but after that
! the demand limits are in place and there needs to be feedback to the Zone Equipment
IF((.not. FirstHVACIteration) .and. (ControlNode > 0)) Then
MaxWaterFlow = Node(ControlNode)%MassFlowRateMaxAvail
MinWaterFlow = Node(ControlNode)%MassFlowRateMinAvail
END IF
WCCoilInletNode=OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%CoilAirInletNode
WCCoilOutletNode=OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%CoilAirOutletNode
CpAirZn = PsyCpAirFnWTdb(Node(WCCoilInletNode)%HumRat,Node(WCCoilInletNode)%Temp)
OAMassFlow = OutAirUnit(OAUnitNum)%OutAirMassFlow
IF((OPMode == NeutralMode).OR.(OPMode == HeatingMode) &
.OR.(Node(WCCoilInletNode)%Temp<CompAirOutTemp)) THEN
QCompReq=0.0d0
ELSE
QCompReq=CpAirZn*OAMassFlow*((CompAirOutTemp-Node(WCCoilInletNode)%Temp)-faneffect)
IF (ABS(QCompReq) < SmallLoad) QCompReq = 0.d0
IF (QCompReq > 0.d0) QCompReq = 0.d0 ! coil can cool only
END IF
CALL ControlCompOutput(CompName=OutAirUnit(OAUnitNum)%Name, CompType='ZONEHVAC:OUTDOORAIRUNIT',CompNum=UnitNum, &
FirstHVACIteration=FirstHVACIteration,QZnReq=QCompReq, &
ActuatedNode=ControlNode,MaxFlow=MaxWaterFlow, &
MinFlow=MinWaterFlow,ControlOffSet=0.001d0,Action=1, &
ControlCompTypeNum=OutAirUnit(OAUnitNum)%ControlCompTypeNum,&
CompErrIndex=OutAirUnit(OAUnitNum)%CompErrIndex,EquipIndex=SimCompNum,&
LoopNum = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%LoopNum,&
LoopSide = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%LoopSideNum,&
BranchIndex = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%BranchNum)
END IF
CASE(WaterCoil_CoolingHXAsst) ! 'CoilSystem:Cooling:Water:HeatExchangerAssisted'
IF (Sim) Then
ControlNode = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%CoilWaterInletNode
MaxWaterFlow = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%MaxWaterMassFlow
MinWaterFlow = 0.0d0
!On the first HVAC iteration the system values are given to the controller, but after that
! the demand limits are in place and there needs to be feedback to the Zone Equipment
IF((.not. FirstHVACIteration) .and. (ControlNode > 0)) Then
MaxWaterFlow = Node(ControlNode)%MassFlowRateMaxAvail
MinWaterFlow = Node(ControlNode)%MassFlowRateMinAvail
END IF
WCCoilInletNode=OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%CoilAirInletNode
WCCoilOutletNode=OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%CoilAirOutletNode
CpAirZn = PsyCpAirFnWTdb(Node(WCCoilInletNode)%HumRat,Node(WCCoilInletNode)%Temp)
OAMassFlow = OutAirUnit(OAUnitNum)%OutAirMassFlow
IF((OPMode == NeutralMode).OR.(OPMode == HeatingMode) &
.OR.(Node(WCCoilInletNode)%Temp<CompAirOutTemp)) THEN
QCompReq=0.0d0
ELSE
QCompReq=CpAirZn*OAMassFlow*((CompAirOutTemp-Node(WCCoilInletNode)%Temp)-faneffect)
IF (ABS(QCompReq) < SmallLoad) QCompReq = 0.d0
IF (QCompReq > 0.d0) QCompReq = 0.d0 ! coil can cool only
END IF
CALL ControlCompOutput(CompName=OutAirUnit(OAUnitNum)%Name, CompType='ZONEHVAC:OUTDOORAIRUNIT',CompNum=UnitNum, &
FirstHVACIteration=FirstHVACIteration,QZnReq=QCompReq, &
ActuatedNode=ControlNode,MaxFlow=MaxWaterFlow, &
MinFlow=MinWaterFlow,ControlOffSet=0.001d0,Action=1, &
ControlCompTypeNum=OutAirUnit(OAUnitNum)%ControlCompTypeNum,&
CompErrIndex=OutAirUnit(OAUnitNum)%CompErrIndex,EquipIndex=SimCompNum, &
LoopNum = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%LoopNum,&
LoopSide = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%LoopSideNum,&
BranchIndex = OutAirUnit(OAUnitNum)%OAEquip(EquipNum)%BranchNum)
END IF
CASE(DXSystem) ! CoilSystem:Cooling:DX old 'AirLoopHVAC:UnitaryCoolOnly'
IF (Sim) Then
IF (((OPMode == NeutralMode).AND.(OutAirUnit(OAUnitNum)%ControlType == Temperature)).OR.(OPMode == HeatingMode)) THEN
Dxsystemouttemp = 100.0d0 ! There is no cooling demand for the DX system.
ELSE
Dxsystemouttemp = CompAirOutTemp-faneffect
END IF
CALL SimDXCoolingSystem(EquipName,FirstHVACIteration,-1,DXSystemIndex,UnitNum,Dxsystemouttemp)
END IF
CASE(DXHeatPumpSystem)
IF (Sim) Then
IF (((OPMode == NeutralMode).AND.(OutAirUnit(OAUnitNum)%ControlType == Temperature)).OR.(OPMode == CoolingMode)) THEN
Dxsystemouttemp = -20.0d0 ! There is no heating demand for the DX system.
ELSE
Dxsystemouttemp = CompAirOutTemp-faneffect
END IF
CALL SimDXHeatPumpSystem( EquipName,FirstHVACIteration,-1,DXSystemIndex,UnitNum,Dxsystemouttemp)
ENDIF
CASE(UnitarySystem) ! 'AirLoopHVAC:UnitarySystem'
IF (Sim) Then
! This may have to be done in the unitary system object since there can be both cooling and heating
IF (((OPMode == NeutralMode).AND.(OutAirUnit(OAUnitNum)%ControlType == Temperature)).AND.(OPMode == HeatingMode)) THEN
Dxsystemouttemp = 100 ! There is no cooling demand.
ELSE IF (((OPMode == NeutralMode).AND.(OutAirUnit(OAUnitNum)%ControlType == Temperature)).AND.(OPMode == CoolingMode)) THEN
Dxsystemouttemp = -20 ! There is no heating demand.
ELSE
Dxsystemouttemp = CompAirOutTemp-faneffect
END IF
CALL SimUnitarySystem(EquipName,FirstHVACIteration,-1,DXSystemIndex,HeatActive,CoolActive,UnitNum,Dxsystemouttemp)
END IF
CASE DEFAULT
CALL ShowFatalError('Invalid Outdoor Air Unit Component='//TRIM(EquipType)) ! validate
END SELECT
RETURN
END SUBROUTINE SimOutdoorAirEquipComps