program hicon

C	PROGRAM TO MODEL DYNAMICS OF FLOW OF HAWAIIAN MAGMA/GAS
C	MIXTURES IN VERTICAL ERUPTIVE CONDUITS.  THE MODEL ASSUMES
C	STEADY STATE, HOMOGENEOUS FLOW OF LIQUID MAGMA AND IDEAL
C	GAS.  THE COMPLETE DOCUMENTATION TO THIS CODE IS EXPLAINED
C	IN THE U.S.G.S. OPEN-FILE REPORT "A NUMERICAL PROGRAM FOR
C	STEADY-STATE FLOW OF HAWAIIAN MAGMA-GAS MIXTURES THROUGH
C	VERTICAL ERUPTIVE CONDUITS", OPEN FILE REPORT NUMBER 95-756
C	
C	WRITTEN BY LARRY G. MASTIN
C     U.S. GEOLOGICAL SURVEY
C     CASCADES VOLCANO OBSERVATORY
C     1300 SE Cardinal Court,
C	Bldg.10, Suite 100 		
C	VANCOUVER, WA 98683
C	TEL. (360) 696-7518
C	E-MAIL lgmastin@usgs.gov
C

C	DECLARE VARIABLES

	implicit double precision (a-h,o-z)

	real*8 area(2000),output(37,2000),pres(2000),re(2000),rho(2000),
     *		time(2000),vel(2000),vesic(2000),visc(2000),z(2000)
	real*8 mach(2000)
        real*8 blkmag,cm,co2,cp,cph2o,cpco2,cps,cv,cvh2o,
     *		cvco2,cvs,dadz,diam,dpdz,dz,dznext,
     *		dzout,eps,eta,exco2,exh2o,exmol,exsulfur,f,fo,g,gamma,
     *		h2o,m,mco2,mdot,mf,mh2o,mm,ms,p,pi,pout,pgrad,r,rey,rhof,rhom,
     *		rhomix,sulfur,sv,t1,temp,v,vfgas,wtdepth,wtmin,
     *		xco2,xh2o,xsarea,xsulfur,zin
	integer i,icalc,iend,ifinal,im,in,ip,io,ivar(12),ivars,ives,
     *		ivt,ix
	character title(37)*10, outfile*40

        Common/block1/area,blkmag,cm,co2,cp,cph2o,cpco2,cps,
     *		cv,cvh2o,cvco2,cvs,dadz,diam,dpdz,eps,eta,exco2,exh2o,
     *		exmol,exsulfur,f,fo,g,gamma,h2o,m,mach,mdot,mf,mm,
     *		mco2,mh2o,ms,pres,r,re, rey,rho,rhof,rhom,rhomix,
     *		sulfur,sv,temp,v,vel,vfgas,vesic,visc,xco2,
     *		xh2o,xsarea,xsulfur,z
	common/ints/i,icalc,iend,im,ip,io,ives

	data title/'      area','    mach #','   p (MPa)',
     *		'    log Re','   density','  time (s)',' vel (m/s)',
     *		'     vfgas','  log visc','     z (m)','     da/dz',
     *		'    log(p)','      dpdz','    dz (m)',' wt% exco2',
     *		' wt% exh2o','   wt% exs','         f','     gamma',
     *		' mgas/mtot',' mmag/mtot',' R (J/m K)','  gas dens',
     *		' sonic vel','      xco2','      xh2o','   xsulfur',
     *		'     cph2o','     cpco2','  cpsulfur','     cvh2o',
     *		'     cvco2','  cvsulfur','   temp(C)',' h (kJ/kg)',
     *		'        cp','    radius'/

C	OPEN INPUT AND OUTPUT FILES

	open (unit=8,file='hicin')
	
C     QUERY USER FOR NAME OF OUTPUT FILE

      write (6,1342)
1342  format (/,5x,'enter name of output file:'$)
      read (5,1343) outfile
1343  format (a40)
            	
	open (unit=9,file=outfile)

C	READ INPUT DATA

	read (8,*)
	read (8,*) icalc
	read (8,*) pres(1)
	read (8,*) pgrad
	read (8,*) ivt
	read (8,*) vel(1)
	read (8,*) rhom
	read (8,*) t1
30	read (8,*) h2o, co2, sulfur

	  if ((h2o.eq.0.).and.(sulfur.ne.0.).and.(co2.ne.0.)) then
	    write (6,265)
265	    format (/,' Sorry, I can"t handle zero-values of H2O and',/,
     *		' non-zero values of CO2 and sulfur.  Please try',/,
     *		' another combination.')
	    stop
 	  end if

	read (8,*) ives
	read (8,*) z(1)
	  if (z(1).gt.0.) z(1)=-z(1)
	read (8,*) diam
	read (8,*) fo

C	READ PARAMETERS TO WRITE TO OUTPUT FILE

	do 1039 iparam=1,18
1039	   read (8,*)

	ivars=0
	do 1041 iin=1,37
	  read (8,31,err=1041) ix
31	  format (i1)
	  if (ix.le.0) go to 1041
	  ivar(ix)=iin
	  ivars = ivars+1
1041	continue

	do 1044 ix=1,ivars
	  if (ivar(ix).eq.0) then
		write (6,1043)
1043		format (/, ' output parameters incorrectly listed.',
     *			/,' program stopped.')
		stop
		end if
1044	continue

C	SET INITIAL VALUES

	g = 9.81d+00

	if (icalc.eq.2) then

C	CONVERT PRESSURE GRADIENT FROM Pa/m TO MPa/km

	  dpdz = -pgrad*1000.
	  pres(1) = 1.013d+05 + dpdz*z(1)
	  ivt = 1
	  eps = 1.0d-03
	  imax = 2000
	 else
	  dadz = 0.
	  pres(1) = pres(1)*1.0d+06
	  eps = 3.0d-07
	  imax = 1000
	end if

	blkmag = 1.0d+11
	cm = 1.0d+03
	i = 1
	iend = 0
	im = 1
	ip = 1
	iruns = 0
	mco2 = 0.0440
	mh2o = 0.01801
	ms = 0.032064
	pi = 3.14159d+00
	r = 8.314
	area(1) = pi * (diam/2.)**2
	xsarea = area(1)

C	WRITE OUT INITIAL CONDITIONS

	write (6,134) vel(1), rhom, t1, fo, h2o, co2, sulfur
134	format (/,10x,'INPUT VALUES:',//,
     *		10x,' input velocity = ',f8.4,' m/s',/,
     *		10x,' magma density=',f7.0,' kg/m3',/,
     *		10x,' input temperature =',f6.0,' degrees Celsius',/,
     *		10x,' fo (wall roughness) =',f7.4,/,
     *		10x,' initial dissolved h2o=',f6.3,' wt %',/,
     *		10x,' initial dissolved co2=',f6.3,' wt %',/,
     *		10x,' initial dissolved S=',f6.3,' wt %')

	if (icalc.eq.1) then
		write (6,1538) diam, pres(1)/1.0d+06
1538		format (/,10x,'assume constant conduit diameter:',/,
     *		  10x,'diameter = ',f6.3,' meters',/,
     *		  10x,'input pressure = ',f6.2,' MPa')
	  else
		write (6,1539) pgrad, diam
1539		format (/,10x,'assume constant pressure gradient',/,
     *		  10x,'pressure gradient = ',f7.2,' MPa/km',/,
     *		  10x,'initial conduit diameter = ',f6.3,' meters')
	end if

        if (ivt.eq.1) then
                write (6,1534)
1534            format (/,10x,'no velocity adjustment',/)
          else
                write (6,1535)
1535            format (/,10x,'automatic velocity adjustment',/)
        end if

        if (ives.eq.1) then
                write (6,1536)
1536            format (/,10x,
     *		  'continued exsolution after fragmentation',/)
          else
                write (6,1537)
1537            format (10x,'no exsolution after fragmentation',/)
        end if

C	CALCULATE PARAMETERS AT BOTTOM OF CONDUIT

50	continue

	iruns = iruns+1

	write (6,1433)  iruns
1433	format (' STARTING RUN NUMBER ',i3,':',$)

	p = pres(1)
	dz = -z(1)/100.
	wtmin = 5000.
	temp = t1 + 2.7315d+02

C	CALCULATE AND WRITE OUT MASS FLUX

	call exsolv(p)
	call dens(p)

C	STOP PROGRAM IF MAGMA PRESSURE GRADIENT > CONDUIT PRESSURE GRADIENT

	if ((icalc.eq.2).and.(rhomix.gt.(pgrad*100.))) then
	  write (6,1552) rhomix, rhomix/100.
1552	  format (/,10x,
     *	    'Density of magma/gas mixture = ',f6.0,' kg/m3.',/,
     *          10x,'Thus its pressure gradient is ',f6.0,' MPa/km.',/,
     *	    10x,'This is greater than that specified for the conduit',
     *	    /,10x,
     *	    'It must be LESS THAN that of the conduit',
     *	    /,10x,
     *	    'or else magma will not erupt.',//,
     *	    10x,'program stopped.',/)
	  stop
	end if

	mdot = rhomix*xsarea*vel(1)

	write (6,135) mdot
135	format(10x,'     mass flux=',e12.4,' kg/s')

C	CALCULATE AND WRITE INITIAL VALUES OF VARIABLES.  IF ICALC=2,
C	ADJUST DZ VALUE SO THAT XSAREA DOESN'T CHANGE BY MORE THAN
C	10% BETWEEN STEPS.

	if (icalc.eq.1) then
	  call derivs(z(1),pres(1),dpdz)
	 else
	  call derivs(z(1),xsarea,dadz)
	  dz = abs(0.1*xsarea/dadz)
	end if

	ho = temp*(mf*cp+mm*cm)+pres(1)/rhom + vel(1)**2/2.
	area(1) = xsarea
	mach(1) = m
	re(1) = rey
	rho(1) = rhomix
	time(1) = 0.
	vesic(1) = vfgas
	visc(1) = eta

C	ASSIGN VARIABLES TO OUTPUT ARRAY

	output(1,1) = area(1)
	output(2,1) = mach(1)
	output(3,1) = pres(1)/1.e+06
	output(4,1) = log10(re(1))
	output(5,1) = rho(1)
	output(6,1) = time(1)
	output(7,1) = vel(1)
	output(8,1) = vesic(1)
	output(9,1) = log10(visc(1))
	output(10,1) = z(1)
	output(11,1) = dadz
	output(12,1) = dlog10(pres(1))-6.0
	output(13,1) = dpdz
	output(14,1) = dz
	output(15,1) = exco2
	output(16,1) = exh2o
	output(17,1) = exsulfur
	output(18,1) = f
	output(19,1) = gamma
	output(20,1) = mf
	output(21,1) = mm
	output(22,1) = r
	output(23,1) = rhof
	output(24,1) = sv
	output(25,1) = xco2
	output(26,1) = xh2o
	output(27,1) = xsulfur
	output(28,1) = cph2o
	output(29,1) = cpco2
	output(30,1) = cps
	output(31,1) = cvh2o
	output(32,1) = cvco2
	output(33,1) = cvs
	output(34,1) = temp-273.15
	output(35,1) = ho/1.0d+03
	output(36,1) = cp
	output(37,1) = diam/2.

	write (6,13) '  i', (title(ivar(ix)), ix=1,ivars)
	write (6,1402) i, (output(ivar(ix),1), ix=1,ivars)

C**********************************************************************

C	BEGIN LOOP

	i = 1

100	continue

	zin = z(i)
	p = pres(i)

C	CALL SELF-ADJUSTING RUNGE-KUTTA PROGRAM TO CALCULATE NEXT Z STEP
C	AND PRSSURE ETC AT THAT STEP.

	if (icalc.eq.1) then
	  call rkqc(p,dpdz,zin,dz,eps,p,dzout,dznext,derivs)
	  i = i+1
	  z(i) = zin 
	  pres(i) = p
	 else
	  call rkqc(xsarea,dadz,zin,dz,eps,xsarea,dzout,dznext,derivs)
	  i = i+1
	  z(i) = zin
	  pres(i) = 1.013d+05 + dpdz*zin
	end if
	  
	if ((i.eq.1).and.(dzout.ne.dz)) output(14,1) = dzout


	dz = dznext

C	IF Z>0., ADJUST DZ AND CALL RK4 TO CALCULATE P AT Z=0.

	if (z(i).gt.0.) then
	  dz=-z(i-1)
	  if (icalc.eq.1) then
	     call rk4(pres(i-1),dpdz,z(i-1),dz,pout,derivs)
	     pres(i) = pout
	   else
	     call rk4(area(i-1),dadz,z(i-1),dz,xsarea,derivs)
	     pres(i) = 1.013d+05
	     area(i) = xsarea
	  end if
	  z(i) = 0.
	end if

C	ASSIGN NEW VALUES OF PARAMETERS TO ARRAYS

	if (icalc.eq.1) then
	  call derivs(z(i),pres(i),dpdz)
	 else
	  call derivs(z(i),xsarea,dadz)
	end if

	area(i) = xsarea
	mach(i) = m
	re(i) = rey
	rho(i) = rhomix
     	vel(i) = v
	vavg = (vel(i)+vel(i-1))/2.
	time(i) = time(i-1)+(z(i)-z(i-1))/vavg
	vesic(i) = vfgas
	visc(i) = eta

C	CALCULATE NEW TEMPERATURE AND ENTHALPY BY ASSUMING THAT THE SUM
C	(ENTHALPY + SP. KINETIC ENERGY OF MIXTURE) IS CONSTANT

	h = ho - vel(i)**2/2. - g*(z(i)-z(1))
	temp = (h - pres(i)/rhom)/(mf*cp + mm*cm)

C	WRITE VALUES TO ARRAY "OUTPUT"

	output(1,i) = area(i)
	output(2,i) = mach(i)
	output(3,i) = pres(i)/1.e+06
	output(4,i) = log10(re(i))
	output(5,i) = rho(i)
	output(6,i) = time(i)
	output(7,i) = vel(i)
	output(8,i) = vesic(i)
	output(9,i) = log10(visc(i))
	output(10,i) = z(i)
	output(11,i) = dadz
	output(12,i) = dlog10(pres(i))-6.0
	output(13,i) = dpdz
	output(14,i) = dz
	output(15,i) = exco2
	output(16,i) = exh2o
	output(17,i) = exsulfur
	output(18,i) = f
	output(19,i) = gamma
	output(20,i) = mf
	output(21,i) = mm
	output(22,i) = r
	output(23,i) = rhof
	output(24,i) = sv
	output(25,i) = xco2
	output(26,i) = xh2o
	output(27,i) = xsulfur
	output(28,i) = cph2o
	output(29,i) = cpco2
	output(30,i) = cps
	output(31,i) = cvh2o
	output(32,i) = cvco2
	output(33,i) = cvs
	output(34,i) = temp-273.15
	output(35,i) = h/1.0d+03
	output(36,i) = cp
	output(37,i) = diam/2.

C	CALCULATE WATER TABLE DEPTH REQUIRED FOR HYDROSTATIC PRESSURE
C	TO EXCEED PRES(I) (ASSUME WATER DENSITY OF 0.9, OR 9000 PA/M)

	wtdepth = z(i) + (pres(i)-1.013d+05)/9000.
	if (wtdepth.lt.wtmin) wtmin=wtdepth

	if (icalc.eq.2) go to 1500

C       IF ICALC=1 AND P<1 ATM, OR M>1, ADJUST THE INPUT VELOCITY

        if (((pres(i).lt.1.013e+05).or.(mach(i).gt.1.00)).
     *    and.(z(i).lt.-0.05)) then
	  if (ivt.eq.1) then
1491	    if (pres(i).lt.1.013e+05) then
	      write (6,533)
533	      format (/,5x,'p < 1 atm.  program stopped')
	     else
	      write (6,1434)
1434	      format (/,5x,'mach number > 1.  program stopped')
	    end if
	    go to 1501
	  else
1492  	    write (6,1402) i, (output(ivar(ix),i), ix=1,ivars)
	    if ((vel(1).eq.0.001).and.(pres(i).lt.1.013e+05)) then
	     write (6,1445)
1445	     format(/,10x,'pressure insufficient to produce eruption',/)
	     iend = 1
	     go to 1501
	    end if
            call adjust
	    if (iend.eq.1) go to 1501
            go to 50
	  end if
	end if

C	IF M>0.99999 AND Z>-0.05, CALL IT GOOD

	if ((z(i).gt.-0.05).and.(mach(i).gt.0.99999)) go to 1501

C       RETURN TO BEGINNING OF LOOP IF Z < 0. AND P > 1 ATM

1500    if ((z(i).lt.0.).and.(i.lt.imax)) go to 100

C	IF imax ITERATIONS IS REACHED, OR IVT=1, STOP PROGRAM

	if ((i.eq.imax).or.(ivt.eq.1)) go to 1501

C       IF Z=0. AND P>1 ATM, ADJUST THE INPUT VELOCITY AND START OVER

        if (pres(i).gt.1.014e+05) then
  	    write (6,1402) i, (output(ivar(ix),i), ix=1,ivars)
            call adjust
	    if (iend.eq.1) then
	      write (6,5109)
5109	      format (/,10x,'limit of resolution reached',/)
	      go to 1501
	    end if
            go to 50

C	IF PRESSURE IS BETWEEN 0.1012 AND 0.1014 MPA, CALL IT GOOD

	  else if ((pres(i).le.1.014e+05).and.(pres(i).gt.1.012e+05)) 
     *		then
	    go to 1501

C	IF PRESSURE IS LESS THAN .1012 MPA, ADJUST THE INPUT VELOCITY

	  else
  	    write (6,1402) i, (output(ivar(ix),i), ix=1,ivars)
	    write (6,1424)
1424	    format (/,10x,'pressure < 1 atm',/)
	    call adjust
	    if (iend.eq.1) go to 1501
	    go to 50
         end if

C***********************************************************************

C	ONCE THE A SOLUTION HAS BEEN REACHED, WRITE OUT FINAL RESULTS

1501	continue

	ifinal = i

C	WRITE OUT HEADERS

     	write (9,1301) ifinal,'  i', (title(ivar(ix)), ix=1,ivars)
13	format (/,1x,a4,7a10)
1301	format (i4,a3,7a10)

C	WRITE FINAL VALUES TO STANDARD OUTPUT

	if (iend.ne.1) then
  	  write (6,1402) ifinal, (output(ivar(ix),ifinal), ix=1,ivars)
	  if ((ifinal.eq.imax).and.(icalc.eq.2)) then
	  write (6,1902)
1902	  format (/,10x,'Number of iterations has exceeded the limit.',/,
     *		10x,'You should be able to perform this calculation in',/,
     *		10x,'fewer iterations.  Check and see if the radius is',/,
     *		10x,'changing rapidly at the bottom of the conduit.',/,
     *		10x,'(if icalc=2). If so, try adjusting these',/,
     *		10x,'parameters and running it over again.')
	   go to 1034
	  end if
	  write (6,1401)
1401	  format (/,' successful completion')

C	CALCULATE MAXIMUM THEORETICAL VELOCITY, FINAL TEMPERATURES

	  call velmax

C	WRITE OUT WATER TABLE DEPTH REQUIRED FOR WATER INFLUX

	  write (6,1042) wtmin
1042	  format (/,' maximum water table depth that will',
     *		' allow g.w. influx = ',f8.2,' meters',/,
     *		' (negative values are below ground surface,',
     *		' positive values are above)',/)
	end if

C	WRITE FLOW PROPERTIES TO OUTPUT FILE

1034	do 1100 in=1,ifinal
  	  write (9,1403) in, (output(ivar(ix),in), ix=1,ivars)
1402      format (1x,i4,7f10.3)
1403      format (3x,i4,7f10.3)
1100	continue

	close(8)
	close(9)

	end

C			END OF PROGRAM

C************************************************************************

C************************************************************************

C	SUBROUTINE RKQC
C	SUBROUTINE TAKEN FROM NUMERICAL RECIPES, P. 558, THAT
C	CALCULATES THE PRESSURE AT THE NEW VALUE OF Z AND ADJUSTS
C	THE NEXT DZ VALUE FOR THE CHANGING CONDITIONS

	subroutine rkqc(y,dydx,x,htry,eps,yscal,hdid,hnext,derivs)

	implicit double precision (a-h,o-z)

	parameter (pgrow=-0.20,pshrink=-0.25,fcor=1./15.,
     *		one=1.,safety=0.9,errcon=6.d-04)
        real*8 dydx,eps,errmax,h,hdid,hh,hnext,
     *          htry,x,xsav,y,ysav,
     *          yscal,ytemp


	external derivs
	
	xsav = x
	ysav = y
	dysav = dydx

	h = htry
1	hh = 0.5*h

	call rk4(ysav,dysav,xsav,hh,ytemp,derivs)

	x = xsav+hh
	call derivs(x,ytemp,dydx)
	call rk4(ytemp,dydx,x,hh,y,derivs)

	x = xsav+h
	if (x.eq.xsav) then
	  write (6,1400)
1400	  format (/,10x,'Stepsize not significant in rkqc.',/,
     *		10x,'If you are using a constant pressure gradient',/,
     *		10x,'chances are that your conduit radius is too large',/,
     *		10x,'(or too small),or your entrance velocity is too low',/,
     *		10x,'(or too high).  Try again.',//,
     *		10x,'program stopped',/)
	  stop
	end if
	call rk4(ysav,dysav,xsav,h,ytemp,derivs)

	ytemp = y-ytemp
	errmax = (abs(ytemp/yscal))/eps

	if (errmax.gt.one) then
		h = safety*h*(errmax**pshrink)
		go to 1
	  else
		hdid=h
		if (errmax.gt.errcon) then
		  hnext = safety*h*(errmax**pgrow)
		else
			hnext = 1.7*h
		end if
	end if

	y = y + ytemp*fcor

	return

	end

C************************************************************************

C	SUBROUTINE RK4
C	SUBROUTINE TO CALCULATE NEW PRESSURE AT THE NEW ELEVATION
C	USING THE FOURTH-ORDER RUNGE-KUTTA METHOD.  THIS SUBROUTINE
C	WAS MODIFIED FROM THAT IN NUMERICAL RECIPES, P. 553.

	subroutine rk4(y,dydx,x,h,yout,derivs)

	implicit double precision (a-h,o-z)

        real*8 dydx,dydx2,dym,dyt,h,h6,hh,x,xh,y,yout,yt

	hh = h*0.5
	h6 = h/6.
	xh = x + hh
	dydx2 = dydx

      yt = y + hh*dydx

      call derivs(xh,yt,dyt)
      yt = y + hh*dyt

      call derivs(xh,yt,dym)
      yt = y + h*dym
      dym = dyt + dym

      call derivs(x+h,yt,dyt)

	dydx = dydx2

	yout = y + h6*(dydx + dyt + 2.*dym)

	return

	end

C************************************************************************

	subroutine derivs(znow,yp,grad)

C	SUBROUTINE TO CALCULATE PRESSURE GRADIENT BETWEEN THE PREVIOUS
C	AND THE CURRENT DEPTH.

C	DECLARE VARIABLES USED IN THIS SUBROUTINE

	implicit double precision (a-h,o-z)

        real*8 area(2000),dadz,diam,eta,f,fo,g,grad,m,
     *		mdot,p,rey,rhomix,sv,v,vfgas,xsarea,yp,z(2000),znow
	integer i, icalc

C	DECLARE VARIABLES LISTED IN THE COMMON BLOCK BUT NOT USED
C	IN THIS SUBROUTINE

        real*8 blkmag,cm,co2,cp,cph2o,cpco2,cps,cvh2o,cvco2,cv,cvs,eps,
     *		exco2,exh2o,exmol,exsulfur,gamma,h2o,
     *		mach(2000),mco2,mf,mh2o,mm,ms,pres(2000),r,re(2000),
     *		rho(2000),rhof,rhom,sulfur,temp,vel(2000),vesic(2000),
     *		visc(2000),xco2,xh2o,xsulfur
	integer iend,im,ip,io,ives

C	COMMON BLOCKS

        Common/block1/area,blkmag,cm,co2,cp,cph2o,cpco2,cps,
     *		cv,cvh2o,cvco2,cvs,dadz,diam,dpdz,eps,eta,exco2,exh2o,
     *		exmol,exsulfur,f,fo,g,gamma,h2o,m,mach,mdot,mf,mm,
     *		mco2,mh2o,ms,pres,r,re, rey,rho,rhof,rhom,rhomix,
     *		sulfur,sv,temp,v,vel,vfgas,vesic,visc,xco2,
     *		xh2o,xsarea,xsulfur,z

	common/ints/i,icalc,iend,im,ip,io,ives

	if (icalc.eq.1) then
	  p = yp
	 else
	  xsarea = yp
	  if (xsarea.lt.0.) pause ' xsarea < 0'
	  diam = 2.*sqrt(xsarea/3.14159)
	  p = 1.013d+05 + dpdz*znow
	end if

C	CALCULATE MIXTURE DENSITY

	call dens(p)

C	CALCULATE VISCOSITY

	call vis

C	CALCULATE VELOCITY, REYNOLDS, NUMBER, FRICTION FACTOR

	v = mdot/(rhomix*xsarea)
	rey = rhomix*v*diam/eta
	f = 16./rey + fo


C	CALCULATE SONIC VELOCITY, MACH NUMBER

	call svel
	m = v/sv

C	CALCULATE GRADIENT IN PRESSURE OR XSAREA

	if (icalc.eq.1) then
	   term1 = 2.*f*v**2/diam
	   grad = (rhomix*(-g - 2.*f*v**2/diam + v**2/xsarea * dadz))/
     *		(1.-m**2)
	   dpdz = grad
	 else
	   grad = xsarea/v**2 * ( dpdz*(1.-m**2)/rhomix + g +
     *		(2.*f*v**2)/diam )
	   dadz = grad
	end if

	return
	end

C*******************************************************************

C	SUBROUTINE DENS
C	SUBROUTINE TO CALCULATE MIXTURE DENSITY.  IT TAKES THE
C	PRESSURE P FROM THE CALLING PROGRAM AND RETURNS THE VALUE
C	RHOMIX


	subroutine dens(p)

C	DECLARE VARIABLES USED IN THIS SUBROUTINE

	implicit double precision (a-h,o-z)

	real*8 exmol, mf, mm, p, r, rhof, rhom, rhomix, temp
	integer ives

C	DECLARE VARIABLES LISTED IN THE COMMON BLOCK BUT NOT USED
C	IN THIS SUBROUTINE

        real*8 area(2000),blkmag,cm,co2,cp,cpco2,cph2o,cps,
     *		cv,cvco2,cvh2o,cvs,dadz,diam,eps,eta,exco2,exh2o,
     *		exsulfur,f,fo,g,gamma,h2o,m,mach(2000),mco2,mdot,
     *		mh2o,ms,pres(2000),re(2000),rey,rho(2000),sulfur,
     *		sv,v,vel(2000),vesic(2000),
     *		vfgas,visc(2000),xsarea,z(2000)
	integer i,iend,im,io,ip

C	COMMON BLOCKS

        Common/block1/area,blkmag,cm,co2,cp,cph2o,cpco2,cps,
     *		cv,cvh2o,cvco2,cvs,dadz,diam,dpdz,eps,eta,exco2,exh2o,
     *		exmol,exsulfur,f,fo,g,gamma,h2o,m,mach,mdot,mf,mm,
     *		mco2,mh2o,ms,pres,r,re, rey,rho,rhof,rhom,rhomix,
     *		sulfur,sv,temp,v,vel,vfgas,vesic,visc,xco2,
     *		xh2o,xsarea,xsulfur,z
	common/ints/i,icalc,iend,im,ip,io,ives

C	DETERMINE NEW MASS FRACTION GAS ONLY IF MAGMA IS UNFRAGMENTED.
C	IF MAGMA IS FRAGMENTED, ASSUME THAT NO NEW GAS EXSOLVES.

	if ((vfgas.lt.0.75).or.(ives.eq.1)) then
		call exsolv(p)
	end if

C	CALCULATE GAS DENSITY, MIXTURE DENSITY, VOLUME FRACTION GAS

	if (mf.gt.0.) then
	  rhof = mf*p/(exmol*r*temp)
	  rhomix = 1./(mm/rhom + mf/rhof)
	  vfgas = mf*rhomix/rhof 
	 else
	  rhof = 1.
	  rhomix = rhom
	  vfgas = 0.
	end if

	return
	end

C****************************************************************

C	SUBROUTINE EXSOLV
C	SUBROUTINE TO CALCULATE MASS FRACTION OF EXSOLVED GAS
C	USING EQUATIONS TAKEN FROM GERLACH (1986)

	subroutine exsolv(p)

	implicit double precision (a-h,o-z)

C	DECLARE VARIABLES LISTED IN THE COMMON BLOCK BUT NOT USED 
C	IN THIS SUBROUTINE

        real*8 area(2000),blkmag,cpco2,dadz,diam,eta,eps,
     *		f,fo,g,m,mach(2000),mdot,pres(2000),
     *		re(2000),rey,
     *		rho(2000),rhof,rhom,rhomix,sv,
     *		temp,v,vel(2000),vesic(2000),
     *		visc(2000),xsarea,z(2000)

C	DECLARE VARIABLES USED IN THIS SUBROUTINE

      real*8 a1,a2,b1,b2,cm,co2,cp,cph2o,cps,cvco2,cvh2o,cv,cvs,dco2, 
     *		dh2o, dph2o1, dph2o2, dsulfur, 
     *  	exco2, exdif, exh2o, exh2o1, exh2o2, exmol, exsulfur, 
     *  	extotal,gamma,h2o,mco2,mf,mh2o,mm,ms,p,ph2o,ph2onew,
     *		r,sulfur,vfgas, vgvm, xco2, xh2o, xsulfur

C	COMMON BLOCKS

        Common/block1/area,blkmag,cm,co2,cp,cph2o,cpco2,cps,
     *		cv,cvh2o,cvco2,cvs,dadz,diam,dpdz,eps,eta,exco2,exh2o,
     *		exmol,exsulfur,f,fo,g,gamma,h2o,m,mach,mdot,mf,mm,
     *		mco2,mh2o,ms,pres,r,re, rey,rho,rhof,rhom,rhomix,
     *		sulfur,sv,temp,v,vel,vfgas,vesic,visc,xco2,
     *		xh2o,xsarea,xsulfur,z

	if (p.gt.0.) then

C	CALCULATE DISSOLVED CO2 USING EQUATION 7 FROM GERLACH (1986)

           dco2 = 0.0005 + 5.9e-04*(p/1.0d+06)

	   if (dco2.ge.co2) then
		mf = 0.
		vfgas = 0.
		gamma = 1.167
		exco2 = 0.
		exh2o = 0.
		exsulfur = 0.
		xco2 = 0.333
		xh2o = 0.333
		xsulfur = 0.333
		extotal = 0.
		exmol = 0.
		go to 300
	   end if

           exco2 = co2 - dco2

C	BEGIN LOOP THAT ITERATES TO FIND THE PARTIAL PRESSURE OF H2O
C	(PH2O, WHICH IS NEEDED TO CALCULATE DISSOLVED H2O).  START
C	BY GUESSING THAT PH2O = P/2.

	   ph2onew = p/2.

1000       continue

           ph2o = ph2onew

C	CALCULATE EXSOLVED WATER USING EQUATION 6 FROM GERLACH (1986)

           dh2o = 1801./(8394.19*sqrt(p/1.0d+06)*
     *		((ph2o/1.0d+06)**(-.9917)) - 356.98)
           exh2o1 = h2o - dh2o

C       CALCULATE EXSOLVED WATER USING A REARRANGED VERSION OF EQUATION
C	13 FROM GERLACH (1986)

           exh2o2 = (21.07*ph2o*exco2)/(44.*p - 51.48*ph2o)

C       COMPARE EXSOLVED WATER FROM THE TWO METHODS

           exdif = exh2o2-exh2o1
           if (abs(exdif).gt.0.00001) then

C       IF THEY DON'T AGREE, USE THE FIRST DERIVATIVES OF EXH2O1 AND EXH2O2
C       (I.E. D(EXH2O1)/D(PH2O)) AND D(EXH2O2)/D(PH2O) TO CALCULATE A NEW 
C	PH2O

              dph2o1 = (-1.5001e+07*sqrt(p/1.0d+06)*((ph2o/1.0d+06)**
     *		(-1.9917))) /
     *          (8394.19*sqrt(p/1.0d+06)*((ph2o/1.0d+06)**(-0.9917)) 
     *		- 356.98)**2

	      dph2o1 = dph2o1/1.0d+06

              dph2o2 = ((21.06*exco2)/(44.*p-51.48*ph2o)) *
     *                  ( 1. + (51.48*ph2o)/(44.*p - 51.48*ph2o))

C       THESE DERIVATIVES MAKE UP THE SLOPES OF LINES THAT GO THROUGH PH2O AND
C       THE RESPECTIVE EXH2O VALUES.  THE LINES ARE DEFINED BY THE EQUATIONS
C                  Y1 = A1 * X + B1 		FOR EXH2O1 VS PH2O, AND
C                  Y2 = A2 * X + B2 		FOR EXH2O2 VS PH2O.
C       THE OBJECTIVE IS TO FIND WHERE THESE LINES CROSS.  THAT WILL BE OUR
C       NEW ESTIMATED VALUE OF PH2O.

              a1 = dph2o1
              a2 = dph2o2

              b1 = exh2o1 - ph2o * a1
              b2 = exh2o2 - ph2o * a2

C       THE LINES CROSS AT THE VALUE PH2O = (B1-B2)/(A2-A1).

              ph2onew = (b1-b2)/(a2-a1)

C       MAKE SURE THE NEW PH2O DOES NOT EXCEED 0.847*P (IN WHICH CASE THE
C	SOLUTION BLOWS UP).

              if (ph2onew.gt.(0.847*p)) then
                   ph2onew = (ph2o + 0.847*p)/2.
              end if

              go to 1000
	   end if

C	ONCE WE HAVE FOUND THE VALUE OF PH2O, CALCULATE TOTAL EXSOLVED 
C	FLUIDS AND VESICULARITY

           exh2o = (exh2o1+exh2o2)/2.
	   if (exh2o.lt.0.) exh2o = 0.
	   dh2o = h2o-exh2o

           exsulfur = 0.3025*exh2o + 0.1238*exco2
	   if (exsulfur.lt.0.) exsulfur = 0.
           dsulfur = sulfur-exsulfur

           extotal = exh2o + exco2 + exsulfur
           exmol = .01*(exh2o/mh2o + exco2/mco2 + exsulfur/ms)
	   mf = extotal/100.
	   mm = 1.-mf

           xh2o = ph2o/p
           xco2 = 0.855 - xh2o
	   xsulfur = 0.155

           vgvm = exmol*r*temp*rhom/(p*mm)

	   vfgas = vgvm/(vgvm+1.)

C	CALCULATE CP FOR GAS SPECIES USING
C	EMPIRICAL FORMULAS TAKEN FROM TABLE A-15 IN MORAN IN SHAPIRO
C	AT VARIOUS TEMPERATUES (P ASSUMED =1 ATM)

	   cph2o = (4.070 - 1.108d-3*temp + 4.152e-6*temp**2 -
     *		2.964d-9*temp**3 + 0.807d-12*temp**4) * r/mh2o
	   cpco2 = (2.401 + 8.735d-3*temp - 6.607d-6*temp**2 +
     *		2.002d-9*temp**3) * r/mco2
	   cps = (3.267 + 5.324d-3*temp + 0.684d-06*temp**2 -
     *		5.281d-9*temp**3 + 2.559d-12*temp**4) * r/ms
 	   cp = (exh2o*cph2o+exco2*cpco2+exsulfur*cps)/extotal

	   cvh2o = cph2o - 8.314/mh2o
	   cvco2 = cpco2 - 8.314/mco2
	   cvs = cps - 8.314/ms

C	CALCULATE CV, GAMMA

	   cv = (exh2o*cvh2o+exco2*cvco2+exsulfur*cvs)/extotal

	   gamma = cp/cv

C	IF PRESSURE < 0., MAKE UP NUMBERS FOR GAMMA, MF, VFGAS

	else

	   mf = (h2o+co2+sulfur)/100.
	   gamma = 1.25
	   vfgas = 0.99

        end if

300	continue
	mm = 1. - mf

	return
	end

C****************************************************************

C	SUBROUTINE SVEL
C	SUBROUTINE TO CALCULATE SONIC VELOCITY

	subroutine svel

C	DECLARE VARIABLES USED IN THIS SUBROUTINE

	implicit double precision (a-h,o-z)

	real*8 blkgas, blkmag, blkmix, gamma, mf, mm, r,
     *           rhof, rhom, rhomix, sv, temp, vfgas, vfmag

C	DECLARE VARIABLES LISTED IN THE COMMON BLOCK BUT NOT USED
C	IN THIS SUBROUTINE

	real*8 area(2000),cm,co2,cp,cpco2,cph2o,cps,cvco2,cvh2o,
     *		cv,cvs,dadz, diam,eps,eta,exco2,exh2o,exmol,exsulfur,
     *		f,fo,g,h2o,m,mach(2000),mco2,mdot,mh2o,ms,pres(2000),
     *		re(2000),rey,rho(2000),sulfur,v,vel(2000),
     *		vesic(2000),visc(2000),xsarea,z(2000)

        Common/block1/area,blkmag,cm,co2,cp,cph2o,cpco2,cps,
     *		cv,cvh2o,cvco2,cvs,dadz,diam,dpdz,eps,eta,exco2,exh2o,
     *		exmol,exsulfur,f,fo,g,gamma,h2o,m,mach,mdot,mf,mm,
     *		mco2,mh2o,ms,pres,r,re, rey,rho,rhof,rhom,rhomix,
     *		sulfur,sv,temp,v,vel,vfgas,vesic,visc,xco2,
     *		xh2o,xsarea,xsulfur,z

C	CALCULATE VOLUME FRACTION OF ROCK

	vfmag = 1.-vfgas

C	CALCULATE BULK MODULI AND SONIC VELOCITY

	if (mf.gt.0.) then
	  blkgas = rhof*gamma*exmol*r*temp/mf
	  blkmix = 1./(vfgas/blkgas + vfmag/blkmag)
          sv = sqrt(blkmix/rhomix)
	 else
	  sv = sqrt(blkmag/rhom)
	end if
	  
	return
	end

C*******************************************************************

C	SUBROUTINE VIS
C	SUBROUTINE THAT CALCULATES VISCOSITY AS A FUNCTION OF T,
C	GAS CONTENT, AND VESICULARITY.  THE SECTION THAT GIVES 
C	VISCOSITY CONTENT VERSUS T AND WATER CONTENT WAS TAKEN
C	FROM SHAW (1972) FOR KILAUEAN BASALTS.
C	THE SECTION THAT GIVES VISCOSITY AS A
C	FUNCTION OF VESICULARITY IS MODIFIED FROM EQUATIONS IN
C	DOBRAN (1992, EQ. 24)

	subroutine vis

C	DECLARE VARIABLES USED IN THIS SUBROUTINE

	implicit double precision (a-h,o-z)

	real*8 eta, etagas, etagaslg, etamag, etamaglg, etamixlg,
     *		 exp, temp, vfgas 

C	DECLARE VARIABLES THAT ARE IN THE COMMON BLOCK BUT NOT USED
C	IN THIS SUBROUTINE

        real*8 area(2000),blkmag,cm,co2,cp,cpco2,cph2o,cps,cv,
     *		cvco2,cvh2o,cvs,dadz,diam,eps,exco2,exh2o,exmol,
     *		exsulfur,f,fo,g,gamma,h2o,m,mach(2000),
     *		mco2,mdot,mf,mh2o,mm,ms,pres(2000),
     *		r,re(2000),rey,rho(2000),rhof,rhom,rhomix,sulfur,sv,v,
     *		vel(2000),vesic(2000),visc(2000),xsarea,z(2000)

        Common/block1/area,blkmag,cm,co2,cp,cph2o,cpco2,cps,
     *		cv,cvh2o,cvco2,cvs,dadz,diam,dpdz,eps,eta,exco2,exh2o,
     *		exmol,exsulfur,f,fo,g,gamma,h2o,m,mach,mdot,mf,mm,
     *		mco2,mh2o,ms,pres,r,re, rey,rho,rhof,rhom,rhomix,
     *		sulfur,sv,temp,v,vel,vfgas,vesic,visc,xco2,
     *		xh2o,xsarea,xsulfur,z


C	CALCULATE MAGMA VISCOSITY AS A FUNCTION OF TEMPERATURE

	exp = -10.737 + 1.8183 * (1.0d+04/temp)
 	eta = 10.**exp

C	CALCULATE VISCOSITY AS A FUNCTION OF VFGAS, USING RELATIONSHIPS
C	FROM DOBRAN (1992). IF VESICULARITY IS > 50%,  USE A WEIGHTING
C	FUNCTION TO CALCULATE THE VISCOSITY OF MAGMA AND GAS NEAR THE
C	FRAGMENTATION POINT.


	if (vfgas.lt.0.5) then
          eta = eta / (1.-vfgas)
         else if (vfgas.lt.1.0) then
          etamag = eta / (1.-vfgas)
          etagas = (5.3d-05 * (1.-(1.-vfgas)/0.62)**(-1.5))
          etamaglg = dlog10(etamag)
          etagaslg = dlog10(etagas)
          etamixlg = etamaglg * 2.**(-((vfgas/0.75)**40))
     *                  + etagaslg * 2.**(-((0.75/vfgas)**40))
          eta = 10.**(etamixlg)
         else
          eta = 5.3d-05
        end if

	return		
	end

C******************************************************************************

C	SUBROUTINE ADJUST

C	SUBROUTINE THAT ADJUSTS INPUT VELOCITY

	subroutine adjust

C	DECLARE VARIABLES USED IN THIS SUBROUTINE

	implicit double precision (a-h,o-z)

	real*8 eps,int, mach(2000),pres(2000),slope,vel(2000),v1m(100),
     *		v1o(100),v1p(100),rmaxo,rminv,z(2000),zlm(100),zlp(100)
	integer i,im,ip

C	DECLARE VARIABLES IN THE COMMON BLOCK BUT NOT USED IN THIS
C	SUBROUTINE

	real*8 area(2000),blkmag,cm,co2,cp,cpco2,cph2o,cps,cv,
     *		cvco2,cvh2o,cvs,dadz,diam,eta,exco2,exh2o,exmol,
     *          exsulfur,f,fo,g,gamma,h2o,m,mco2,mdot,mf,mh2o,
     *		mm,ms,r,re(2000),
     *          rey,rho(2000),rhof,rhom,rhomix,sulfur,sv,temp,v,vfgas,
     *		vesic(2000),visc(2000),xsarea
	integer icalc,iend,io,ives

C	COMMON BLOCKS

        Common/block1/area,blkmag,cm,co2,cp,cph2o,cpco2,cps,
     *		cv,cvh2o,cvco2,cvs,dadz,diam,dpdz,eps,eta,exco2,exh2o,
     *		exmol,exsulfur,f,fo,g,gamma,h2o,m,mach,mdot,mf,mm,
     *		mco2,mh2o,ms,pres,r,re, rey,rho,rhof,rhom,rhomix,
     *		sulfur,sv,temp,v,vel,vfgas,vesic,visc,xco2,
     *		xh2o,xsarea,xsulfur,z
	common/ints/i,icalc,iend,im,ip,io,ives

C*********************************************************************

C	SOLUTIONS FOR Z=0.

C*********************************************************************

	if (z(i).eq.0.) then

C	IF Z(I)=0 AND P>1 ATM, SEE IF THERE ARE PREVIOUS CALCULATIONS
C	RESULTING IN M>1 OR P<1 ATM.  IF SO, INCREASE VEL(1) BY 0.2 
C	TIMES THE DIFFERENCE BETWEEN THE MINIMUM V1M OR V1P AND THE 
C	MAXIMUM V1O

	  if (pres(i).gt.1.014e+05) then
	    write (6,*) 'exit pressure > 1 atm and M < 1'
	    v1o(io) = vel(1)
	    io = io+1

C	FIND MINIMUM OF V1P AND V1M

	    rminv = 5.d+05
	    do 150 j=1,im-1
150	    rminv=min(rminv,v1m(j))
	    do 160 j=1,ip-1
160	    rminv=min(rminv,v1p(j))

C	FIND MAXIMUM OF V1O

	    rmaxo = 0.
	    do 170 j=1,io-1
170	    rmaxo=max(rmaxo,v1o(j))

C	IF THE MINIMUM OF V1P OR V1M AND THE MAXIMUM OF V1O DON'T DIFFER BY MORE
C	THAN ABOUT 100*EPS, THEN CALL THE SOLUTION GOOD.

	    if ((rmaxo.gt.0.).and.((rminv-rmaxo)/rmaxo).lt.(10.*eps)) then
	      iend=1
	      return

C	CALCULATE NEW VALUE OF VEL(1)

	     else if (rminv.lt.5.d+05) then
	      vel(1) = rmaxo + 0.25*(rminv-rmaxo)
	     else
	      vel(1) = 1.5*vel(1)
	    end if
	    go to 500

C	IF Z=0. AND THE FINAL PRESSURE IS <0.1012 MPA, ADJUST THE 
C	INITIAL VELOCITY SO THAT IT'S HALFWAY BETWEEN THE CURRENT 
C	VEL(1) AND THE MAXIMUM V1O

	  else
	    
	    rmaxo = 0.
	    do 171 j=1,io-1
171	    rmaxo=max(rmaxo,v1o(j))

	    vel(1) = rmaxo + 0.5*(vel(1)-rmaxo)
	    if (vel(1).lt.0.001) then
		write (6,143)
143		format (/,10x,'pressure is too low to erupt')
		iend = 1
		return
	    end if
	    go to 500

	  end if
	end if

C*********************************************************************

C	SOLUTIONS FOR Z<0.

C*********************************************************************

C	IF M>1, THE RELATIONSHIP BETWEEN Z(I) AND VEL(1) SHOULD BE
C	ALMOST LINEAR.  THEREFORE, IF WE HAVE RUN AT LEAST
C	TWO ITERATIONS WHERE VEL(1) AND Z(I) HAVE BEEN OBTAINED,
C	WE CAN USE THOSE VALUES TO DEFINE THE LINE RELATING Z(I) AND
C	VEL(1), AND CALCULATE THE VEL(1) NEEDED TO OBTAIN M=1 AT
C	Z(I) = 0.   THIS VALUE IS VEL(1)=-INT/SLOPE, WHERE INT IS THE
C	Z(I) INTERCEPT OF THE Z(I) VS VEL(1) LINE, AND SLOPE IS THE
C	SLOPE OF THE LINE.

C	IT TURNS OUT THAT, IF ONE ASSUMES THE RELATIONSHIP
C	BETWEEN Z(I) AND VEL(1) TO BE PERFECTLY LINEAR, ONE OVERSHOOTS
C	AND ENDS UP BACK IN THE M<1 FIELD.  THEREFORE, I ADD 10% OF 
C	THE DIFFERENCE BETWEEN THE OLD VEL(1) AND THAT OBTAINED FROM
C	VEL(1)=-INT/SLOPE, TO MAKE SURE THAT VEL(1) STAYS WITHIN
C	THE M>=1 FIELD.

	if (mach(i).gt.1.000) then
          write (6,*) ' mach number > 1.  adjusting vi'
	  zlm(im) = z(i)
	  v1m(im) = vel(1)

C	CALCULATE SLOPE AND INTERCEPT OF V(1) VS Z(I) LINE,
C	AND VALUE OF V(1) ALONG THIS LINE WHEN Z(I)=0.  

	  if (im.ge.2) then
	    slope = (zlm(im)-zlm(im-1))/(v1m(im)-v1m(im-1))
	    int = zlm(im)-slope*v1m(im)
	    vel(1) = -int/slope + 0.1*(min(v1m(im),v1m(im-1))+
     *			int/slope)
	   else 
	    vel(1) = -vel(1)*(z(i)-z(1))/z(1) 
	  end if
	  im = im+1

C	FOR P<1 ATM, ADJUST V(1).  ASSUME, AS WHEN M>1, THAT THE
C	RELATIONSHIP BETWEEN V(1) AND Z(I) IS LINEAR.  CALCULATE V(1)
C	ALONG THIS LINE FOR Z(I)=0.

	else if (pres(i).lt.1.013d+05) then
          write (6,*) 'pressure is less than 1 atm.  adjusting vi'
	  zlp(ip) = z(i)
	  v1p(ip) = vel(1)
	  if (ip.ge.2) then
	    slope = (zlp(ip)-zlp(ip-1))/(v1p(ip)-v1p(ip-1))
	    int = zlp(ip)-slope*v1p(ip)
	    if (((-int/slope).le.0.).or.((-int/slope).gt.
     *		(vel(1)))) then
		vel(1) = vel(1)/2.
	     else
	    	vel(1) = -int/slope
	    end if
	  else
	    vel(1) = -vel(1)*(z(i)-z(1))/z(1) 
	  end if
	  if (vel(1).le.0.001) vel(1)=0.001
	  ip = ip+1
	end if

C	RE-INITIALIZE VARIABLES AND WRITE OUT NEW INITIAL VELOCITY

500	continue

	do 100 j=1,i
	  re(j) = 0.
	  rho(j) = 0.
	  mach(j) = 0.
	  vesic(j) = 0.
	  visc(j) = 0.
100	continue
	do 200 j=2,i
	  vel(j) = 0.
	  pres(j) = 0.
	  z(j) = 0.
200	continue
	i = 1
	write (6,1044) vel(1)
1044    format (/,' trying new input velocity ',f8.5,' m/s',/)

	return
	end

C***********************************************************************

C	SUBROUTINE VELMAX

	subroutine velmax

C	CALCULATES MAXIMUM THEORETICAL VELOCITY.  THIS IS DONE BY FIRST
C	CALCULATING THE AMOUNT OF COOLING THAT ACCOMPANIES DECOMPRESSION
C	OF THE MIXTURE TO ATMOSPHERIC PRESSURE.  USING THIS AMOUNT OF
C	COOLING, A NEW ENTHALPY IS CALCULATED.  THEN, FROM THE NEW
C	ENTHALPY, A MAXIMUM THEORETICAL VELOCITY IS CALCULATED FROM THE
C	EQUATION:
C			VMAX = SQRT(2.*(H2-H1))
C
C	WHERE H1 IS THE ENTHALPY OF THE MIXTURE AT THE VENT EXIT, AND
C	H2 IS THE ENTHALPY OF THE MIXTURE ONCE ITS PRESSURE EQUILIBRATES
C	WITH ATMOSPHERIC.

C	DECLARE VARIABLES USED IN THIS SUBROUTINE

	implicit double precision (a-h,o-z)

	real*8 cm, cp, deltah, deltat, gmix, mf, mm, pres(2000), r,
     *		rhom, temp, temp2, temp2c, vel(2000), vmax
	integer i

C	DECLARE VARIABLES LISTED IN COMMON BLOCK BUT NOT USED IN
C	THIS SUBROUTINE

        real*8 area(2000),blkmag,co2,cph2o,cpco2,cps,cv,cvh2o,
     *		cvco2,cvs,dadz,diam,dpdz,eps,eta,exco2,exh2o,exmol,
     *		exsulfur,f,fo,g,gamma,h2o,m,mach(2000),mco2,
     *		mdot,mh2o,ms,re(2000),
     *		rey,rho(2000),rhof,rhomix,sulfur,sv,v,vfgas,
     *		vesic(2000),visc(2000),xco2,xh2o,xsarea,xsulfur,
     *		z(2000)
	integer icalc,iend,im,ip,io,ives

C	COMMON BLOCK

        Common/block1/area,blkmag,cm,co2,cp,cph2o,cpco2,cps,
     *		cv,cvh2o,cvco2,cvs,dadz,diam,dpdz,eps,eta,exco2,exh2o,
     *		exmol,exsulfur,f,fo,g,gamma,h2o,m,mach,mdot,mf,mm,
     *		mco2,mh2o,ms,pres,r,re, rey,rho,rhof,rhom,rhomix,
     *		sulfur,sv,temp,v,vel,vfgas,vesic,visc,xco2,
     *		xh2o,xsarea,xsulfur,z
	common/ints/i,icalc,iend,im,ip,io,ives

C	1.  CALCULATE GAMMA FOR MIXTURE:

	gmix = (mf*cp + mm*cm)/(mf*cv + mm*cm)

C	2.  CALCULATE NEW TEMPERATURE:

	temp2 = temp*(0.1013e+06/pres(i))**((gmix-1.)/gmix)
	temp2c = temp2-273.15
	deltat = temp-temp2

C	3.  CALCULATE CHANGE IN ENTHALPY

	deltah = mf*cp*deltat + mm*(cm*deltat + 
     *		(pres(i)-0.1013e+06)/rhom)

C	4.  CALCULATE MAXIMUM THEORETICAL VELOCITY

	if (deltah.ge.0.) then
	  vmax = vel(i) + sqrt(2.*deltah)
	 else
	  vmax = vel(i) - sqrt(-2.*deltah)
	end if

	write (6,1432)  temp2c, deltat, deltah, vmax
1432	format(/,5x,'AFTER ISENTROPIC EQUILIBRATION TO 1 ATM PRESSURE:',/,
     *		  10x,' final temperature = ',f7.2,' deg. C',/,
     *		  10x,' temperature change = ',f7.3,' deg. K',/,
     *		  10x,' enthalpy change = ',e12.4,' J/kg',/,
     *		  10x,' max. theoretical velocity = ',f9.2,' m/s',/)

	return
	end