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.
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 GetDualDuctInput
! SUBROUTINE INFORMATION:
! AUTHOR Richard Liesen
! DATE WRITTEN April 1998
! MODIFIED na
! RE-ENGINEERED na
! PURPOSE OF THIS SUBROUTINE:
! This subroutine is the main routine to call other input routines and Get routines
! METHODOLOGY EMPLOYED:
! Uses the status flags to trigger events.
! REFERENCES:
! na
! USE STATEMENTS:
USE InputProcessor, ONLY: GetNumObjectsFound, GetObjectItem, VerifyName, SameString, FindItemInList
USE NodeInputManager, ONLY: GetOnlySingleNode
USE DataZoneEquipment, ONLY: ZoneEquipConfig
USE BranchNodeConnections, ONLY: TestCompSet
USE DataDefineEquip, ONLY: AirDistUnit, NumAirDistUnits
USE DataIPShortCuts
USE DataHeatBalance
USE General, ONLY : RoundSigDigits
USE ReportSizingManager, ONLY: ReportSizingOutput
IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
! SUBROUTINE ARGUMENT DEFINITIONS:
! na
! SUBROUTINE PARAMETER DEFINITIONS:
CHARACTER(len=*), PARAMETER :: RoutineName='GetDualDuctInput: ' ! include trailing bla
! INTERFACE BLOCK SPECIFICATIONS
! na
! DERIVED TYPE DEFINITIONS
! na
! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
INTEGER :: DamperNum ! The Damper that you are currently loading input into
INTEGER :: DamperIndex ! Loop index to Damper that you are currently loading input into
INTEGER :: NumAlphas
INTEGER :: NumNums
INTEGER :: IOSTAT
INTEGER :: ZoneNum ! Index to actual zone number
REAL(r64), DIMENSION(2) :: NumArray = 0.0d0
CHARACTER(len=MaxNameLength), DIMENSION(7) :: AlphArray = ' '
CHARACTER(len=MaxNameLength), DIMENSION(7) :: cAlphaFields = ' ' ! Alpha field names
CHARACTER(len=MaxNameLength), DIMENSION(2) :: cNumericFields = ' ' ! Numeric field names
LOGICAL, DIMENSION(7) :: lAlphaBlanks = .TRUE. ! Logical array, alpha field input BLANK = .true.
LOGICAL, DIMENSION(2) :: lNumericBlanks = .TRUE. ! Logical array, numeric field input BLANK = .true.
CHARACTER (len=MaxNameLength) :: CurrentModuleObject ! for ease in getting objects
LOGICAL :: ErrorsFound = .false. ! If errors detected in input
LOGICAL :: IsNotOK ! Flag to verify name
LOGICAL :: IsBlank ! Flag for blank name
INTEGER :: CtrlZone ! controlled zone do loop index
INTEGER :: SupAirIn ! controlled zone supply air inlet index
INTEGER :: ADUNum ! loop control to search Air Distribution Units
REAL(r64) :: DummyOAFlow = 0.0d0
! Flow
NumDualDuctConstVolDampers = GetNumObjectsFound(cCMO_DDConstantVolume)
NumDualDuctVarVolDampers = GetNumObjectsFound(cCMO_DDVariableVolume)
NumDualDuctVarVolOA = GetNumObjectsFound( cCMO_DDVarVolOA )
NumDampers = NumDualDuctConstVolDampers + NumDualDuctVarVolDampers + NumDualDuctVarVolOA
ALLOCATE(Damper(NumDampers))
ALLOCATE(CheckEquipName(NumDampers))
CheckEquipName=.true.
ALLOCATE(DamperInlet(NumDampers))
ALLOCATE(DamperHotAirInlet(NumDampers))
ALLOCATE(DamperColdAirInlet(NumDampers))
ALLOCATE(DamperOutlet(NumDampers))
ALLOCATE(DamperOAInlet(NumDampers))
ALLOCATE(DamperRecircAirInlet(NumDampers))
IF (NumDualDuctConstVolDampers .GT. 0) THEN
DO DamperIndex = 1, NumDualDuctConstVolDampers
CurrentModuleObject=cCMO_DDConstantVolume
CALL GetObjectItem(CurrentModuleObject,DamperIndex,AlphArray,NumAlphas,NumArray,NumNums,IOSTAT, &
NumBlank=lNumericBlanks,AlphaBlank=lAlphaBlanks, &
AlphaFieldNames=cAlphaFields,NumericFieldNames=cNumericFields)
DamperNum = DamperIndex
IsNotOK=.false.
IsBlank=.false.
CALL VerifyName(AlphArray(1),Damper%DamperName,DamperNum-1,IsNotOK,IsBlank,TRIM(CurrentModuleObject)//' Name')
IF (IsNotOK) THEN
ErrorsFound=.true.
IF (IsBlank) AlphArray(1)='xxxxx'
ENDIF
Damper(DamperNum)%DamperName = AlphArray(1)
Damper(DamperNum)%DamperType = DualDuct_ConstantVolume
Damper(DamperNum)%Schedule = AlphArray(2)
IF (lAlphaBlanks(2)) THEN
Damper(DamperNum)%SchedPtr = ScheduleAlwaysOn
ELSE
Damper(DamperNum)%SchedPtr = GetScheduleIndex(AlphArray(2))
IF (Damper(DamperNum)%SchedPtr == 0) THEN
CALL ShowSevereError(TRIM(CurrentModuleObject)//', "'//TRIM(Damper(DamperNum)%DamperName)//&
'" '//TRIM(cAlphaFields(2))//' = '//TRIM(AlphArray(2))//' not found.')
ErrorsFound=.true.
ENDIF
ENDIF
Damper(DamperNum)%OutletNodeNum = &
GetOnlySingleNode(AlphArray(3),ErrorsFound,TRIM(CurrentModuleObject),AlphArray(1), &
NodeType_Air,NodeConnectionType_Outlet,1,ObjectIsNotParent,cAlphaFields(3))
Damper(DamperNum)%HotAirInletNodeNum = &
GetOnlySingleNode(AlphArray(4),ErrorsFound,TRIM(CurrentModuleObject),AlphArray(1), &
NodeType_Air,NodeConnectionType_Inlet,1,ObjectIsNotParent,cAlphaFields(4))
Damper(DamperNum)%ColdAirInletNodeNum = &
GetOnlySingleNode(AlphArray(5),ErrorsFound,TRIM(CurrentModuleObject),AlphArray(1), &
NodeType_Air,NodeConnectionType_Inlet,1,ObjectIsNotParent,cAlphaFields(5))
Damper(DamperNum)%MaxAirVolFlowRate = NumArray(1)
Damper(DamperNum)%ZoneMinAirFrac = 0.0d0
! Register component set data - one for heat and one for cool
CALL TestCompSet(TRIM(CurrentModuleObject)//':HEAT',Damper(DamperNum)%DamperName, &
AlphArray(4),AlphArray(3),'Air Nodes')
CALL TestCompSet(TRIM(CurrentModuleObject)//':COOL',Damper(DamperNum)%DamperName, &
AlphArray(5),AlphArray(3),'Air Nodes')
! Fill the Zone Equipment data with the inlet node numbers of this unit.
DO CtrlZone = 1,NumOfZones
IF (.not. ZoneEquipConfig(CtrlZone)%IsControlled) CYCLE
DO SupAirIn = 1,ZoneEquipConfig(CtrlZone)%NumInletNodes
IF (Damper(DamperNum)%OutletNodeNum .EQ. ZoneEquipConfig(CtrlZone)%InletNode(SupAirIn)) THEN
IF (ZoneEquipConfig(CtrlZone)%AirDistUnitCool(SupAirIn)%OutNode > 0) THEN
CALL ShowSevereError('Error in connecting a terminal unit to a zone')
CALL ShowContinueError(TRIM(NodeID(Damper(DamperNum)%OutletNodeNum))//' already connects to another zone')
CALL ShowContinueError('Occurs for terminal unit '//TRIM(CurrentModuleObject)//' = '// &
TRIM(Damper(DamperNum)%DamperName))
CALL ShowContinueError('Check terminal unit node names for errors')
ErrorsFound = .true.
ELSE
ZoneEquipConfig(CtrlZone)%AirDistUnitCool(SupAirIn)%InNode = Damper(DamperNum)%ColdAirInletNodeNum
ZoneEquipConfig(CtrlZone)%AirDistUnitHeat(SupAirIn)%InNode = Damper(DamperNum)%HotAirInletNodeNum
ZoneEquipConfig(CtrlZone)%AirDistUnitCool(SupAirIn)%OutNode = Damper(DamperNum)%OutletNodeNum
ZoneEquipConfig(CtrlZone)%AirDistUnitHeat(SupAirIn)%OutNode = Damper(DamperNum)%OutletNodeNum
END IF
END IF
END DO
END DO
!Setup the Average damper Position output variable
! CurrentModuleObject='AirTerminal:DualDuct:ConstantVolume'
CALL SetupOutputVariable('Zone Air Terminal Cold Supply Duct Damper Position []', Damper(DamperNum)%ColdAirDamperPosition, &
'System','Average',Damper(DamperNum)%DamperName)
CALL SetupOutputVariable('Zone Air Terminal Hot Supply Duct Damper Position []', Damper(DamperNum)%HotAirDamperPosition, &
'System','Average',Damper(DamperNum)%DamperName)
END DO ! end Number of Damper Loop
END IF
IF (NumDualDuctVarVolDampers .GT. 0) THEN
DO DamperIndex = 1, NumDualDuctVarVolDampers
CurrentModuleObject=cCMO_DDVariableVolume
CALL GetObjectItem(CurrentModuleObject,DamperIndex,AlphArray,NumAlphas,NumArray,NumNums,IOSTAT, &
NumBlank=lNumericBlanks,AlphaBlank=lAlphaBlanks, &
AlphaFieldNames=cAlphaFields,NumericFieldNames=cNumericFields)
DamperNum = DamperIndex + NumDualDuctConstVolDampers
IsNotOK=.false.
IsBlank=.false.
CALL VerifyName(AlphArray(1),Damper%DamperName,DamperNum-1,IsNotOK,IsBlank,TRIM(CurrentModuleObject)//' Name')
IF (IsNotOK) THEN
ErrorsFound=.true.
IF (IsBlank) AlphArray(1)='xxxxx'
ENDIF
Damper(DamperNum)%DamperName = AlphArray(1)
Damper(DamperNum)%DamperType = DualDuct_VariableVolume
Damper(DamperNum)%Schedule = AlphArray(2)
IF (lAlphaBlanks(2)) THEN
Damper(DamperNum)%SchedPtr = ScheduleAlwaysOn
ELSE
Damper(DamperNum)%SchedPtr = GetScheduleIndex(AlphArray(2))
IF (Damper(DamperNum)%SchedPtr == 0) THEN
CALL ShowSevereError(TRIM(CurrentModuleObject)//', "'//TRIM(Damper(DamperNum)%DamperName)//&
'" '//TRIM(cAlphaFields(2))//' = '//TRIM(AlphArray(2))//' not found.')
ErrorsFound=.true.
ENDIF
ENDIF
Damper(DamperNum)%OutletNodeNum = &
GetOnlySingleNode(AlphArray(3),ErrorsFound,TRIM(CurrentModuleObject),AlphArray(1), &
NodeType_Air,NodeConnectionType_Outlet,1,ObjectIsNotParent,cAlphaFields(3))
Damper(DamperNum)%HotAirInletNodeNum = &
GetOnlySingleNode(AlphArray(4),ErrorsFound,TRIM(CurrentModuleObject),AlphArray(1), &
NodeType_Air,NodeConnectionType_Inlet,1,ObjectIsNotParent,cAlphaFields(4))
Damper(DamperNum)%ColdAirInletNodeNum = &
GetOnlySingleNode(AlphArray(5),ErrorsFound,TRIM(CurrentModuleObject),AlphArray(1), &
NodeType_Air,NodeConnectionType_Inlet,1,ObjectIsNotParent,cAlphaFields(5))
Damper(DamperNum)%MaxAirVolFlowRate = NumArray(1)
Damper(DamperNum)%ZoneMinAirFrac = NumArray(2)
! Register component set data - one for heat and one for cool
CALL TestCompSet(TRIM(CurrentModuleObject)//':HEAT',Damper(DamperNum)%DamperName, &
AlphArray(4),AlphArray(3),'Air Nodes')
CALL TestCompSet(TRIM(CurrentModuleObject)//':COOL',Damper(DamperNum)%DamperName, &
AlphArray(5),AlphArray(3),'Air Nodes')
! Fill the Zone Equipment data with the inlet node numbers of this unit.
DO CtrlZone = 1,NumOfZones
IF (.not. ZoneEquipConfig(CtrlZone)%IsControlled) CYCLE
DO SupAirIn = 1,ZoneEquipConfig(CtrlZone)%NumInletNodes
IF (Damper(DamperNum)%OutletNodeNum .EQ. ZoneEquipConfig(CtrlZone)%InletNode(SupAirIn)) THEN
ZoneEquipConfig(CtrlZone)%AirDistUnitCool(SupAirIn)%InNode = Damper(DamperNum)%ColdAirInletNodeNum
ZoneEquipConfig(CtrlZone)%AirDistUnitHeat(SupAirIn)%InNode = Damper(DamperNum)%HotAirInletNodeNum
ZoneEquipConfig(CtrlZone)%AirDistUnitCool(SupAirIn)%OutNode = Damper(DamperNum)%OutletNodeNum
ZoneEquipConfig(CtrlZone)%AirDistUnitHeat(SupAirIn)%OutNode = Damper(DamperNum)%OutletNodeNum
Damper(DamperNum)%CtrlZoneNum = CtrlZone
Damper(DamperNum)%ActualZoneNum = ZoneEquipConfig(CtrlZone)%ActualZoneNum
END IF
END DO
END DO
IF(.NOT. lAlphaBlanks(6))THEN
Damper(DamperNum)%OARequirementsPtr = FindItemInList(AlphArray(6),OARequirements%Name,NumOARequirements)
IF(Damper(DamperNum)%OARequirementsPtr .EQ. 0)THEN
CALL ShowSevereError(TRIM(cAlphaFields(6))//' = '//TRIM(AlphArray(6))//' not found.')
CALL ShowContinueError('Occurs in '//cCMO_DDVariableVolume//' = '//TRIM(Damper(DamperNum)%DamperName))
ErrorsFound=.true.
ELSE
Damper(DamperNum)%NoOAFlowInputFromUser = .FALSE.
END IF
END IF
!Setup the Average damper Position output variable
! CurrentModuleObject='AirTerminal:DualDuct:VAV'
CALL SetupOutputVariable('Zone Air Terminal Cold Supply Duct Damper Position []', Damper(DamperNum)%ColdAirDamperPosition, &
'System','Average',Damper(DamperNum)%DamperName)
CALL SetupOutputVariable('Zone Air Terminal Hot Supply Duct Damper Position []', Damper(DamperNum)%HotAirDamperPosition, &
'System','Average',Damper(DamperNum)%DamperName)
CALL SetupOutputVariable('Zone Air Terminal Outdoor Air Volume Flow Rate [m3/s]', Damper(DamperNum)%OutdoorAirFlowRate, &
'System','Average',Damper(DamperNum)%DamperName)
END DO ! end Number of Damper Loop
END IF
IF (NumDualDuctVarVolOA > 0) THEN
DO DamperIndex = 1, NumDualDuctVarVolOA
CurrentModuleObject=cCMO_DDVarVolOA
CALL GetObjectItem(CurrentModuleObject,DamperIndex,AlphArray,NumAlphas,NumArray,NumNums,IOSTAT, &
NumBlank=lNumericBlanks,AlphaBlank=lAlphaBlanks, &
AlphaFieldNames=cAlphaFields,NumericFieldNames=cNumericFields)
DamperNum = DamperIndex + NumDualDuctConstVolDampers + NumDualDuctVarVolDampers
IsNotOK=.false.
IsBlank=.false.
CALL VerifyName(AlphArray(1),Damper%DamperName,DamperNum-1,IsNotOK,IsBlank,TRIM(CurrentModuleObject)//' Name')
IF (IsNotOK) THEN
ErrorsFound=.true.
IF (IsBlank) AlphArray(1)='xxxxx'
ENDIF
Damper(DamperNum)%DamperName = AlphArray(1)
Damper(DamperNum)%DamperType = DualDuct_OutdoorAir
Damper(DamperNum)%Schedule = AlphArray(2)
IF (lAlphaBlanks(2)) THEN
Damper(DamperNum)%SchedPtr = ScheduleAlwaysOn
ELSE
Damper(DamperNum)%SchedPtr = GetScheduleIndex(AlphArray(2))
IF (Damper(DamperNum)%SchedPtr == 0) THEN
CALL ShowSevereError(TRIM(CurrentModuleObject)//', "'//TRIM(Damper(DamperNum)%DamperName)//&
'" '//TRIM(cAlphaFields(2))//' = '//TRIM(AlphArray(2))//' not found.')
ErrorsFound=.true.
ENDIF
ENDIF
Damper(DamperNum)%OutletNodeNum = &
GetOnlySingleNode(AlphArray(3),ErrorsFound,TRIM(CurrentModuleObject),AlphArray(1), &
NodeType_Air,NodeConnectionType_Outlet,1,ObjectIsNotParent,cAlphaFields(3))
Damper(DamperNum)%OAInletNodeNum = &
GetOnlySingleNode(AlphArray(4),ErrorsFound,TRIM(CurrentModuleObject),AlphArray(1), &
NodeType_Air,NodeConnectionType_Inlet,1,ObjectIsNotParent,cAlphaFields(4))
IF (.NOT. lAlphaBlanks(5)) THEN
Damper(DamperNum)%RecircAirInletNodeNum = &
GetOnlySingleNode(AlphArray(5),ErrorsFound,TRIM(CurrentModuleObject),AlphArray(1), &
NodeType_Air,NodeConnectionType_Inlet,1,ObjectIsNotParent,cAlphaFields(5))
ELSE
! for this model, we intentionally allow not using the recirc side
Damper(DamperNum)%RecircIsUsed = .FALSE.
ENDIF
Damper(DamperNum)%MaxAirVolFlowRate = NumArray(1)
Damper(DamperNum)%MaxAirMassFlowRate = Damper(DamperNum)%MaxAirVolFlowRate * StdRhoAir
! Register component set data - one for OA and one for RA
CALL TestCompSet(TRIM(CurrentModuleObject)//':OutdoorAir',Damper(DamperNum)%DamperName, &
AlphArray(4),AlphArray(3),'Air Nodes')
IF (Damper(DamperNum)%RecircIsUsed) THEN
CALL TestCompSet(TRIM(CurrentModuleObject)//':RecirculatedAir',Damper(DamperNum)%DamperName, &
AlphArray(5),AlphArray(3),'Air Nodes')
ENDIF
SELECT CASE (TRIM(AlphArray(7)) )
CASE ('CURRENTOCCUPANCY')
Damper(DamperNum)%OAPerPersonMode = PerPersonDCVByCurrentLevel
CASE ('DESIGNOCCUPANCY')
Damper(DamperNum)%OAPerPersonMode = PerPersonByDesignLevel
END SELECT
! checks on this are done later
! Fill the Zone Equipment data with the inlet node numbers of this unit.
DO CtrlZone = 1,NumOfZones
IF (.not. ZoneEquipConfig(CtrlZone)%IsControlled) CYCLE
DO SupAirIn = 1,ZoneEquipConfig(CtrlZone)%NumInletNodes
IF (Damper(DamperNum)%OutletNodeNum .EQ. ZoneEquipConfig(CtrlZone)%InletNode(SupAirIn)) THEN
IF (Damper(DamperNum)%RecircIsUsed) THEN
ZoneEquipConfig(CtrlZone)%AirDistUnitCool(SupAirIn)%InNode = Damper(DamperNum)%RecircAirInletNodeNum
ELSE
ZoneEquipConfig(CtrlZone)%AirDistUnitCool(SupAirIn)%InNode = Damper(DamperNum)%OAInletNodeNum
ENDIF
ZoneEquipConfig(CtrlZone)%AirDistUnitHeat(SupAirIn)%InNode = Damper(DamperNum)%OAInletNodeNum
ZoneEquipConfig(CtrlZone)%AirDistUnitCool(SupAirIn)%OutNode = Damper(DamperNum)%OutletNodeNum
ZoneEquipConfig(CtrlZone)%AirDistUnitHeat(SupAirIn)%OutNode = Damper(DamperNum)%OutletNodeNum
Damper(DamperNum)%CtrlZoneNum = CtrlZone
Damper(DamperNum)%ActualZoneNum = ZoneEquipConfig(CtrlZone)%ActualZoneNum
END IF
END DO
END DO
Damper(DamperNum)%OARequirementsPtr = FindItemInList(AlphArray(6),OARequirements%Name,NumOARequirements)
IF(Damper(DamperNum)%OARequirementsPtr .EQ. 0)THEN
CALL ShowSevereError(TRIM(cAlphaFields(6))//' = '//TRIM(AlphArray(6))//' not found.')
CALL ShowContinueError('Occurs in '//cCMO_DDVarVolOA//' = '//TRIM(Damper(DamperNum)%DamperName))
ErrorsFound=.true.
ELSE
Damper(DamperNum)%NoOAFlowInputFromUser = .FALSE.
! now fill design OA rate
CALL CalcOAOnlyMassFlow (DamperNum, DummyOAFlow , MaxOAVolFlow = Damper(DamperNum)%DesignOAFlowRate)
IF (Damper(DamperNum)%MaxAirVolFlowRate /= Autosize) THEN
CALL ReportSizingOutput(CurrentModuleObject, Damper(DamperNum)%DamperName, &
'Maximum Outdoor Air Flow Rate [m3/s]', Damper(DamperNum)%DesignOAFlowRate)
IF (Damper(DamperNum)%RecircIsUsed) THEN
Damper(DamperNum)%DesignRecircFlowRate = Damper(DamperNum)%MaxAirVolFlowRate - Damper(DamperNum)%DesignOAFlowRate
Damper(DamperNum)%DesignRecircFlowRate = MAX(0.d0, Damper(DamperNum)%DesignRecircFlowRate)
CALL ReportSizingOutput(CurrentModuleObject, Damper(DamperNum)%DamperName, &
'Maximum Recirculated Air Flow Rate [m3/s]', Damper(DamperNum)%DesignRecircFlowRate)
ELSE
IF (Damper(DamperNum)%MaxAirVolFlowRate < Damper(DamperNum)%DesignOAFlowRate) THEN
CALL ShowSevereError('The value '//TRIM(RoundSigDigits(Damper(DamperNum)%MaxAirVolFlowRate, 5)) &
//' in '// TRIM(cNumericFields(1)) // 'is lower than the outdoor air requirement.')
CALL ShowContinueError('Occurs in '//cCMO_DDVarVolOA//' = '//TRIM(Damper(DamperNum)%DamperName))
CALL ShowContinueError('The design outdoor air requirement is '// &
TRIM(RoundSigDigits(Damper(DamperNum)%DesignOAFlowRate, 5)) )
ErrorsFound = .TRUE.
ENDIF
ENDIF
ENDIF
END IF
IF (Damper(DamperNum)%OAPerPersonMode == PerPersonModeNotSet) THEN
DummyOAFlow = OARequirements(Damper(DamperNum)%OARequirementsPtr)%OAFlowPerPerson
IF ((DummyOAFlow == 0.d0) .AND. (lAlphaBlanks(7))) THEN ! no worries
! do nothing, okay since no per person requirement involved
ELSEIF ((DummyOAFlow > 0.d0) .AND. (lAlphaBlanks(7))) THEN ! missing input
CALL ShowSevereError(TRIM(cAlphaFields(7))//' was blank.')
CALL ShowContinueError('Occurs in '//cCMO_DDVarVolOA//' = '//TRIM(Damper(DamperNum)%DamperName))
CALL ShowContinueError('Valid choices are "CurrentOccupancy" or "DesignOccupancy"')
ErrorsFound=.true.
ELSEIF ((DummyOAFlow > 0.d0) .AND. .NOT. (lAlphaBlanks(7))) THEN ! incorrect input
CALL ShowSevereError(TRIM(cAlphaFields(7))//' = '//TRIM(AlphArray(7))//' not a valid key choice.')
CALL ShowContinueError('Occurs in '//cCMO_DDVarVolOA//' = '//TRIM(Damper(DamperNum)%DamperName))
CALL ShowContinueError('Valid choices are "CurrentOccupancy" or "DesignOccupancy"')
ErrorsFound=.true.
ENDIF
ENDIF
!Setup the Average damper Position output variable
CALL SetupOutputVariable('Zone Air Terminal Outdoor Air Duct Damper Position []', Damper(DamperNum)%OADamperPosition , &
'System','Average',Damper(DamperNum)%DamperName)
CALL SetupOutputVariable('Zone Air Terminal Recirculated Air Duct Damper Position []', &
Damper(DamperNum)%RecircAirDamperPosition , &
'System','Average',Damper(DamperNum)%DamperName)
CALL SetupOutputVariable('Zone Air Terminal Outdoor Air Fraction []', Damper(DamperNum)%OAFraction, &
'System','Average',Damper(DamperNum)%DamperName)
END DO ! end Number of Damper Loop
END IF
DO DamperIndex = 1, NumDampers
DO ADUNum = 1,NumAirDistUnits
IF (Damper(DamperIndex)%OutletNodeNum == AirDistUnit(ADUNum)%OutletNodeNum) THEN
! AirDistUnit(ADUNum)%InletNodeNum = Damper(DamperIndex)%InletNodeNum
Damper(DamperIndex)%ADUNum = ADUNum
END IF
END DO
! one assumes if there isn't one assigned, it's an error?
IF (Damper(DamperIndex)%ADUNum == 0) THEN
! convenient String
IF (Damper(DamperIndex)%DamperType == DualDuct_ConstantVolume) THEN
CurrentModuleObject='ConstantVolume'
ELSEIF (Damper(DamperIndex)%DamperType == DualDuct_VariableVolume) THEN
CurrentModuleObject='VAV'
ELSEIF (Damper(DamperIndex)%DamperType == DualDuct_OutdoorAir) THEN
CurrentModuleObject='VAV:OutdoorAir'
ELSE
CurrentModuleObject='*invalid*'
ENDIF
CALL ShowSevereError(RoutineName//'No matching List:Zone:AirTerminal for AirTerminal:DualDuct = ['// &
TRIM(CurrentModuleObject)//','//TRIM(Damper(DamperIndex)%DamperName)//'].')
CALL ShowContinueError('...should have outlet node='//TRIM(NodeID(Damper(DamperIndex)%OutletNodeNum)))
ErrorsFound=.true.
ENDIF
END DO
IF (ErrorsFound) THEN
CALL ShowFatalError(RoutineName//'Errors found in input. Preceding condition(s) cause termination.')
ENDIF
RETURN
END SUBROUTINE GetDualDuctInput