      SUBROUTINE TYPE194(TIME,XIN,OUT,T,DTDT,PAR,INFO,ICNTRL,*)

C************************************************************************************************
C 5-PARAMETER PHOTOVOLTAIC MODULE
C  This component implements the 5-Parameter PV model as presented by
C  DeSoto, Klein, and Beckman, to appear in Solar Energy Journal, 2005 
C 
C  The parameters at the reference condition must be provided as parameters.  An
C  EES distributable program is available for this purpose.
C  2005.11.00 - SAK - Written for TRNSYS 16.1
C  2005.12.01 - DAA - Added the electrical units for RCHECK
C  2005.12.15 - DAA - Corrected the calculation of EEFREF and IL, based on module-values,
C                      as well as the calculation of the maximum power for the array.
C  2005.12.16 - DAA/SAK Added outputs in order to be consistent with Type94.
C                      Corrected calculation of maximum power.  Added initialization of outputs.
C                      Changed input1, instead of Beam Normal, now it uses beam on horizontal.
C  2006.01.15 - DAA - Added the first parameter, MODE, for future upgrades
C  2006.02.23 - DAA - Created a second MODE that reads the parameters from a text file
C  2006.09.22 - DAA - Modified inputs to use similar ones than those used by Type94.  Deleted 
C                      the option MODE=2, as this is not necessary: it is handled by EES plugin.
C  2006.11.18 - DAA - Modified cell temperature equation, to take into account wind speed
C  2006.12.20 - DAA - Added MODE = 2, which models a PV module coupled with an inverter
C  2007.01.23 - DAA/WAB Fixed calculation of incidence angle modifiers for diffuse and ground 
C                     reflected radiation.
C
C************************************************************************************************
! Copyright © 2006 Solar Energy Laboratory, University of Wisconsin-Madison. All rights reserved.

!export this subroutine for its use in external DLLs.
!DEC$ATTRIBUTES DLLEXPORT :: TYPE194
      
C    USE STATEMENTS
      USE TrnsysConstants
      USE TrnsysFunctions

      IMPLICIT NONE !force explicit declaration of variables

C    TRNSYS DECLARATIONS
	DOUBLE PRECISION XIN,OUT,TIME,PAR,T,DTDT,STORED,TIME0,DELT
      INTEGER*4 INFO(15),NPMAX,NI,NO,ND,NSMAX,IUNIT,ITYPE,ICNTRL,NP
      CHARACTER*3 YCHECK,OCHECK1,OCHECK2

C    SET THE MAXIMUM NUMBER OF PARAMETERS(NP),INPUTS(NI),OUTPUTS(NO),DERIVATIVES(ND), AND STORAGE SPOTS(NSMAX)
C    THAT MAY BE SUPPLIED FOR THIS TYPE
      PARAMETER (NPMAX=29,NI=10,NO=13,ND=0)

C    REQUIRED TRNSYS DIMENSIONS
      DIMENSION XIN(NI),OUT(NO),PAR(NPMAX),YCHECK(NI),
     &	OCHECK1(12), OCHECK2(13)

C    COMMON BLOCK DEFININTIONS
      COMMON /ARRAY194/ A, IL, IO, RS, RSH
      COMMON /PARAM194/ SERCELL,TCR,IMR,VMR,ISCR,VOCR,MVOC,MISC,EG

C    LOCAL VARIABLE DECLARATIONS
	INTEGER NSER, NPRL
      DOUBLE PRECISION I,  !current [amps]
     & CURRENT5194, !function, determines current as function of voltage for the 5 parameter model
     & V,        !load voltage [volts]
     & IO_REF,   !reverse saturation current at reference conditons [A]
     & IO,       !reverse saturation current, dependent on temperature [A]
     & TA,       !ambient temperature [Kelvin (K), but input in °C]
     & A_REF,    !modified ideality factor at reference conditions
     & A,        !modified ideality factor
     & KB,       !Boltzmann constant [J/K]
     & IL_REF,   !photocurrent at reference conditions [A]
     & IL,       !photocurrent, dependent on insolation [A]
     & ISC,      !short circuit current [A]
     & TC,       !cell temperature [K]
     & VOC,      !open circuit voltage [V]
     & ISCR,     !short circuit current at reference [A]
     & VOCR,     !open circuit voltage at reference [V]
     & TCR,      !reference cell temperature [K]
     & SUNR,     !reference irradiance [W/m^2]
     & VMR,      !reference max. power point voltage [V]
     & IMR,      !reference current at max. power [A]
     & MISC,     !temperature coefficient: short circuit current [A/K]
     & EG_REF,   !bandgap energy at reference conditions[eV]
     & EG,       !bandgap energy at cell temperature[eV]     
     & SERCELL,  !Number of cells in series in module
     & TCNOCT,   !cell temperature at NOCT [K]
     & TANOCT,   !ambient temperature at NOCT [K]
     & SUNNOCT,  !irradiance at NOCT [K]
     & AREA,     !collector area [m^2]
     & TAU_AL,   !transmittance-absorptance product
     & EFFREF,   !reference max. power efficiency
     & IMP,      !current at max. power [A]
     & VMP,      !max. power point voltage [V]
     & P,        !power [W]
     & PMAX,     !maximum power point along IV curve [W]
     & MVOC,     !temperature coefficient: open circuit voltage [V/K]
     & THETAZ,
     & RS,       !series resistance (constant)
     & RSH_REF,  !shunt resistance at reference conditons
     & RSH,      !shunt resistance
     & SLOPE,    !slope of PV array [degrees]
     & OPENVOLTN194,
     & SUNDIR,
     & SUNGND,
     & SUNDIFF,
     & THETA,
     & TADIFF,
     & TAGND,
     & TADIR,
     & TAMAX,
     & SUNEFF,
     & SUNBN,
     & SUNTILT,
     & RHO,
     & AMASS,
     & MAM,
     & a0,    !coefficient for effect of air mass on incident radiation 
     & a1,
     & a2,
     & a3,
     & a4,
     & n2,
     & KL,
     & RefrAng1,
     & RefrAng2,
     & RefrAng3,
     & TransSurf1,
     & TransSurf2,
     & TransSurf3,
     & TransCoverABS1,
     & TransCoverABS2,
     & TransCoverABS3,
     & tau1,
     & tau2,
     & tau3,
     & THETA2,
     & THETA3,
     & THETA3X,
     & UTIL,		!COLLECTION EFFICIENCY
     & FF,				!FILL FACTOR
     & V_max_inv,			!Inverter maximum voltage
     & V_min_inv,			!Inverter minimum voltage
     & P_max_inv,			!Inverter maximum power
     & eta_inverter,
     & P_mp_array,		!Array power at maximum power point
     & V_mp_array,		!Array voltage at maximum power point
     & I_mp_array,		!Array current at maximum power point
     & V_oc_array,		!Array open circuit voltage
     & I_vmin,
     & P_vmin,
     & I_vmax,
     & P_vmax,
     & V_max_prime,
     & X(2),
     & Y(1),
     & V_WIND,			!Wind speed
     & TARE,				!Inverter tare
     & VMPLOW,			!Lower limit for maximum power point
     & VMPUP,				!Upper limit for maximum power point
     & VMPOLD, VMPNEW,	!Intermediate variables for maximum power point calculation
     & G, Iplus,				!Intermediate variable for maximum power point calculation
     & IVSLOPE, 
     & DPDV				!Slope of Power curve curve	


	
	INTEGER  NS,         !the number of double precision storage spots required for this instance of Type194 
     & MODE,		 !Component mode - for future upgrades
     & LU_INV,		 !Logical unit number of the file that contains the inverter parameters (for mode 2)
     & NX(2)

C    DATA STATEMENTS
	DATA KB/8.618E-5/ !Boltzmann constant [eV/K]  note units
	DATA a0/0.918093/,a1/0.086257/,a2/-0.024459/,a3/0.002816/,
     &     a4/-0.000126/ !Air mass modifier coefficients as indicated in DeSoto paper
      DATA YCHECK/'IR1','TE1','VO1','DG1','IR1','IR1','IR1','DG1','DG1',
     &	'VE1'/
      DATA OCHECK1/'VO1','CU1','PW2','PW2','DM1','VO1',
     &	        'CU1','VO1','CU1','DM1','TE1','DM1'/
      DATA OCHECK2/'VO1','CU1','PW2','PW2','DM1','VO1',
     &	        'CU1','VO1','CU1','DM1','TE1','DM1','DM2'/



C--------------------------------------------------------------------------------------------------
C    GET GLOBAL TRNSYS SIMULATION VARIABLES
      TIME0   = getSimulationStartTime()
      DELT    = getSimulationTimeStep()

C--------------------------------------------------------------------------------------------------
C    SET THE VERSION INFORMATION FOR TRNSYS
      IF(INFO(7).EQ.-2) THEN
	  INFO(12)=16
	  RETURN 1
	ENDIF

C--------------------------------------------------------------------------------------------------
C    PERFORM LAST CALL MANIPULATIONS 
      IF (INFO(8).EQ.-1) THEN
	  RETURN 1
	ENDIF

C--------------------------------------------------------------------------------------------------
C    PERFORM POST CONVERGENCE MANIPULATIONS 
      IF(INFO(13).GT.0) THEN
	  RETURN 1
	ENDIF

C--------------------------------------------------------------------------------------------------
C    PERFORM FIRST CALL MANIPULATIONS
      IF (INFO(7).EQ.-1) THEN
        !retrieve unit and type number for this component from the INFO array
        IUNIT = INFO(1)
	  ITYPE = INFO(2)
        !set some info array variables to tell the trnsys engine how this type is to work
        INFO(6) = NO   !reserve space in the OUT array using INFO(6)
        INFO(9) = 0    !this TYPE does not depend explicitly on TIME

	  INFO(10)=0 !

        MODE    = JFIX(PAR(1)+0.1)
 	  IF (MODE .EQ. 1) THEN		
	    NP = 24
	  ELSE IF (MODE .EQ. 2) THEN
		NP = 29
	  ENDIF

        !CALL THE TYPE CHECK SUBROUTINE TO COMPARE WHAT THIS TYPE REQUIRES TO WHAT IS SUPPLIED IN 
        !THE TRNSYS INPUT FILE
	  CALL TYPECK(1,INFO,NI,NP,ND)
        !CALL THE INPUT-OUTPUT CHECK SUBROUTINE TO SET THE CORRECT INPUT AND OUTPUT UNITS
	  IF (MODE .EQ. 1) THEN
		CALL RCHECK(INFO,YCHECK,OCHECK1)
	  ELSE IF (MODE .EQ. 2) THEN
		CALL RCHECK(INFO,YCHECK,OCHECK2)
	  ENDIF
	  !RETURN TO THE CALLING PROGRAM
        RETURN 1
      ENDIF

C--------------------------------------------------------------------------------------------------
C    PERFORM INITIAL TIMESTEP MANIPULATIONS
      IF (TIME.LT.(TIME0+DELT/2.)) THEN
        !set the UNIT and TYPE numbers for future calls
        IUNIT = INFO(1)
	  ITYPE = INFO(2)

        MODE    = JFIX(PAR(1)+0.1)
     	  
	  IF((MODE.LT.1) .OR. (MODE.GT.2))    CALL TYPECK(-4,INFO,0,1,0)


	    ISCR    = PAR(2) 
          VOCR    = PAR(3)
          TCR     = PAR(4)
          SUNR    = PAR(5)
          VMR     = PAR(6)
          IMR     = PAR(7)
          MISC    = PAR(8)
          MVOC    = PAR(9)
          SERCELL = PAR(10)
          NSER    = PAR(11)
          NPRL    = PAR(12)
          TCNOCT  = PAR(13)
          TANOCT  = PAR(14)
          SUNNOCT = PAR(15)
          AREA    = PAR(16)
          TAMAX   = DABS(PAR(17))
          EG_REF  = PAR(18)  !Band gap at reference temperature
	    A_REF   = PAR(19)  !the following are the 5 reference parameters for the DeSoto model
	    IL_REF  = PAR(20)
	    IO_REF  = PAR(21)
	    RS      = PAR(22)
	    RSH_REF = PAR(23)
	    KL      = PAR(24) !extinction coefficient

	  IF (MODE .EQ. 2) THEN
     	    P_max_inv = PAR(25)	!Inverter maximum power
	    V_max_inv = PAR(26)	!Inverter maximum voltage
          V_min_inv = PAR(27)	!Inverter minimum voltage
		tare	  = PAR(28)
	    LU_inv	  = jfix(PAR(29) +0.1)
	  ENDIF
	  	
	  IF(ISCR.LT.0.d0)    CALL TYPECK(-4,INFO,0,2,0)
        IF(VOCR.LT.0.d0)    CALL TYPECK(-4,INFO,0,3,0)
        IF(TCR.LT.0.d0)     CALL TYPECK(-4,INFO,0,4,0)
        IF(SUNR.LT.0.d0)    CALL TYPECK(-4,INFO,0,5,0)
        IF(VMR.LT.0.d0)     CALL TYPECK(-4,INFO,0,6,0)
        IF(IMR.LT.0.d0)     CALL TYPECK(-4,INFO,0,7,0)
        IF(SERCELL.LT.1.d0) CALL TYPECK(-4,INFO,0,10,0)
        IF(NSER.LT.1.d0)    CALL TYPECK(-4,INFO,0,11,0) 
        IF(NPRL.LT.1.d0)    CALL TYPECK(-4,INFO,0,12,0)
	  IF(TCNOCT.LT.0.d0)  CALL TYPECK(-4,INFO,0,13,0)
        IF(TANOCT.LT.0.d0)  CALL TYPECK(-4,INFO,0,14,0)
        IF(SUNNOCT.LT.0.d0) CALL TYPECK(-4,INFO,0,15,0)
        IF(AREA.LT.0.d0)    CALL TYPECK(-4,INFO,0,16,0)
	  IF(TAMAX.EQ.0.d0)   CALL TYPECK(-4,INFO,0,17,0)
        IF(EG_REF.LT.0.d0)  CALL TYPECK(-4,INFO,0,18,0)


C      INITIALIZE OUTPUTS  
        OUT(1)  = VOCR*NSER	!ARRAY VOLTAGE
        OUT(2)  = ISCR*NPRL	!ARRAY CURRENT
        OUT(3)  = 0.D0		!ARRAY POWER
        OUT(4)  = 0.D0		!ARRAY MAXIMUM POWERset to non-zero only if DOPMAX (Par 23) > 0
	  OUT(5)  = 0.D0		!RATIO P/PMAX
        OUT(6)  = VMR*NSER	!ARRAY VOLTAGE AT MAXIMUM POWER POINT
        OUT(7)  = IMR*NPRL	!ARRAY CURRENT AT MAXIMUM POWER POINT
        OUT(8)  = VOCR*NSER	!ARRAY OPEN CIRCUIT VOLTAGE
	  OUT(9)  = ISCR*NPRL	!ARRAY SHORT CIRCUIT CURRENT
	  OUT(10) = 0.D0		!ARRAY FILL FACTOR
	  OUT(11) = 0.D0		!ARRAY TEMPERATURE
	  OUT(12) = 0.D0		!ARRAY COLLECTION EFFICIENCY
	  IF (MODE .EQ. 2) THEN
		OUT(13) = 0.D0
      ENDIF
	  
      ENDIF

C--------------------------------------------------------------------
C    THIS IS AN ITERATIVE CALL TO THIS COMPONENT ***
C--------------------------------------------------------------------

C    RE-READ THE PARAMETERS IF ANOTHER UNIT OF THIS TYPE HAS BEEN CALLED SINCE THE LAST 
C    TIME THEY WERE READ IN
      IF(INFO(1).NE.IUNIT) THEN
        !reset the unit number
	  IUNIT = INFO(1)
	  ITYPE = INFO(2)
  	  !read the parameter values
        MODE    = PAR(1)
	  ISCR    = PAR(2)
        VOCR    = PAR(3)
        TCR     = PAR(4)
        SUNR    = PAR(5)
        VMR     = PAR(6)
        IMR     = PAR(7)
        MISC    = PAR(8)
        MVOC    = PAR(9)
        SERCELL = PAR(10)
        NSER    = PAR(11)
        NPRL    = PAR(12)
        TCNOCT  = PAR(13)
        TANOCT  = PAR(14)
        SUNNOCT = PAR(15)
        AREA    = PAR(16)
        TAMAX   = DABS(PAR(17))
        EG_REF  = PAR(18)
	  A_REF   = PAR(19)  !the following are the 5 reference parameters for the DeSoto model
	  IL_REF  = PAR(20)
	  IO_REF  = PAR(21)
	  RS      = PAR(22)
	  RSH_REF = PAR(23)
        KL      = PAR(24)  

	  IF (MODE .EQ. 2) THEN
     	    P_max_inv = PAR(25)	!Inverter maximum power
	    V_max_inv = PAR(26)	!Inverter maximum voltage
          V_min_inv = PAR(27)	!Inverter minimum voltage
		tare	  = PAR(28) !Night tare
		LU_inv	  = jfix(PAR(29) + 0.1)
        ENDIF
      ENDIF

C    RETRIEVE THE CURRENT VALUES OF THE INPUTS TO THIS MODEL FROM THE XIN ARRAY
      SUNTILT = XIN(1)/3.6d0          !total solar radiation on tilted surface; Input in kJ/m2-hr converted to W/m^2
      TA      = XIN(2)+273.15         !ambient temperature in K but input in °C {SAK 10/10/05} 
      V       = XIN(3)				!voltage
      SLOPE   = XIN(4)				!slope of array
	SUNDIR  = XIN(5)/3.6D0			!beam radiation on tilted surface Input in kJ/m2-hr converted to W/m^2
	SUNDIFF = XIN(6)/3.6D0			!sky diffuse radiation on tilted surface; Input in kJ/m2-hr converted to W/m^2
	SUNGND  = XIN(7)/3.6D0			!ground diffuse radiation on tilted surface; Input in kJ/m2-hr converted to W/m^2
	THETA	= XIN(8)				!incidence angle on tilted surface
	THETAZ  = XIN(9)				!zenith angle
	V_WIND  = XIN(10)				!Wind speed
	
	IF (THETAZ.GT. 86.0) THETAZ=86.0 !Zenith angle must be < 90°	  

C       INCIDENCE ANGLE MODIFIER CALCULATIONS
      IF (THETA.LE.0) THEN
        THETA=1
      ENDIF
      n2         = 1.526   !refractive index of glass

      RefrAng1   = asinD(sinD(THETA)/n2)
      TransSurf1 = 1-0.5*((sinD(RefrAng1-THETA))**2/(sinD(RefrAng1+
     &  THETA))**2+(tanD(RefrAng1-THETA))**2/(tanD(RefrAng1+THETA))**2)
      TransCoverAbs1 = Dexp(-KL/cosD(RefrAng1))
      tau1       = TransCoverAbs1*TransSurf1
        
C       Evaluating transmittance at angle Normal to surface (0), use 1 to avoid probs.
      THETA2     = 1
      RefrAng2   = asinD(sinD(THETA2)/n2)
      TransSurf2 = 1-0.5*((sinD(RefrAng2-1))**2/(sinD(RefrAng2+1))**2+
     & (tanD(RefrAng2-1))**2/(tanD(RefrAng2+1))**2)
      TransCoverAbs2 = Dexp(-KL/cosD(RefrAng2))
      tau2       = TransCoverAbs2*TransSurf2
      
C	   Evaluating transmittance at equivalent angle for diffuse 
!      THETA3     = 58
	THETA3 = 59.7 - 0.1388*SLOPE  + 0.001497*SLOPE**2
      RefrAng3   = AsinD(sinD(THETA3)/n2)
      TransSurf3 = 1-.5*((sinD(RefrAng3-THETA3))**2/(sinD(RefrAng3+
     & THETA3))**2 + (tanD(RefrAng3-THETA3))**2/(tanD(RefrAng3+
     & THETA3))**2)
      TransCoverAbs3 = Dexp(-KL/cosD(RefrAng3))
      tau3       = TransCoverAbs3*TransSurf3
      TADIR      = tau1/tau2
      TADIFF     = tau3/tau2
	THETA3X	   = THETA3
C	   Evaluating transmittance at equivalent angle for ground reflected radiation 
!      THETA3     = 58
	THETA3 = 90.0 - 0.5788*SLOPE  + 0.002693*SLOPE**2
      RefrAng3   = AsinD(sinD(THETA3)/n2)
      TransSurf3 = 1-.5*((sinD(RefrAng3-THETA3))**2/(sinD(RefrAng3+
     & THETA3))**2 + (tanD(RefrAng3-THETA3))**2/(tanD(RefrAng3+
     & THETA3))**2)
      TransCoverAbs3 = Dexp(-KL/cosD(RefrAng3))
      tau3       = TransCoverAbs3*TransSurf3
      tau3       = TransCoverAbs3*TransSurf3
      TAGND     = tau3/tau2

C         Calculation of Effective irradiance
      SUNDIFF=SUNDIFF*TADIFF
      SUNGND=SUNGND*TAGND
      SUNDIR=SUNDIR*TADIR
	SUNEFF = SUNDIFF+SUNGND+SUNDIR 
	TAU_AL     = TAMAX
	IF (SUNTILT.GT.0) TAU_AL = TAMAX*SUNEFF/SUNTILT  !DAA: = TAMAX is used for CEC study
      IF (SUNEFF.LT.0)  SUNEFF=0

C	    Calculation of Air Mass Modifier
      IF (THETAZ.LE.0) THETAZ=0
      AMASS      = 1/(cosD(THETAZ)+0.5057*(96.080-THETAZ)**(-1.634))
      MAM        = a0+a1*AMASS+a2*AMASS**2+a3*AMASS**3+a4*AMASS**4
      SUNEFF     = SUNEFF*MAM

C  Evaluation of cell temperature from NOCT and ambient conditions

      EFFREF     = IMR*VMR/(SUNR*AREA)
      IF (SUNEFF.LT.1) THEN
        TC       = TA
      ELSE
        TC = TA + (SUNTILT*(TCNOCT-TANOCT)/SUNNOCT*(1.-EFFREF/TAU_AL))*
     . 	  9.5/(5.7 + 3.8*V_WIND) 
      ENDIF

C       Evaluation of IL and IO at operating conditions, for one module
	IL   = (SUNEFF/SUNR)*(IL_REF+MISC*(TC-TCR))  

      IF (IL.LT.0.0) IL=0.0
	EG   = EG_REF*(1-0.0002677*(TC-TCR))
      IO   = IO_REF*((TC/TCR)**3)*DEXP((1/KB)*(EG_REF/TCR-EG/TC))
      A    = A_REF*TC/TCR
	RSH  = 1E6
      IF (SUNEFF.GT.0.d0) RSH=RSH_REF*(SUNR/SUNEFF) !Shunt resistance relation in DeSoto paper

C         Open circuit voltage, short circuit current for 1 module
      VOC = OPENVOLTN194(VOCR,SUNEFF)   
      ISC = IL/(1+RS/RSH)

      
C****   all calculations are being skipped during time periods
C****   with no insolation     
      IF(SUNEFF.EQ.0.d0)THEN
        V    = 0.d0
        I    = 0.d0
	  IMP  = 0.d0
	  VMP  = 0.d0
	  PMAX = 0.d0
	  UTIL = 0.d0
	  FF   = 0.d0
      ELSE
C****     check on operation mode
        IF(V.LT.0.)THEN
          V=0.d0
          I=0.d0
        ELSE
C****         normal operation
C****         check if voltage greater than open circuit voltage
          IF((V/NSer).GT.VOC)THEN
            V=VOC*NSer
            I=0.d0
          ELSE
            I=CURRENT5194(V,0.9*IL, NSER, NPRL)  !CURRENT FOR ENTIRE ARRAY
          ENDIF
        ENDIF

1000    P=I*V	!POWER FOR ENTIRE ARRAY

c     MAXIMUM POWER FOR THE ARRAY
	  PMAX=0
	  VMP=0
	  IMP=0
          VMP=(VMR+MVOC*(TC-TCR))/2
          DO WHILE (PMAX.LE.(IMP*VMP).AND. (VMP.LT.VOC))
	      PMAX=IMP*VMP
	     VMP=VMP+0.01
            IMP=CURRENT5194(VMP,0.9*IL, 1, 1)  !IMP PER MODULE 
	    END DO
	  
	  PMAX = IMP*VMP*NSER*NPRL  !PER ARRAY

        IF(PMAX.NE.0.)THEN
          UTIL=P/PMAX
        ELSE
          UTIL=0.d0
        ENDIF

C      Fill factor
        IF ((VOC.GT.0.d0).AND.(ISC.GT.0.d0)) THEN
          FF=VMP*IMP/VOC/ISC
        ELSE
          FF=0.d0
        ENDIF
      ENDIF

C--------------------------------------------------------------- 

C     INVERTER 
C	This section modifies the operating voltage of the modules
C     in order to couple them with the inverter
	
	P_mp_array = PMAX		!Array power at maximum power point
	V_mp_array = VMP*NSER	!Array voltage at maximum power point
	I_mp_array = IMP*NPRL	!Array current at maximum power point
	V_oc_array = VOC*NSER	!Array open circuit voltage

	IF (MODE .EQ. 2) THEN
	  eta_inverter = 1		!Initialization value

	  if (P_mp_array<P_max_inv) then
	    if (V_mp_array > V_max_inv) then
		  V=V_max_inv 
		  I =  CURRENT5194(V,0.9*IL,NSER,NPRL)
		  if ( (V.lt.V_min_inv) .or. (V.gt.V_max_inv) .or. 
     .		  (P.gt.P_max_inv) ) then
		    eta_inverter = 0.d0
		  else
		    !Interpolation routine for inverter efficiency
		    X(1) = V
		    X(2) = P_mp_array
		    NX(1) = 3
		    NX(2) = 7
		    call DynamicData(LU_inv,2,NX,1,X,Y,INFO,*101)
		    call LINKCK('Type198','DynamicData',3,198)
101		    if (ErrorFound()) return 1
		    eta_Inverter = Y(1)
            endif
		    P=V*I*eta_Inverter
	    else
	      if ((V_min_inv<V_mp_array) .and. (V_mp_array< V_max_inv)) then
			I=I_mp_array
			V=V_mp_array
		    if ( (V.lt.V_min_inv) .or. (V.gt.V_max_inv) .or. 
     .		  (P.gt.P_max_inv) ) then
		      eta_inverter = 0.d0
		    else
		      !Interpolation routine for inverter efficiency
			  X(1) = V
			  X(2) = P_mp_array
			  NX(1) = 3
			  NX(2) = 7
			  call DynamicData(LU_inv,2,NX,1,X,Y,INFO,*102)
			  call LINKCK('Type198','DynamicData',3,198)
102			  if (ErrorFound()) return 1
			  eta_Inverter = Y(1)
			endif
			P=I*V*eta_inverter
		  else ! "V < V_min"

			if(V_oc_array > V_min_inv) THEN
			  V=V_min_inv
			  I = CURRENT5194(V,0.9*IL,NSER,NPRL)
		      if ( (V.lt.V_min_inv) .or. (V.gt.V_max_inv) .or. 
     .		    (P.gt.P_max_inv) ) then
		        eta_inverter = 0.d0
		      else
		        !Interpolation routine for inverter efficiency
			    X(1) = V
			    X(2) = P_mp_array
			    NX(1) = 3
			    NX(2) = 7
			    call DynamicData(LU_inv,2,NX,1,X,Y,INFO,*103)
			    call LINKCK('Type198','DynamicData',3,198)
103			    if (ErrorFound()) return 1
			    eta_Inverter = Y(1)
	          endif
			  P=V*I*eta_inverter
			else
			  V=V_oc_array
			  I=0
			  P=0
			  eta_inverter=0
			endif
		  endif
		endif

	  else !"P_mp>P_max_inv"
	  P=0
	  eta_inverter=1000

	  if (V_oc_array<V_min_inv) then
		P=0
		I=0
		V=0
	  else !"V_oc>V_min"
		V = V_min_inv
	    I = CURRENT5194(V,0.9*IL,NSER,NPRL)
		I_vmin = I
		P_vmin=V_min_inv*I_vmin
		if (V_oc_array>V_max_inv) then
		  V = V_max_inv
		  I_vmax = I
		  P_vmax=V_max_inv*I_vmax
		else	
		  P_vmax=0	
		  V_max_prime=V_oc_array
		endif

		if (V_mp_array<V_min_inv) then
		  P=P_vmin
		else 
		  if (V_mp_array>V_max_inv) then
			if ((P_vmin>P_max_inv) .and. (P_vmax>P_max_inv)) then
			  P=0
			else
			  P=dmax1(P_vmin, dmin1(P_max_inv, P_vmax))
			endif
		  else !"V_min < V_mp < V_max"
			if ((P_vmin>P_max_inv) .and. (P_vmax>P_max_inv)) then
			  P=0
			else
			  P=P_max_inv
			endif
		  endif
		endIf
	  endIf
	  eta_inverter=P_max_inv/P_mp_array
	endif

	P = eta_inverter * P_mp_array

	ENDIF

C*****  Update power during the night - inverter on, so it consumes power
      IF(SUNEFF.EQ.0.d0)THEN
	  P = -tare
	  eta_inverter = 0
	ENDIF

C**** SET OUTPUTS  ************************************
      OUT(1)  = V			!ARRAY VOLTAGE
      OUT(2)  = I			!ARRAY CURRENT
      OUT(3)  = P			!ARRAY POWER
      OUT(4)  = PMAX		!ARRAY MAXIMUM POWERset to non-zero only if DOPMAX (Par 23) > 0
	OUT(5)  = UTIL		!RATIO P/PMAX
      OUT(6)  = VMP*NSER	!ARRAY VOLTAGE AT MAXIMUM POWER POINT
      OUT(7)  = IMP*NPRL	!ARRAY CURRENT AT MAXIMUM POWER POINT
      OUT(8)  = VOC*NSER	!ARRAY OPEN CIRCUIT VOLTAGE
	OUT(9)  = ISC*NPRL	!ARRAY SHORT CIRCUIT CURRENT
	OUT(10) = FF		!ARRAY FILL FACTOR
	OUT(11) = TC		!ARRAY TEMPERATURE
	IF (SunTilt.GT.0) THEN
	  OUT(12) = P/(Area*NSER*NPRL*SunTilt) !ARRAY COLLECTION EFFICIENCY
	ELSE 
	  OUT(12)= 0.D0
	ENDIF
	IF (MODE .EQ. 2) THEN
		OUT(13) = eta_inverter
	ENDIF
		
	
1010  RETURN 1
      END SUBROUTINE TYPE194

C****************************************************************
      FUNCTION CURRENT5194(V,IMR,NSER,NPRL)

C     Iterative solution for current as a function of voltage using
C     equations from the five-parameter model.  Newton's method is used
C     to converge on a value.  Max power at reference conditions is initial
C     guess.  

      IMPLICIT NONE

      COMMON /ARRAY194/ A, IL, IO, RS, RSH

      DOUBLE PRECISION IOLD,INEW,F,FPRIME, I, CURRENT5194,V_MODULE,V   
      DOUBLE PRECISION A, IL,IO,RS,RSH,IMR
	INTEGER NSER,NPRL

      IOLD = 0.0
	V_MODULE    = V/NSer	
C**** first guess is max.power point current
      INEW = IMR
      DO WHILE (DABS(INEW-IOLD).GT.1.E-4)
        IOLD   = INEW     
        F      = IL-IOLD-IO*(DEXP((V_MODULE+IOLD*RS)/A)-1.0)-
     &	       (V_MODULE+IOLD*RS)/RSH
        FPRIME = -1.-IO*(RS/A)*DEXP((V_MODULE+IOLD*RS)/A)-(RS/RSH)
        INEW   = MAX(0.d0,(IOLD-(F/FPRIME)))
      END DO
      I           = INEW	 !CURRENT FOR ONE MODULE
      CURRENT5194 = I*NPRL !CURRENT FOR ENTIRE ARRAY

      END FUNCTION CURRENT5194

C****************************************************************
      FUNCTION OPENVOLTN194(VOCR,SUN)

C     Function added by BF and modified by SAK
C     Iterative solution for open-circuit voltage.  Explicit algebraic solution
C     not possible in 5-parameter model

      IMPLICIT NONE

      COMMON /ARRAY194/ A, IL, IO, RS, RSH

      DOUBLE PRECISION VOCOLD,VOCNEW,OPENVOLTN194,I
      DOUBLE PRECISION A,IL,IO,RS,RSH,VOCR,SUN
      DOUBLE PRECISION VOCUP,VOCLOW

      IF (SUN.LT.1) THEN
        OPENVOLTN194=0
      ELSE
        VOCUP=VOCR*1.5
        VOCLOW=0
        VOCOLD=0
        VOCNEW=VOCR
        DO WHILE (DABS(VOCUP-VOCLOW).GT.1.E-3)             
          VOCOLD=VOCNEW
          I=IL-IO*(DEXP(VOCOLD/A)-1)-VOCOLD/RSH
          IF (I.LT.0) VOCUP=VOCOLD
          IF (I.GT.0) VOCLOW=VOCOLD
          VOCNEW=(VOCUP+VOCLOW)/2
        END DO      
        OPENVOLTN194=VOCNEW
      ENDIF

      END FUNCTION OPENVOLTN194 