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 CalcAirflowNetworkHeatBalance
! SUBROUTINE INFORMATION:
! AUTHOR Lixing Gu
! DATE WRITTEN Oct. 2005
! MODIFIED na
! RE-ENGINEERED Revised based on Subroutine CalcADSHeatBalance
! PURPOSE OF THIS SUBROUTINE:
! This subroutine performs AirflowNetwork thermal simulations.
! METHODOLOGY EMPLOYED:
! na
! REFERENCES:
! na
! USE STATEMENTS:
! na
IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
! SUBROUTINE ARGUMENT DEFINITIONS:
! na
! SUBROUTINE PARAMETER DEFINITIONS:
CHARACTER(len=*), PARAMETER :: Blank=' '
! INTERFACE BLOCK SPECIFICATIONS
! na
! DERIVED TYPE DEFINITIONS
! na
! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
INTEGER i,j
INTEGER LF,LT,CompNum,NF,NT
INTEGER CompTypeNum,TypeNum
Character(len=MaxNameLength) CompName
REAL(r64) Ei,DirSign,Tamb
REAL(r64) CpAir, TZON, load
INTEGER ZoneNum
LOGICAL found,OANode
MA = 0.0d0
MV = 0.0d0
DO I=1,AirflowNetworkNumOfLinks
CompNum = AirflowNetworkLinkageData(i)%CompNum
CompTypeNum = AirflowNetworkCompData(CompNum)%CompTypeNum
CompName = AirflowNetworkCompData(CompNum)%EPlusName
CpAir = PsyCpAirFnWTdb((AirflowNetworkNodeSimu(AirflowNetworkLinkageData(i)%NodeNums(1))%WZ+ &
AirflowNetworkNodeSimu(AirflowNetworkLinkageData(i)%NodeNums(2))%WZ)/2.0d0, &
(AirflowNetworkNodeSimu(AirflowNetworkLinkageData(i)%NodeNums(1))%TZ+ &
AirflowNetworkNodeSimu(AirflowNetworkLinkageData(i)%NodeNums(2))%TZ)/2.0d0)
! Calculate duct conduction loss
if (CompTypeNum == CompTypeNum_DWC .AND. CompName == Blank) then ! Duct element only
TypeNum = AirflowNetworkCompData(CompNum)%TypeNum
IF (AirflowNetworkLinkSimu(I)%FLOW .GT. 0) then ! flow direction is tha same as input from node 1 to node 2
LF = AirflowNetworkLinkageData(i)%NodeNums(1)
LT = AirflowNetworkLinkageData(i)%NodeNums(2)
DirSign = 1.0d0
else ! flow direction is tha opposite as input from node 2 to node 1
LF = AirflowNetworkLinkageData(i)%NodeNums(2)
LT = AirflowNetworkLinkageData(i)%NodeNums(1)
DirSign = -1.0d0
end if
! Fatal error when return flow is opposite to the desired direction
If (AirflowNetworkLinkSimu(I)%FLOW .EQ. 0.0d0 .AND. AirflowNetworkLinkSimu(I)%FLOW2 > 0.0d0) Then
CALL ShowSevereError('AirflowNetwork: The airflow direction is opposite to the intended direction ' &
//'(from node 1 to node 2) in AirflowNetwork:Distribution:Linkage = '//Trim(AirflowNetworkLinkageData(i)%Name))
CALL ShowContinueErrorTimeStamp(' ')
CALL ShowContinueError('The sum of the airflows entering the zone is greater than the airflows leaving the zone '// &
'(e.g., wind and stack effect).')
CALL ShowContinueError('Please check wind speed or reduce values of "Window/Door Opening Factor, '// &
'or Crack Factor" defined in AirflowNetwork:MultiZone:Surface objects.')
CALL ShowFatalError('AirflowNetwork: The previous error causes termination.')
End If
Ei = exp(-DisSysCompDuctData(TypeNum)%UThermal*DisSysCompDuctData(TypeNum)%L*DisSysCompDuctData(TypeNum)%D*pi/ &
(DirSign*AirflowNetworkLinkSimu(I)%FLOW*CpAir))
if (AirflowNetworkLinkageData(i)%ZoneNum < 0) then
Tamb = OutDryBulbTempAt(AirflowNetworkNodeData(AirflowNetworkLinkageData(i)%NodeNums(2))%NodeHeight)
else if (AirflowNetworkLinkageData(i)%ZoneNum == 0) then
Tamb = AirflowNetworkNodeSimu(LT)%TZ
else
Tamb = ANZT(AirflowNetworkLinkageData(i)%ZoneNum)
end if
MA((LT-1)*AirflowNetworkNumOfNodes+LT) = MA((LT-1)*AirflowNetworkNumOfNodes+LT)+ &
Abs(AirflowNetworkLinkSimu(I)%FLOW)*CpAir
MA((LT-1)*AirflowNetworkNumOfNodes+LF) = -Abs(AirflowNetworkLinkSimu(I)%FLOW)*CpAir*Ei
MV(LT) = MV(LT)+abs(AirflowNetworkLinkSimu(I)%FLOW)*Tamb*(1.0d0-Ei)*CpAir
end if
if (CompTypeNum == CompTypeNum_TMU) then ! Reheat unit: SINGLE DUCT:CONST VOLUME:REHEAT
TypeNum = AirflowNetworkCompData(CompNum)%TypeNum
IF (AirflowNetworkLinkSimu(I)%FLOW .GT. 0.d0) then ! flow direction is tha same as input from node 1 to node 2
LF = AirflowNetworkLinkageData(i)%NodeNums(1)
LT = AirflowNetworkLinkageData(i)%NodeNums(2)
DirSign = 1.0d0
else ! flow direction is tha opposite as input from node 2 to node 1
LF = AirflowNetworkLinkageData(i)%NodeNums(2)
LT = AirflowNetworkLinkageData(i)%NodeNums(1)
DirSign = -1.0d0
end if
Ei = exp(-0.001d0*DisSysCompTermUnitData(TypeNum)%L*DisSysCompTermUnitData(TypeNum)%D*pi/ &
(DirSign*AirflowNetworkLinkSimu(I)%FLOW*CpAir))
Tamb = AirflowNetworkNodeSimu(LT)%TZ
MA((LT-1)*AirflowNetworkNumOfNodes+LT) = MA((LT-1)*AirflowNetworkNumOfNodes+LT)+ &
Abs(AirflowNetworkLinkSimu(I)%FLOW)*CpAir
MA((LT-1)*AirflowNetworkNumOfNodes+LF) = -Abs(AirflowNetworkLinkSimu(I)%FLOW)*CpAir*Ei
MV(LT) = MV(LT)+abs(AirflowNetworkLinkSimu(I)%FLOW)*Tamb*(1.0d0-Ei)*CpAir
end if
if (CompTypeNum == CompTypeNum_COI) then ! heating or cooling coil
TypeNum = AirflowNetworkCompData(CompNum)%TypeNum
IF (AirflowNetworkLinkSimu(I)%FLOW .GT. 0.d0) then ! flow direction is tha same as input from node 1 to node 2
LF = AirflowNetworkLinkageData(i)%NodeNums(1)
LT = AirflowNetworkLinkageData(i)%NodeNums(2)
DirSign = 1.0d0
else ! flow direction is tha opposite as input from node 2 to node 1
LF = AirflowNetworkLinkageData(i)%NodeNums(2)
LT = AirflowNetworkLinkageData(i)%NodeNums(1)
DirSign = -1.0d0
end if
! Ei = exp(-0.001*DisSysCompCoilData(TypeNum)%L*DisSysCompCoilData(TypeNum)%D*pi/ &
! (DirSign*AirflowNetworkLinkSimu(I)%FLOW*CpAir))
! Tamb = AirflowNetworkNodeSimu(LT)%TZ
! MA((LT-1)*AirflowNetworkNumOfNodes+LT) = MA((LT-1)*AirflowNetworkNumOfNodes+LT)+ &
! Abs(AirflowNetworkLinkSimu(I)%FLOW)*CpAir
! MA((LT-1)*AirflowNetworkNumOfNodes+LF) = -Abs(AirflowNetworkLinkSimu(I)%FLOW)*CpAir*Ei
! MV(LT) = MV(LT)+abs(AirflowNetworkLinkSimu(I)%FLOW)*Tamb*(1.0-Ei)*CpAir
end if
! Calculate temp in a constant pressure drop element
if (CompTypeNum == CompTypeNum_CPD .AND. CompName == Blank) then ! constant pressure element only
IF (AirflowNetworkLinkSimu(I)%FLOW .GT. 0) then ! flow direction is tha same as input from node 1 to node 2
LF = AirflowNetworkLinkageData(i)%NodeNums(1)
LT = AirflowNetworkLinkageData(i)%NodeNums(2)
else ! flow direction is tha opposite as input from node 2 to node 1
LF = AirflowNetworkLinkageData(i)%NodeNums(2)
LT = AirflowNetworkLinkageData(i)%NodeNums(1)
end if
MA((LT-1)*AirflowNetworkNumOfNodes+LT) = MA((LT-1)*AirflowNetworkNumOfNodes+LT)+ &
Abs(AirflowNetworkLinkSimu(I)%FLOW)*CpAir
MA((LT-1)*AirflowNetworkNumOfNodes+LF) = -Abs(AirflowNetworkLinkSimu(I)%FLOW)*CpAir
MV(LT) = 0.0d0
end if
! Calculate return leak
if ((CompTypeNum == CompTypeNum_PLR .OR. CompTypeNum == CompTypeNum_ELR) .AND. CompName == Blank) then
! Return leak element only
if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i)%NodeNums(1))%EPlusZoneNum > 0) .AND. &
(AirflowNetworkNodeData(AirflowNetworkLinkageData(i)%NodeNums(2))%EPlusZoneNum == 0) .AND. &
(AirflowNetworkLinkSimu(I)%FLOW .GT. 0.0d0)) then
LF = AirflowNetworkLinkageData(i)%NodeNums(1)
LT = AirflowNetworkLinkageData(i)%NodeNums(2)
MA((LT-1)*AirflowNetworkNumOfNodes+LT) = MA((LT-1)*AirflowNetworkNumOfNodes+LT)+Abs(AirflowNetworkLinkSimu(I)%FLOW)*CpAir
MA((LT-1)*AirflowNetworkNumOfNodes+LF) = -Abs(AirflowNetworkLinkSimu(I)%FLOW)*CpAir
end if
if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i)%NodeNums(1))%ExtNodeNum > 0) .AND. &
(AirflowNetworkNodeData(AirflowNetworkLinkageData(i)%NodeNums(2))%EPlusZoneNum == 0) .AND. &
(AirflowNetworkLinkSimu(I)%FLOW .GT. 0.0d0)) then
LF = AirflowNetworkLinkageData(i)%NodeNums(1)
LT = AirflowNetworkLinkageData(i)%NodeNums(2)
MA((LT-1)*AirflowNetworkNumOfNodes+LT) = MA((LT-1)*AirflowNetworkNumOfNodes+LT)+ &
Abs(AirflowNetworkLinkSimu(I)%FLOW)*CpAir
MA((LT-1)*AirflowNetworkNumOfNodes+LF) = -Abs(AirflowNetworkLinkSimu(I)%FLOW)*CpAir
end if
if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i)%NodeNums(2))%EPlusZoneNum > 0) .AND. &
(AirflowNetworkNodeData(AirflowNetworkLinkageData(i)%NodeNums(1))%EPlusZoneNum == 0) .AND. &
(AirflowNetworkLinkSimu(I)%FLOW2 .GT. 0.0d0)) then
LF = AirflowNetworkLinkageData(i)%NodeNums(2)
LT = AirflowNetworkLinkageData(i)%NodeNums(1)
MA((LT-1)*AirflowNetworkNumOfNodes+LT) = MA((LT-1)*AirflowNetworkNumOfNodes+LT)+ &
Abs(AirflowNetworkLinkSimu(I)%FLOW2)*CpAir
MA((LT-1)*AirflowNetworkNumOfNodes+LF) = -Abs(AirflowNetworkLinkSimu(I)%FLOW2)*CpAir
end if
if ((AirflowNetworkNodeData(AirflowNetworkLinkageData(i)%NodeNums(2))%ExtNodeNum > 0) .AND. &
(AirflowNetworkNodeData(AirflowNetworkLinkageData(i)%NodeNums(1))%EPlusZoneNum == 0) .AND. &
(AirflowNetworkLinkSimu(I)%FLOW2 .GT. 0.0d0)) then
LF = AirflowNetworkLinkageData(i)%NodeNums(2)
LT = AirflowNetworkLinkageData(i)%NodeNums(1)
MA((LT-1)*AirflowNetworkNumOfNodes+LT) = MA((LT-1)*AirflowNetworkNumOfNodes+LT)+ &
Abs(AirflowNetworkLinkSimu(I)%FLOW2)*CpAir
MA((LT-1)*AirflowNetworkNumOfNodes+LF) = -Abs(AirflowNetworkLinkSimu(I)%FLOW2)*CpAir
end if
end if
! Check reheat unit or coil
if (AirflowNetworkCompData(CompNum)%EPlusTypeNum .EQ. EPlusTypeNum_RHT .AND. &
(.NOT. AirflowNetworkLinkageData(i)%VAVTermDamper)) then
NF = 0
NT = 0
if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i)%NodeNums(1))%EPlusNodeNum > 0) then
NF = AirflowNetworkNodeData(AirflowNetworkLinkageData(i)%NodeNums(1))%EPlusNodeNum
end if
if (AirflowNetworkNodeData(AirflowNetworkLinkageData(i)%NodeNums(2))%EPlusNodeNum > 0) then
NT = AirflowNetworkNodeData(AirflowNetworkLinkageData(i)%NodeNums(2))%EPlusNodeNum
end if
if ((NF .EQ. 0) .OR. (NT .EQ. 0)) then
CALL ShowFatalError('Node number in the primary air loop is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE = ' &
//AirflowNetworkLinkageData(i)%Name)
end if
if (AirflowNetworkLinkSimu(I)%FLOW .GT. 0.0d0) then
LF = AirflowNetworkLinkageData(i)%NodeNums(1)
LT = AirflowNetworkLinkageData(i)%NodeNums(2)
load = Node(NT)%Temp-Node(NF)%Temp
else
LF = AirflowNetworkLinkageData(i)%NodeNums(2)
LT = AirflowNetworkLinkageData(i)%NodeNums(1)
load = Node(NF)%Temp-Node(NT)%Temp
end if
CpAir = PsyCpAirFnWTdb(Node(NT)%HumRat,Node(NT)%Temp)
MV(LT) = MV(LT)+AirflowNetworkLinkSimu(I)%FLOW*CpAir*load
end if
END DO
! Prescribe temperature for EPlus nodes
DO I=1,AirflowNetworkNumOfNodes
found = .FALSE.
OANode = .FALSE.
DO J=1,AirflowNetworkNumOfLinks
if (AirflowNetworkLinkageData(J)%NodeNums(1) == I .OR. AirflowNetworkLinkageData(J)%NodeNums(2) == I) then
CompNum = AirflowNetworkLinkageData(j)%CompNum
if (AirflowNetworkCompData(CompNum)%EPlusTypeNum .EQ. EPlusTypeNum_RHT .AND. &
(.NOT. AirflowNetworkLinkageData(J)%VAVTermDamper)) then
found = .TRUE.
Exit
end if
! Overwrite fan outlet node
if (AirflowNetworkCompData(CompNum)%EPlusTypeNum .EQ. EPlusTypeNum_FAN .AND. &
AirflowNetworkLinkageData(J)%NodeNums(2) == I) then
found = .FALSE.
Exit
end if
! Overwrite return connection outlet
if (AirflowNetworkLinkageData(j)%ConnectionFlag .EQ. EPlusTypeNum_RCN ) then ! Modified on 9/2/09
found = .TRUE.
Exit
end if
if (AirflowNetworkLinkageData(j)%ConnectionFlag .EQ. EPlusTypeNum_SCN .AND. & ! Modified on 9/2/09
AirflowNetworkLinkageData(J)%NodeNums(2) == I) then
found = .TRUE.
Exit
end if
end if
if (AirflowNetworkLinkageData(J)%NodeNums(2) == I .AND. &
AirflowNetworkNodeData(AirflowNetworkLinkageData(J)%NodeNums(1))%EPlusTypeNum == EPlusTypeNum_OAN) then
OANode = .TRUE.
Exit
End if
END DO
if (found) cycle
if (AirflowNetworkNodeData(I)%EPlusZoneNum .eq. 0 .AND. &
AirflowNetworkNodeData(I)%EPlusTypeNum .EQ. EPlusTypeNum_ZIN) cycle
J = AirflowNetworkNodeData(I)%EPlusNodeNum
if (J > 0 .AND. (AirflowNetworkNodeData(I)%EPlusZoneNum > 0 .OR. &
AirflowNetworkNodeData(I)%EPlusTypeNum == EPlusTypeNum_FOU .OR. &
AirflowNetworkNodeData(I)%EPlusTypeNum == EPlusTypeNum_COU .OR. &
AirflowNetworkNodeData(I)%EPlusTypeNum == EPlusTypeNum_HXO)) then
MA((I-1)*AirflowNetworkNumOfNodes+I) = 1.0d10
MV(I) = Node(j)%Temp*1.0d10
end if
if (J > 0 .AND. OANode) then
MA((I-1)*AirflowNetworkNumOfNodes+I) = 1.0d10
MV(I) = Node(j)%Temp*1.0d10
end if
if (AirflowNetworkNodeData(I)%EPlusZoneNum > 0 .AND. &
MA((I-1)*AirflowNetworkNumOfNodes+I) .LT. 0.9d10 ) then
ZoneNum = AirflowNetworkNodeData(I)%EPlusZoneNum
MA((I-1)*AirflowNetworkNumOfNodes+I) = 1.0d10
MV(I) = ANZT(ZoneNum)*1.0d10
end if
if (AirflowNetworkNodeData(I)%ExtNodeNum > 0 .AND. &
MA((I-1)*AirflowNetworkNumOfNodes+I) .LT. 0.9d10 ) then
MA((I-1)*AirflowNetworkNumOfNodes+I) = 1.0d10
MV(I) = OutDryBulbTempAt(AirflowNetworkNodeData(I)%NodeHeight)*1.0d10
end if
END DO
! Check singularity
DO I=1,AirflowNetworkNumOfNodes
if (MA((I-1)*AirflowNetworkNumOfNodes+I) .LT. 1.0d-6) then
CALL ShowFatalError('CalcAirflowNetworkHeatBalance: A diagonal entity is zero in AirflowNetwork matrix at node '// &
TRIM(AirflowNetworkNodeData(I)%Name))
end if
END DO
! Get an inverse matrix
Call MRXINV(AirflowNetworkNumOfNodes)
! Calculate node temperatures
DO I=1,AirflowNetworkNumOfNodes
TZON = 0.0d0
DO J=1, AirflowNetworkNumOfNodes
TZON = TZON +MA((I-1)*AirflowNetworkNumOfNodes+J)*MV(J)
END DO
AirflowNetworkNodeSimu(I)%TZ = TZON
END DO
RETURN
END SUBROUTINE CalcAirflowNetworkHeatBalance