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) | :: | LoopNum | |||
integer, | intent(in) | :: | TankInletLoopSide | |||
real(kind=r64), | intent(out) | :: | TankOutletTemp |
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 UpdateHalfLoopInletTemp(LoopNum, TankInletLoopSide, TankOutletTemp)
! SUBROUTINE INFORMATION:
! AUTHOR Rick Strand
! DATE WRITTEN September 2001
! MODIFIED Simon Rees, July 2007
! Brent Griffith, Feb. 2010, add LoopNum arg
! RE-ENGINEERED Brent Griffith, Sept 2010, generalize for both loop sides
! add pump heat from other loop
! B.Griffith and L.Gu, Oct 2011, solve via analytical soln, use average over timestep
! PURPOSE OF THIS SUBROUTINE:
! This subroutine calculates the new loop side inlet temperature
! based on the previous temperature of the mixed tank, mass flow rate and the new
! outlet temperature on the supply side. The temperature does not
! pass directly across because the loop has some capacitance. It is
! called separately but used for both supply-to-demand, and demand-to-supply
! METHODOLOGY EMPLOYED:
! This uses a analytical solution for changes in the
! fluid loop temperature. The user defines some volume of fluid
! for the loop which gets converted to a fixed amount of mass.
! The loop side inlet node is modeled as the outlet of a fully mixed
! tank. Note that this routine is called repeatedly to re calculate
! loop capacitance based on current plant conditions
! REFERENCES:
! na
! USE STATEMENTS:
USE DataHVACGlobals, ONLY : TimeStepSys, SysTimeElapsed
USE DataLoopNode, ONLY : Node
USE DataPlant, ONLY : PlantLoop
USE DataGlobals, ONLY : SecInHour, TimeStepZone, TimeStep, HourOfDay
USE FluidProperties, ONLY : GetSpecificHeatGlycol
IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
! SUBROUTINE ARGUMENTS:
INTEGER, INTENT(IN) :: LoopNum
INTEGER, INTENT(IN) :: TankInletLoopSide
REAL(r64),INTENT(OUT) :: TankOutletTemp
! SUBROUTINE PARAMETER DEFINITIONS:
REAL(r64),PARAMETER :: FracTotLoopMass = 0.5d0 !Fraction of total loop mass assigned to the half loop
! INTERFACE BLOCK SPECIFICATIONS:
! na
! DERIVED TYPE DEFINITIONS:
! na
! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
INTEGER :: TankOutletLoopSide ! inlet loopsidenumber
INTEGER :: TankInletNode ! inlet loop side outlet node
INTEGER :: TankOutletNode ! inlet loop side outlet node
REAL(r64) :: TankInletTemp ! temporary variable
REAL(r64) :: LastTankOutletTemp ! temporary variable
REAL(r64) :: Cp ! specific heat
REAL(r64) :: TimeElapsed ! temporary value based on current clock time during simulation, fractional hours
REAL(r64) :: TimeStepSeconds
REAL(r64) :: MassFlowRate
REAL(r64) :: PumpHeat
REAL(r64) :: ThisTankMass
REAL(r64) :: TankFinalTemp
REAL(r64) :: TankAverageTemp
! FLOW:
!find tank inlet and outlet nodes
TankOutletLoopSide = 3 - TankInletLoopSide
TankInletNode = PlantLoop(LoopNum)%LoopSide(TankInletLoopSide)%NodeNumOut
TankOutletNode = PlantLoop(LoopNum)%LoopSide(TankOutletLoopSide)%NodeNumIn
TankInletTemp = Node(TankInletNode)%Temp
! This needs to be based on time to deal with system downstepping and repeated timesteps
TimeElapsed = (HourOfDay-1) + TimeStep * TimeStepZone + SysTimeElapsed
IF (PlantLoop(LoopNum)%LoopSide(TankOutletLoopSide)%TimeElapsed /= TimeElapsed) THEN
PlantLoop(LoopNum)%LoopSide(TankOutletLoopSide)%LastTempInterfaceTankOutlet &
= PlantLoop(LoopNum)%LoopSide(TankOutletLoopSide)%TempInterfaceTankOutlet
PlantLoop(LoopNum)%LoopSide(TankOutletLoopSide)%TimeElapsed = TimeElapsed
ENDIF
LastTankOutletTemp = PlantLoop(LoopNum)%LoopSide(TankOutletLoopSide)%LastTempInterfaceTankOutlet
!calculate the specific heat for the capacitance calculation
Cp = GetSpecificHeatGlycol(PlantLoop(loopNum)%FluidName, &
LastTankOutletTemp, &
PlantLoop(loopNum)%FluidIndex,'UpdateHalfLoopInletTemp')
!set the fraction of loop mass assigned to each half loop outlet capacitance ('tank') calculation
!calculate new loop inlet temperature. The calculation is a simple 'tank' (thermal capacitance) calculation that includes:
!--half of loop mass. The other half is accounted for at the other half loop interface
!--pump heat. Pump heat for a single loop setpoint with pumps only on the supply side is added at the supply side inlet.
! Pump heat for a dual setpoint loop is added to each loop side inlet
! The previous tank temperature value is used to prevent accumulation of pump heat during iterations while recalculating
! tank conditions each call.
! Analytical solution for ODE, formulated for both final tank temp and average tank temp.
TimeStepSeconds = TimeStepSys * SecInHour
MassFlowRate = Node(TankInletNode)%MassFlowRate
PumpHeat = PlantLoop(LoopNum)%LoopSide(TankOutletLoopSide)%TotalPumpHeat
ThisTankMass = FracTotLoopMass * PlantLoop(LoopNum)%Mass
IF (ThisTankMass <= 0.d0) THEN ! no mass, no plant loop volume
IF (MassFlowRate > 0.d0) THEN
TankFinalTemp = TankInletTemp + PumpHeat/(MassFlowRate * Cp)
TankAverageTemp = (TankFinalTemp + LastTankOutletTemp)/2.0d0
ELSE
TankFinalTemp = LastTankOutletTemp
TankAverageTemp = LastTankOutletTemp
END IF
ELSE ! tank has mass
IF (MassFlowRate > 0.d0 ) THEN
TankFinalTemp = (LastTankOutletTemp - (MassFlowRate * Cp * TankInletTemp + PumpHeat)/(MassFlowRate * Cp)) * &
exp(-(MassFlowRate * Cp) / (ThisTankMass*Cp)*TimeStepSeconds) + &
(MassFlowRate * Cp * TankInletTemp + PumpHeat)/ (MassFlowRate * Cp)
TankAverageTemp = ((ThisTankMass*Cp)/(MassFlowRate * Cp)*(LastTankOutletTemp - &
(MassFlowRate * Cp * TankInletTemp + PumpHeat)/(MassFlowRate * Cp)) * &
(1.0d0-exp(-(MassFlowRate * Cp) / (ThisTankMass*Cp)*TimeStepSeconds))/TimeStepSeconds + &
(MassFlowRate * Cp * TankInletTemp + PumpHeat)/(MassFlowRate * Cp))
ELSE
TankFinalTemp = PumpHeat/(ThisTankMass*Cp)*TimeStepSeconds + LastTankOutletTemp
TankAverageTemp = (TankFinalTemp + LastTankOutletTemp)/2.0d0
END IF
ENDIF
!update last tank outlet temperature
PlantLoop(LoopNum)%LoopSide(TankOutletLoopSide)%TempInterfaceTankOutlet = TankFinalTemp
! update report variable
PlantLoop(LoopNum)%LoopSide(TankOutletLoopSide)%LoopSideInlet_TankTemp = TankAverageTemp
TankOutletTemp = TankAverageTemp
RETURN
END SUBROUTINE UpdateHalfLoopInletTemp