subroutine control_main(time,xin,out)

!based on
! Object: HyGSHP Controller
! Simulation Studio Model: Type198
! 
! Author: Scott Hackel
! Editor: 
! Date:	 October 04, 2006 last modified: October 04, 2006

!modified as a GHX only controller with pre-cooling
!the GHX must be on if the CT or HP are on; this controller is only for when the CT is used in pre-cooling
!This controller does not operate in heating mode, only cooling

IMPLICIT NONE			!REQUIRES THE USER TO DEFINE ALL VARIABLES BEFORE USING THEM

INTEGER, PARAMETER :: iknd=SELECTED_INT_KIND(8)  ! nobody does this
INTEGER, PARAMETER :: DP=SELECTED_REAL_KIND(14)  ! this is double precision
INTEGER, PARAMETER :: SP=SELECTED_REAL_KIND(6)  ! this is single precision
    
real(DP),intent(in) :: XIN(32)	!THE ARRAY FROM WHICH THE INPUTS TO THIS TYPE WILL BE RETRIEVED
real(DP),intent(out) ::  OUT(8)	!THE ARRAY WHICH WILL BE USED TO STORE THE OUTPUTS FROM THIS TYPE
real(DP),intent(in) ::  TIME	!THE CURRENT SIMULATION TIME - YOU MAY USE THIS VARIABLE BUT DO NOT SET IT!
!real,intent(in) ::  TIME	!THE CURRENT SIMULATION TIME - YOU MAY USE THIS VARIABLE BUT DO NOT SET IT!

real(DP) :: STORE(3) !THE STORAGE ARRAY FOR HOLDING VARIABLES FROM TIMESTEP TO TIMESTEP
real(DP)    OLD_GCHX, OLD_SECONDARY, WAS_HISPEED, DRIVER,lo_spd_tset, & 
            HAVE_BOILER, Y_DRY, Y_FAN_DRY, Y_CLOSED, Y_FAN_CLOSED, Y_OPEN, & 
            Y_FAN_OPEN, Y_GCHX, Y_HISPEED, LOAD_TOT,tod,temp ,Qcool,CTsize, &
            Qheat,PCon,PCon2,Lo_SPD_PC, Qratio,m,b,t_Ct_out
real(DP), save :: PC
!    PARAMETERS
integer STRATEGY,nspeeds
real(DP) DB
real(DP) LO_SPD,spd1,spd2

!    INPUTS
real(DP) T_amb
real(DP) T_wb
real(DP) Load_per
real(DP) Load_cor
real(DP) Flow
real(DP) GCHX_IN
real(DP) CT1
real(DP) CT2
real(DP) GHX1
real(DP) T_Freeze
real(DP) TH1
real(DP) T_ct_in
real(DP) TPC
real(DP) DTPC
real(DP) GHX_out
save

!May need to remove this at some point
if(tod == 7)then
    PC = 0.
endif

DB = XIN(1)
CTsize = XIN(2)
Lo_SPD_PC = XIN(3)
T_amb=XIN(4)
T_wb=XIN(5)
Load_per=XIN(6)
Load_cor=XIN(7)
Flow=XIN(8)
GCHX_IN=XIN(9)
CT1=XIN(10)
CT2=XIN(11)
GHX1=XIN(12)
T_Freeze=XIN(13)
TH1=XIN(14)
t_ct_in=XIN(15)
Strategy = Xin(16)
tod = xin(17)
qcool = xin(18)
qheat = xin(19)
store(1) = xin(20)
store(2) = xin(21)
store(3) = xin(22)
TPC = xin(23)
DTPC = xin(24)
GHX_out = xin(25)
spd1 = xin(26)
spd2 = xin(27)
nspeeds = xin(28)
Qratio = xin(29)
m = xin(30)
b = xin(31)
t_Ct_out = xin(32)

!    GET THE STATE OF THE VARIABLES AT THE PREVIOUS TIMESTEP
OLD_SECONDARY = store(1)
WAS_HISPEED = store(2)
OLD_GCHX = store(3)
PCon = 0.

Y_CLOSED=0
Y_FAN_CLOSED=0
Y_HISPEED=0 
Y_GCHX = 0

!LOAD_TOT=(Load_per+Load_cor)
load_tot = qcool - qheat    !if load_tot < 0, then heating mode

!    SET THE DRIVING FORCE FOR HEAT REJECTION
DRIVER=T_WB
if( ((strategy == 7).or.(strategy == 12).or.(strategy == 13)).and.(PC == 1))then  
    if((tod < 7.).or.(tod >= 21))then   
        PCon2 = 1
    else
        PCon2 = 0
    endif
elseif((strategy == 8).and.(PC == 1))then
    if((tod < 7.).and.(tod >= 4))then   
        PCon2 = 1
    else
        PCon2 = 0
    endif
else
    PCon2 = 0
endif
!    NO FLOW
    IF((FLOW <= 0.).and.(load_tot == 0).and.(PCon2 == 0)) THEN
        Y_CLOSED=0.
        Y_FAN_CLOSED=0.

        Y_GCHX=0.
        Y_HISPEED=0.
        PC = 0
    !    HEATING IS REQUIRED
    ELSE IF((LOAD_TOT < 0).and.(PCon2 == 0)) THEN

        Y_CLOSED=0.
        Y_FAN_CLOSED=0.
        
        Y_HISPEED=0.
        PC = 0.
        Y_GCHX=1.
    elseif(strategy == 0)then
    !GSHP
        Y_CLOSED=0.
        Y_FAN_CLOSED=0.
        
        Y_HISPEED=0.
        PC = 0.
   
        GHX1=GHX1-DB/2.*OLD_GCHX+DB/2.*(1.-OLD_GCHX)
        IF(GCHX_IN >= GHX1) THEN
            Y_GCHX=1.
        ELSE
            Y_GCHX=0.
        ENDIF
                
    elseif((strategy == 3).or.(strategy == 10))then
    !Hybrid strategy and set point only optimization
        Y_HISPEED=0.
        PC = 0.
        CT1=CT1-DB/2.*WAS_HISPEED+DB/2.*(1.-WAS_HISPEED)
        GHX1=GHX1-DB/2.*OLD_GCHX+DB/2.*(1.-OLD_GCHX)
        
        if(nspeeds == 1)then
            IF((T_ct_in >= CT1).AND.(T_AMB > T_FREEZE)) THEN
                Y_CLOSED=1.
                Y_FAN_CLOSED=spd1
                Y_HISPEED=1.
            endif
        elseif(nspeeds == 2)then
            IF((T_ct_in >= CT1).AND.(T_AMB > T_FREEZE)) THEN
                Y_CLOSED=1.
                Y_FAN_CLOSED=spd1
                Y_HISPEED=1.
            elseif((T_ct_in > (T_WB+CT2)).AND.(T_AMB > T_FREEZE)) THEN
                Y_CLOSED=1.
                Y_FAN_CLOSED=spd2
                Y_HISPEED=0
            endif
        elseif(nspeeds > 2)then
            if((T_ct_in > (T_WB+CT1)).AND.(T_AMB > T_FREEZE)) THEN
                Y_closed = 1
                if(T_ct_in > (T_WB+CT2))then
                    Y_fan_closed = 1.                    
                else
                    Y_fan_closed = min(1.,max(0.1,0.041*(T_ct_in - T_wb) - 0.05))
                endif
  100           Y_HISPEED = abs(Y_fan_closed == 1)  
            endif         
        endif

        IF(GCHX_IN >= GHX1) THEN
            Y_GCHX=1.
        ELSE
            Y_GCHX=0.
        ENDIf 
    elseif((strategy == 5))then
    !PC only phase 2   
        !Turn on the GHX
        PCon = 0
        GHX1=GHX1-DB/2.*OLD_GCHX+DB/2.*(1.-OLD_GCHX)
        IF(GCHX_IN >= GHX1) THEN
            Y_GCHX=1.
        ELSE
            Y_GCHX=0.
        ENDIF 
        if((tod >= 7).and.(tod < 21) )then
            Y_closed = 0.
            Y_fan_closed = 0.
            Y_HISPEED=0.
            if(PC == 1) goto 10
            !did the fluid temperature exceed the PC set point?
            if(t_ct_in >= TPC)then
                !is the difference between the fluid temperature out of the ground
                !and the wet bulb large enough to use PC?
                if(GHX_out - T_wb >= DTPC)then
                    PC = 1
                else
                    PC = 0
                endif
            else
                PC = 0
            endif
        else
            if((PC == 1))then  
            !.and.(qcool == 0)              
                Y_closed = 1.
                Y_fan_closed = 1.*Lo_SPD_PC
                Y_GCHX = 1.
                PCon = 1
            else
                Y_closed = 0
                Y_fan_closed = 0
                PCon = 0
            endif                  
        endif     
    
    elseif((strategy == 7).or.(strategy == 13))then
    !Standard differential and set point combo plus PC
        PCon = 0
        Y_HISPEED=0.
        CT1=CT1-DB/2.*WAS_HISPEED+DB/2.*(1.-WAS_HISPEED)
        GHX1=GHX1-DB/2.*OLD_GCHX+DB/2.*(1.-OLD_GCHX)

        if(nspeeds == 1)then
            IF((T_ct_in >= CT1).AND.(T_AMB > T_FREEZE)) THEN
                Y_CLOSED=1.
                Y_FAN_CLOSED=spd1
                Y_HISPEED=1.
            endif
        elseif(nspeeds == 2)then
            IF((T_ct_in >= CT1).AND.(T_AMB > T_FREEZE)) THEN
                Y_CLOSED=1.
                Y_FAN_CLOSED=spd1
                Y_HISPEED=1.
            elseif((T_ct_in > (T_WB+CT2)).AND.(T_AMB > T_FREEZE)) THEN
                Y_CLOSED=1.
                Y_FAN_CLOSED=spd2
                Y_HISPEED=0
            endif
        elseif(nspeeds > 2)then
            if((T_ct_in > (T_WB+CT1)).AND.(T_AMB > T_FREEZE)) THEN
                Y_closed = 1
                if(T_ct_in > (T_WB+CT2))then
                    Y_fan_closed = 1.                    
                else
                    Y_fan_closed = min(1.,max(0.1,0.041*(T_ct_in - T_wb) - 0.05))
                endif
                Y_HISPEED = abs(Y_fan_closed == 1)  
            endif
        endif

12      IF(GCHX_IN >= GHX1) THEN
            Y_GCHX=1.
        ELSE
            Y_GCHX=0.
        ENDIf 

        if((tod >= 7).and.(tod < 21) )then    
            if(PC == 1) goto 10        
            if(t_ct_in >= TPC)then
                !is the difference between the fluid temperature out of the ground
                !and the wet bulb large enough to use PC?
                if(GHX_out - T_wb >= DTPC)then
                    PC = 1
                else
                    PC = 0
                endif
            else
                PC = 0
            endif
        elseif((Y_closed == 0).and.(PC == 1))then
            Y_CLOSED=1. 
            Y_FAN_CLOSED=1.*Lo_SPD_PC
            Y_HISPEED=1.  
            Y_GCHX = 1.    
            PCon = 1
        endif
    elseif((strategy == 8))then
        !Hybrid control with set point only optimization and PC after 4 am
        PCon = 0
        Y_HISPEED=0.
        CT1=CT1-DB/2.*WAS_HISPEED+DB/2.*(1.-WAS_HISPEED)
        GHX1=GHX1-DB/2.*OLD_GCHX+DB/2.*(1.-OLD_GCHX)

        if(nspeeds == 1)then
            IF((T_ct_in >= CT1).AND.(T_AMB > T_FREEZE)) THEN
                Y_CLOSED=1.
                Y_FAN_CLOSED=spd1
                Y_HISPEED=1.
            endif
        elseif(nspeeds == 2)then
            IF((T_ct_in >= CT1).AND.(T_AMB > T_FREEZE)) THEN
                Y_CLOSED=1.
                Y_FAN_CLOSED=spd1
                Y_HISPEED=1.
            elseif((T_ct_in > (T_WB+CT2)).AND.(T_AMB > T_FREEZE)) THEN
                Y_CLOSED=1.
                Y_FAN_CLOSED=spd2
                Y_HISPEED=0
            endif
        elseif(nspeeds > 2)then
            if((T_ct_in > (T_WB+CT1)).AND.(T_AMB > T_FREEZE)) THEN
                Y_closed = 1
                !Y_fan_closed = min(max(0.1,0.838*Qratio**(-0.552)),1.)
                if((T_ct_in - T_ct_out)/(T_ct_in - T_wb) >= 0.5)then
                    Y_fan_closed = 1.                    
                elseif((T_ct_in > (T_WB+CT2)).AND.(T_AMB > T_FREEZE)) THEN
                    Y_fan_closed = min(1.,max(0.1,-1.44*(T_ct_in - T_ct_out)/(T_ct_in - T_wb) + 1.01))
                else
                    Y_fan_closed = min(1.,max(0.1,0.736*(T_ct_in - T_ct_out)/(T_ct_in - T_wb) + 0.0399))
                endif
                Y_HISPEED = abs(Y_fan_closed == 1)  
            endif
        endif

13      IF(GCHX_IN >= GHX1) THEN
            Y_GCHX=1.
        ELSE
            Y_GCHX=0.
        ENDIf 
        
        if((tod >= 7).and.(tod < 21) )then     
            if(PC == 1) goto 10       
            if(t_ct_in >= TPC)then
                !is the difference between the fluid temperature out of the ground
                !and the wet bulb large enough to use PC?
                if(GHX_out - T_wb >= DTPC)then
                    PC = 1
                else
                    PC = 0
                endif
            else
                PC = 0
            endif
        elseif((Y_closed == 0).and.(PC == 1).and.(tod >= 4.).and.(tod < 7) )then
            Y_CLOSED=1. 
            Y_FAN_CLOSED=1.*Lo_SPD_PC
            Y_HISPEED=1.  
            Y_GCHX = 1.   
            PCon = 1 
        endif       
    endif
      
10 if( ( (qcool > 0).or.(qheat > 0) ).and.(Y_GCHX + Y_closed == 0.) )then
    Y_GCHX = 1
 endif  

Y_HISPEED = abs(Y_fan_closed == 1)

!		 Y_CLOSED
			OUT(1)=Y_CLOSED
!		 Y_FAN_CLOSED
			OUT(2)=Y_FAN_CLOSED
!		 Y_GCHX
			OUT(3)=Y_GCHX
!		 Y_HISPEED
			OUT(4)=Y_HISPEED			
!		 TH1
			OUT(5)=TH1
!		 CT1
			OUT(6)=CT1
!		 GHX1
			OUT(7)=GHX1
!       Is cooling tower on in pre-cooling?			
			out(8) = PCon

!store(1) = y_closed
!store(2) = Y_HISPEED
!store(3) = y_gchx

return
end subroutine control_main