*** supcrt96 - Modified from supcrt92 to use the Holland-Powell heat *** capacity regression equation in addition to Maier-Kelly. *** ALL properly formatted sequential-access databases are *** forwards compatible with Supcrt96+Cprons96. These changes *** were made in 1996, with further increases in array sizes *** in 2005 and 2008. -J.Palandri *** *** supcrt92 - Calculates the standard molal thermodynamic properties *** of reactions among minerals, gases, and aqueous species *** using equations and data given by Helgeson et al. (1978), *** Tanger and Helgeson (1988), Shock and Helgeson *** (1988, 1990), Shock et al. (1989, 1991), Johnson and *** Norton (1991), Johnson et al. (1991), and Sverjensky *** et al. (1991). *** ************************************************************************ *** *** Author: James W. Johnson *** Earth Sciences Department, L-219 *** Lawrence Livermore National Laboratory *** Livermore, CA 94550 *** johnson@s05.es.llnl.gov *** *** Abandoned: 13 November 1991 *** ************************************************************************ *** *** Changes Feb-Apr 05. Modify to run up to 400 reactions and up to 300 *** uneven increments. Due to increasing array dimensions, this version *** will not run on 16-bit systems. *** -MAXRXN from 10 to 400 (max reactions in .rxn file) *** -MAXINC from 21 to 300 (max increments, 2nd indep state *** property in the con file, >= MAXODD) *** -MAXODD from 21 to 300 (max # T-P coordinates, non *** uniform increments, <= MAXINC) *** -MAXISO from 11 to 21 (max # of isopleths in con file) *** -13*MAXISO*MAXINC = 3575 to 81900 *** - 2*MAXISO*MAXINC = 550 to 12600 *** *** 13*MAXISO*MAXINC = 81900 *** ***DATA dsvar, Vw, bew, alw, dalw, Sw, Cpw, Hw, Gw, Zw, Qw, Yw, Xw *** *JP 1 / 3003*0.0d0 / *** 1 / 81900*0.0d0 / *** *** 2*MAXISO*MAXINC = 12600 *** *JP DATA lvdome, H2Oerr / 462*.FALSE. / *** DATA lvdome, H2Oerr / 12600*.FALSE. / *** Add capability of output tab file (tabf) with T, P, log K, DG, DH *** only, in columns (J.Palandri). *** -Add integer variable OUTFLG: 1 = normal output *** 2 = T, P, log K, DG, DH only *** -Computes TEMP(K) as well as TEMP(degC) for option 2. *** -Remove some blank lines from tab file (tabf). *** Changes Jan 2008. Modify to run up to 900 uneven increments. *** (J.Palandri). *** -MAXINC from 300 to 900 (max increments, 2nd indep state prop in the con file, >= MAXODD) *** -MAXODD from 300 to 900 (max # T-P coordinates, non-uniform increments, <= MAXINC) *** -13*MAXISO*MAXINC = 81900 to 245700 *** - 2*MAXISO*MAXINC = 12600 to 37800 *** *** 13*MAXISO*MAXINC = 81900 *** ***DATA dsvar, Vw, bew, alw, dalw, Sw, Cpw, Hw, Gw, Zw, Qw, Yw, Xw *** *JP 1 / 81900*0.0d0 / *** 1 / 245700*0.0d0 / *** *** 2*MAXISO*MAXINC = 12600 *** *JP DATA lvdome, H2Oerr / 12600*.FALSE. / *** DATA lvdome, H2Oerr / 37800*.FALSE. / *** Changes Oct 2024. Modify to run up to 3000 uneven increments. *** -MAXINC from 900 to 3000 (max increments, 2nd indep state property in the con file, >= MAXODD) *** -MAXODD from 900 to 3000 (max # T-P coordinates, non-uniform increments, <= MAXINC) *** *** Array initializations, in BLOCK DATA consts, near line 220 *** -13*MAXISO*MAXINC = 13*21*3000 = 81900 *** - 2*MAXISO*MAXINC = 2*21*3000 = 126000 *** *** 13*MAXISO*MAXINC = 81900 *** ***DATA dsvar, Vw, bew, alw, dalw, Sw, Cpw, Hw, Gw, Zw, Qw, Yw, Xw *** *JP 1 / 81900*0.0d0 / !300 incr *** *JP 1 / 245700*0.0d0 / !900 incr *** *jp 1 / 764400*0.0d0 / !2800 incr *** 1 / 819000*0.0d0 / !3000 incr *** *** 2*MAXISO*MAXINC = 12600 *** *JP DATA lvdome, H2Oerr / 12600*.FALSE. / !300 incr *** *JP DATA lvdome, H2Oerr / 37800*.FALSE. / !900 incr *** *jp DATA lvdome, H2Oerr / 117600*.FALSE. / !2800 incr *** DATA lvdome, H2Oerr / 126000*.FALSE. / !3000 incr ************************************************************************ PROGRAM supcrt PARAMETER (NPLOTF = 8) LOGICAL wetrun, unirun INTEGER reac, rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), *JP Added integer variable outflg is a runtime option switch to select *JP either standard output, or output formatted for post processing *JP into SOLTHERM records 1 outflg COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg SAVE CALL banner CALL readin(nreac,wetrun,unirun) WRITE(wterm,10) 10 FORMAT(/,' execution in progress ... ',/) IF (wetrun) THEN WRITE(wterm,20) 20 FORMAT(' calculating H2O properties ...',/) CALL getH2O(unirun) END IF CALL tabtop DO 30 reac = 1,nreac WRITE(wterm,40) reac, nreac 40 FORMAT(' calculating properties for reaction ',i3, 1 ' of ',i3,' ...') CALL getmgi(reac) CALL wrtrxn(reac) 30 CALL runrxn(reac,wetrun) WRITE(wterm,50) 50 FORMAT(/,' ... execution completed.',/) END ******************************************************************** *** banner - Write program banner to the terminal screen. SUBROUTINE banner PARAMETER (NPLOTF = 8) INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), outflg COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg SAVE WRITE(wterm,10) 10 FORMAT(/,5x, ' Welcome to SUPCRT92 Version 1.1', 1 /,5x, ' Author: James W. Johnson', 2 /,5x, ' Abandoned: 13 November 1991', + //,5x,' Modified 1996, Apr-May 2005, May 2008', + /,5x, ' This version of SUPCRT has been modified to', + /,5x, ' use the four-term heat capacity equation of', + /,5x, ' Holland and Powell, in addition to that of', + /,5x, ' Maier-Kelly, with the requisite DPRONS database.' + /,5x, ' Selected array dimensions have been increased.', + /,5x, ' Modifications by J. Palandri; call it V.1.96', + /,5x, ' Abandoned: 19 May 2005',/) END ******************************************************************** *** consts - Constants BLOCK DATA consts IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXISO = 21, MAXINC = 3000, NPLOTF = 8) INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 tempf, mapiso(2,3), mapinc(2,3), mapv3(2,3), 2 rec1m1, rec1m2, rec1m3, rec1m4, rec1aa, rec1gg, 3 outflg DOUBLE PRECISION mwH2O, satmin(2) DOUBLE PRECISION dsvar(MAXINC,MAXISO), Vw(MAXINC,MAXISO), 1 bew(MAXINC,MAXISO), alw(MAXINC,MAXISO), 2 dalw(MAXINC,MAXISO), Sw(MAXINC,MAXISO), 3 Cpw(MAXINC,MAXISO), Hw(MAXINC,MAXISO), 4 Gw(MAXINC,MAXISO), Zw(MAXINC,MAXISO), 5 Qw(MAXINC,MAXISO), Yw(MAXINC,MAXISO), 6 Xw(MAXINC,MAXISO) LOGICAL lvdome(MAXINC,MAXISO), H2Oerr(MAXINC,MAXISO), 1 EQ3run, lv1bar CHARACTER*4 incvar(2,3) CHARACTER*10 isov(2,3), incv(2,3), var3(2,3), isosat(2) CHARACTER*12 isovar(2,3) CHARACTER*20 namecf, namerf, nametf, namepf(NPLOTF) COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /io2/ tempf COMMON /stvars/ isosat, isovar, incvar COMMON /TPDmap/ mapiso, mapinc, mapv3 COMMON /headmp/ isov, incv, var3 COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr COMMON /rlimit/ nmin1, nmin2, nmin3, nmin4, ngas, naqs, 1 rec1m1, rec1m2, rec1m3, rec1m4, rec1gg, rec1aa COMMON /tranm2/ ntrm2 COMMON /aqscon/ eta, theta, psi, anion, cation, gref COMMON /qtzcon/ aa, ba, ca, VPtTta, VPrTtb, Stran COMMON /satend/ satmin COMMON /defval/ DPMIN, DPMAX, DPINC, DTMIN, DTMAX, DTINC, 1 DTSMIN, DTSMAX, DTSINC COMMON /null/ XNULLM, XNULLA COMMON /badtd/ lvdome, H2Oerr COMMON /fnames/ namecf, namerf, nametf, namepf COMMON /EQ36/ EQ3run COMMON /lv1b/ lv1bar COMMON /H2Ogrd/ dsvar, Vw, bew, alw, dalw, Sw, Cpw, Hw, Gw, 1 Zw, Qw, Yw, Xw COMMON /H2Oss/ Dwss, Vwss, bewss, alwss, dalwss, Swss, 1 Cpwss, Hwss, Gwss, Zwss, Qwss, Ywss, Xwss SAVE DATA EQ3run, lv1bar / 2*.FALSE. / *** 8 = NPLOTF DATA namepf / 8*' ' / *** 13*MAXISO*MAXINC = 13 * 21 * 3000 = 819000 DATA dsvar, Vw, bew, alw, dalw, Sw, Cpw, Hw, Gw, Zw, Qw, Yw, Xw *jp 1 / 81900*0.0d0 / ! 300 incr *JP 1 / 245700*0.0d0 / ! 900 incr *jp 1 / 764400*0.0d0 / !2800 incr 1 / 819000*0.0d0 / !3000 increms *** 2*MAXISO*MAXINC = 2 * 21 * 3000 = 126000 *jp DATA lvdome, H2Oerr / 12600*.FALSE. / *JP DATA lvdome, H2Oerr / 37800*.FALSE. / *jp DATA lvdome, H2Oerr / 117600*.FALSE. / DATA lvdome, H2Oerr / 126000*.FALSE. / DATA Dwss, Vwss, bewss, alwss, dalwss, Swss, 1 Cpwss, Hwss, Gwss, Zwss, Qwss, Ywss, Xwss / 13*0.0d0 / DATA XNULLM, XNULLA / 999999.0d0, 999.0d0 / DATA DPMIN, DPMAX, DPINC / 500.0d0, 5000.0d0, 500.0d0 / DATA DTMIN, DTMAX, DTINC / 0.0d0, 1000.0d0, 100.0d0 / DATA DTSMIN, DTSMAX, DTSINC / 0.0d0, 350.0d0, 25.0d0 / DATA satmin / 0.01d0, 0.006117316772d0 / DATA aa, ba, ca / 0.549824d3, 0.65995d0, -0.4973d-4 / DATA VPtTta, VPrTtb, Stran / 0.23348d2, 0.2372d2, 0.342d0 / DATA eta, theta, psi / 0.166027d6, 0.228d3, 0.26d4 / DATA anion, cation, gref / 0.0d0, 0.94d0, 0.0d0 / DATA mwH2O, R / 18.0152d0, 1.9872d0 / DATA Pref, Tref / 0.1d1, 0.29815d3 / *** ZPrTr, YPrTr calculated in SUBR getH2O as f(epseqn) DATA rterm, wterm, iconf, reacf, pronf, tabf, tempf 1 / 5, 6, 40, 41, 42, 43, 44 / *** 8 = NPLOTF DATA plotf / 61, 62, 63, 64, 65, 66, 67, 68 / DATA isovar / 'CHORES(g/cc)', 'BARS(bars) ', 3*'THERMS(degC)', 1 'BARS(bars) ' / DATA incvar / 2*'TEMP', 'DENS' , 2*'PRES', 'TEMP' / DATA isosat / 'TEMP(degC)', 'PRES(bars)' / DATA isov / 'DH2O(g/cc)', 'PRES(bars)', 3*'TEMP(degC)', 1 'PRES(bars)' / DATA incv / 2*'TEMP(degC)', 'DH2O(g/cc)', 'PRES(bars)', 1 'PRES(bars)', 'TEMP(degC)' / DATA var3 / 'PRES(bars)', 'DH2O(g/cc)', 'PRES(bars)', 1 3*'DH2O(g/cc)' / DATA mapiso / 3, 2, 1, 1, 1, 2 / DATA mapinc / 1, 1, 3, 2, 2, 1 / DATA mapv3 / 2, 3, 2, 3, 4, 4 / END ************************************************************************ *** readin - Open user-specified, direct-access data file (STOP if none *** can be located); open/read or create[/store] an input file *** containing i/o specifications and state conditions; *** open/read line 1 of an existing file containing reaction *** titles and stoichiometries or create[/store] such a file *** in its entirety. SUBROUTINE readin(nreac,wetrun,unirun) LOGICAL wetrun, wetcon, wetrxn, unirun, getdf SAVE IF (.NOT. getdf()) STOP CALL getcon(wetcon,unirun) CALL getrxn(nreac,wetrxn) wetrun = (wetcon) .OR. (wetrxn) CALL getout END ************************************************************************ *** getdf - Returns .TRUE. if an appropriate direct-access *** data file can be opened; otherwise returns .FALSE. LOGICAL FUNCTION getdf() PARAMETER (MAXTRY = 5, NPLOTF = 8) CHARACTER*1 ans CHARACTER*20 pfname LOGICAL openf INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), try, 1 rec1m1, rec1m2, rec1m3, rec1m4, rec1gg, rec1aa, outflg COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /rlimit/ nmin1, nmin2, nmin3, nmin4, ngas, naqs, 1 rec1m1, rec1m2, rec1m3, rec1m4, rec1gg, rec1aa COMMON /dapron/ pfname SAVE 1 WRITE(wterm,10) 10 FORMAT(/,' would you like to use the default thermodynamic' 1 ,' database, dpronshp.dat? (y/n)',/) READ(rterm,20) ans 20 FORMAT(a1) IF ((ans .NE. 'y') .AND. (ans .NE. 'Y') .AND. 1 (ans .NE. 'n') .AND. (ans .NE. 'N')) THEN GO TO 1 END IF IF ((ans .EQ. 'y') .OR. (ans .EQ. 'Y')) THEN pfname = 'dpronshp.dat' ELSE WRITE(wterm,30) 30 FORMAT(/,' specify filename for thermodynamic database: ',/) READ(rterm,40) pfname 40 FORMAT(a20) END IF try = 0 *JP* 2 IF (openf(wterm,pronf,pfname,1,2,1,90)) THEN *JP* Change record length 90 to 104 to accomodate the fourth *JP* heat capacity coefficient. 2 IF (openf(wterm,pronf,pfname,1,2,1,104)) THEN READ(pronf,50,REC=1) nmin1, nmin2, nmin3, nmin4, 1 ngas, naqs * 50 FORMAT(6(1x,i4)) 50 FORMAT(6(i5)) READ(pronf,50,REC=2) rec1m1, rec1m2, rec1m3, rec1m4, 1 rec1gg, rec1aa getdf = .TRUE. RETURN ELSE try = try + 1 IF (try .LT. MAXTRY) THEN *** prompt for alternative file *** WRITE(wterm,60) pfname 60 FORMAT(/,' Cannot find ',a20, 1 /,' enter correct filename: ',/) READ(rterm,40) pfname GO TO 2 ELSE *** give up *** WRITE(wterm,70) 70 FORMAT(/,' I am tired of looking for this file;', 1 /,' please do the legwork yourself!', 2 //,' Bye for now ...',/) getdf = .FALSE. RETURN END IF END IF END ************************************************************************ *** getcon - Open/read or create[/store] an input (CON) file that *** contains i/o specifications and state conditions. SUBROUTINE getcon(wetcon,unirun) PARAMETER (NPLOTF = 8) LOGICAL wetcon, unirun INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), outflg COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg SAVE 1 WRITE(wterm,10) 10 FORMAT(/,' choose file option for specifying', 1 ' reaction-independent parameters: ', 1 /,' 1 = select one of three default files', 2 /,' 2 = select an existing non-default file', 3 /,' 3 = build a new file:',/) READ(rterm,*) ifopt IF ((ifopt .LT. 1) .OR. (ifopt .GT. 3)) GO TO 1 IF (ifopt .EQ. 1) THEN unirun = .FALSE. CALL defaul(wetcon) RETURN END IF IF (ifopt .EQ. 2) THEN CALL readcf(wetcon,unirun) ELSE CALL makecf(wetcon,unirun) END IF END ************************************************************************ *** defaul - Set default options / state conditions. SUBROUTINE defaul(wetcon) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXOdd = 3000, NPLOTF = 8) DOUBLE PRECISION isomin, isomax, isoinc, Kmin, Kmax, Kinc, 1 oddv1(MAXODD), oddv2(MAXODD) INTEGER rterm, wterm, reacf, pronf, tabf, 1 plotf(NPLOTF), univar, useLVS, epseqn, geqn, 2 outflg LOGICAL wetcon, EQ3run, savecf, saverf COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /grid/ isomin, isomax, isoinc, v2min, v2max, v2inc, 1 oddv1, oddv2, Kmin, Kmax, Kinc, niso, nv2, nlogK COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /defval/ DPMIN, DPMAX, DPINC, DTMIN, DTMAX, DTINC, 1 DTSMIN, DTSMAX, DTSINC COMMON /EQ36/ EQ3run COMMON /saveif/ savecf, saverf SAVE univar = 0 noninc = 0 useLVS = 1 epseqn = 4 geqn = 3 EQ3run = .FALSE. savecf = .FALSE. ***** prompt for / read isat ***** 1 WRITE(wterm,10) 10 FORMAT(/,' input solvent phase region', 1 /,' 1 = one-phase region ', 2 /,' 2 = liq-vap saturation curve:', 3 /,' 3 = EQ3/6 one-phase/sat grid:',/) READ(rterm,*) isat IF ((isat .LT. 1) .OR. (isat .GT. 3)) THEN GO TO 1 ELSE isat = isat - 1 wetcon = (isat .EQ. 1) END IF IF (isat .EQ. 0) THEN iopt = 2 iplot = 1 isomin = DPMIN isomax = DPMAX isoinc = DPINC niso = 1 + NINT((isomax - isomin)/isoinc) v2min = DTMIN v2max = DTMAX v2inc = DTINC nv2 = 1 + NINT((v2max - v2min)/v2inc) RETURN END IF IF (isat .EQ. 1) THEN iopt = 1 iplot = 3 v2min = DTSMIN v2max = DTSMAX v2inc = DTSINC nv2 = 1 + NINT((v2max - v2min)/v2inc) isomin = 0.0d0 isomax = 0.0d0 isoinc = 0.0d0 niso = 1 RETURN END IF IF (isat .EQ. 2) THEN isat = 0 iopt = 2 iplot = 2 niso = 0 nv2 = 0 noninc = 8 EQ3run = .TRUE. oddv1(1) = 0.01d0 oddv1(2) = 25.00d0 oddv1(3) = 60.00d0 oddv1(4) = 100.00d0 oddv1(5) = 150.00d0 oddv1(6) = 200.00d0 oddv1(7) = 250.00d0 oddv1(8) = 300.00d0 oddv2(1) = 1.01322d0 oddv2(2) = 1.01322d0 oddv2(3) = 1.01322d0 oddv2(4) = 1.01322d0 oddv2(5) = 4.75717d0 oddv2(6) = 15.53650d0 oddv2(7) = 39.73649d0 oddv2(8) = 85.83784d0 RETURN END IF END ************************************************************************ *** readcf - Read options / state conditions (CON) file. SUBROUTINE readcf(wetcon,unirun) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXISO = 21, MAXINC = 3000, MAXOdd = 3000, 1 NPLOTF = 8, TOL = 1.0d-6) CHARACTER*1 TP(2) CHARACTER*20 namecf, namerf, nametf, namepf(NPLOTF) LOGICAL openf, wetcon, unirun, savecf, saverf DOUBLE PRECISION isomin, isomax, isoinc, Kmin, Kmax, Kinc, 1 oddv1(MAXODD), oddv2(MAXODD) INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 univar, useLVS, epseqn, geqn, outflg COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /grid/ isomin, isomax, isoinc, v2min, v2max, v2inc, 1 oddv1, oddv2, Kmin, Kmax, Kinc, niso, nv2, nlogK COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /fnames/ namecf, namerf, nametf, namepf COMMON /saveif/ savecf, saverf SAVE DATA TP / 'T', 'P' / 1 WRITE(wterm,10) 10 FORMAT(/,' specify file name:',/) READ(rterm,20) namecf 20 FORMAT(a20) IF (.NOT. openf(wterm,iconf,namecf,1,1,1,132)) GO TO 1 savecf = .TRUE. ***** skip first 4 comment lines READ(iconf,21) 21 FORMAT(///) ********************************************************** *** READ and hardwire statements for distribution version READ(iconf,*) isat, iopt, iplot, univar, noninc useLVS = 1 epseqn = 4 geqn = 3 *** READ statement for development version * READ(iconf,*) isat, iopt, iplot, univar, noninc, * 1 useLVS, epseqn, geqn ********************************************************** *** insert validity checker for /icon/ *** variables here if desired later wetcon = (isat .EQ. 1) .OR. (iopt .EQ. 1) unirun = (univar .EQ. 1) IF (noninc .NE. 0) THEN *** univar = 0 *** read non-incremental state conditions IF (noninc .GT. MAXODD) THEN WRITE(wterm,131) noninc, MAXODD WRITE(tabf,131) noninc, MAXODD 131 FORMAT(/,' Number of specified odd-increment pairs ' 1 ,'(',i3,') exceeds MAXODD (',i3,').', 2 /,' Revise specifications.') STOP END IF DO 30 i = 1,noninc IF (isat .EQ. 1) THEN READ(iconf,*) oddv1(i) ELSE READ(iconf,*) oddv1(i), oddv2(i) END IF 30 CONTINUE RETURN END IF IF (isat .EQ. 0) THEN READ(iconf,*) isomin, isomax, isoinc IF (isomin .EQ. isomax) THEN niso = 1 ELSE IF (isoinc .EQ. 0.0d0) THEN WRITE(wterm,935) WRITE(tabf,935) 935 FORMAT(/,' Ill-defined ', 1 ' min,max,increment trio',/, 2 ' Revise specifications.') STOP END IF fpniso = 1.0d0 + ((isomax - isomin)/isoinc) niso = NINT(fpniso) IF (DABS(fpniso-DBLE(niso)) .GT. TOL) THEN WRITE(wterm,935) WRITE(tabf,935) STOP END IF END IF IF (niso .GT. MAXISO) THEN WRITE(wterm,31) niso, MAXISO WRITE(tabf,31) niso, MAXISO 31 FORMAT(/,' Number of specified isopleths (',i4,')' 1 ,' exceeds MAXISO (',i3,').', 2 /,' Revise specifications.') STOP END IF ELSE READ(iconf,*) v2min, v2max, v2inc IF (v2min .EQ. v2max) THEN nv2 = 1 ELSE IF (v2inc .EQ. 0.0d0) THEN WRITE(wterm,935) WRITE(tabf,935) STOP END IF fpnv2 = 1.0d0 + ((v2max - v2min)/v2inc) nv2 = NINT(fpnv2) IF (DABS(fpnv2-DBLE(nv2)) .GT. TOL) THEN WRITE(wterm,935) WRITE(tabf,935) STOP END IF END IF IF (nv2 .GT. MAXINC) THEN WRITE(wterm,32) nv2, MAXINC WRITE(tabf,32) nv2, MAXINC 32 FORMAT(/,' Number of specified increments ' 1 ,'(',i3,') exceeds MAXINC (',i3,').', 2 /,' Revise specifications.') STOP END IF niso = 1 isomin = 0.0d0 isomax = 0.0d0 isoinc = 0.0d0 RETURN END IF IF (univar .EQ. 1) THEN *** univariant curve option enabled READ(iconf,*) Kmin, Kmax, Kinc IF (Kmin .EQ. Kmax) THEN nlogK = 1 ELSE IF (Kinc .EQ. 0.0d0) THEN WRITE(wterm,935) WRITE(tabf,935) STOP END IF fplK = 1.0d0 + ((Kmax - Kmin)/Kinc) nlogK = NINT(fplK) IF (DABS(fplK-DBLE(nlogK)) .GT. TOL) THEN WRITE(wterm,935) WRITE(tabf,935) STOP END IF END IF READ(iconf,*) v2min, v2max IF (v2min .LT. v2max) THEN v2inc = 0.0d0 ELSE WRITE(wterm,152) TP(iplot), TP(iplot) 152 FORMAT(/,1x,a1,'min >= ',a1,'max ', 1 /,1x,' revise specifications') STOP END IF ELSE *** univariant curve option disabled READ(iconf,*) v2min, v2max, v2inc IF (v2min .EQ. v2max) THEN nv2 = 1 ELSE IF (v2inc .EQ. 0.0d0) THEN WRITE(wterm,935) WRITE(tabf,935) STOP END IF fpnv2 = 1.0d0 + ((v2max - v2min)/v2inc) nv2 = NINT(fpnv2) IF (DABS(fpnv2-DBLE(nv2)) .GT. TOL) THEN WRITE(wterm,935) WRITE(tabf,935) STOP END IF END IF IF (nv2 .GT. MAXINC) THEN WRITE(wterm,32) nv2, MAXINC WRITE(tabf,32) nv2, MAXINC STOP END IF END IF END ************************************************************************ *** makecf - Prompt for and create options / state conditions *** (CON) file. SUBROUTINE makecf(wetcon,unirun) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXISO = 21, MAXINC = 3000, MAXOdd = 3000, 1 NPLOTF = 8, TOL = 1.0d-6) CHARACTER*1 ptype2(2), TP(2), ans CHARACTER*4 incvar(2,3) CHARACTER*6 ptype1(2) CHARACTER*10 isov(2,3), incv(2,3), var3(2,3), isosat(2) CHARACTER*12 isovar(2,3) CHARACTER*20 namecf, namerf, nametf, namepf(NPLOTF) LOGICAL openf, wetcon, unirun, savecf, saverf DOUBLE PRECISION isomin, isomax, isoinc, Kmin, Kmax, Kinc, 1 oddv1(MAXODD), oddv2(MAXODD) INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 univar, useLVS, epseqn, geqn, outflg COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /grid/ isomin, isomax, isoinc, v2min, v2max, v2inc, 1 oddv1, oddv2, Kmin, Kmax, Kinc, niso, nv2, nlogK COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /stvars/ isosat, isovar, incvar COMMON /headmp/ isov, incv, var3 COMMON /fnames/ namecf, namerf, nametf, namepf COMMON /saveif/ savecf, saverf SAVE DATA TP / 'T', 'P' / DATA ptype2 / 'D', 'P' / DATA ptype1 / 'CHORIC', 'BARIC ' / ***** prompt for / read isat ***** 1 WRITE(wterm,10) 10 FORMAT(/,' specify solvent phase region ', 1 /,' 1 = one-phase region ', 2 /,' 2 = liq-vap saturation curve:',/) READ(rterm,*) isat IF ((isat .NE. 1) .AND. (isat .NE. 2)) THEN GO TO 1 ELSE isat = isat - 1 END IF ***** prompt for / read iopt ***** 2 IF (isat .EQ. 0) THEN WRITE(wterm,20) 20 FORMAT(/,' specify independent state variables: ', 1 /,' 1 = temperature (degC), density[H2O] (g/cc) ', 2 /,' 2 = temperature (degC), pressure (bars)',/) ELSE WRITE(wterm,30) 30 FORMAT(/,' specify independent liq-vap saturation variable:', 1 /,' 1 = temperature (degC)', 2 /,' 2 = pressure (bars)',/) END IF READ(rterm,*) iopt IF ((iopt .NE. 1) .AND. (iopt .NE. 2)) GO TO 2 wetcon = (isat .EQ. 1) .OR. (iopt .EQ. 1) IF (isat .EQ. 1) THEN ***** saturation curve option enabled ***** ***** set univar and iplot ***** univar = 0 iplot = 3 ***** prompt for / read noninc ***** 3 WRITE(wterm,40) 40 FORMAT(/,' specify table-increment option: ', 1 /,' 1 = calculate tables having uniform increments', 2 /,' 2 = calculate tables having unequal increments',/) READ(rterm,*) noninc IF ((noninc .NE. 1) .AND. (noninc .NE. 2)) THEN GO TO 3 ELSE noninc = noninc - 1 IF (noninc .EQ. 0) THEN ***** prompt for / read state condition range along ***** the saturation curve curve isopleth 444 WRITE(wterm,50) isosat(iopt) 50 FORMAT(/,' specify ',a10, ' range:',/, 1 ' min, max, increment:' 1 ,/) READ(rterm,*) v2min, v2max, v2inc IF (v2max .GT. 373.917d0) THEN WRITE(wterm,899) v2max 899 FORMAT(/,' Maximum saturation temperature ', 1 '(',f4.0,') > critical temperature', 2 ' (373.917).', 3 /,' Revise specifications.') GO TO 444 END IF IF (v2min .EQ. v2max) THEN nv2 = 1 ELSE IF (v2inc .EQ. 0.0d0) THEN WRITE(wterm,935) 935 FORMAT(/,' Ill-defined ', 1 ' min,max,increment trio',/, 2 ' Revise specifications.') GO TO 444 END IF fpnv2 = 1.0d0 + ((v2max - v2min)/v2inc) nv2 = NINT(fpnv2) IF (DABS(fpnv2-DBLE(nv2)) .GT. TOL) THEN WRITE(wterm,935) GO TO 444 END IF IF (nv2 .GT. MAXINC) THEN WRITE(wterm,31) nv2, MAXINC 31 FORMAT(/,' Number of specified isopleths' 1 ,' (',i4,') exceeds MAXINC (',i3,').' 2 ,/,' Revise specifications.') GO TO 444 END IF END IF niso = 1 isomin = 0.0d0 isomax = 0.0d0 isoinc = 0.0d0 ELSE ***** prompt for / read [noninc] non-incremental state ***** ***** condition points along saturation curve ***** WRITE(wterm,60) isosat(iopt) 60 FORMAT(/,' specify liq-vap saturation ',a10, 1 ' values', 2 /,' one per line, concluding with a zero:',/) 4 READ(rterm,*) oddv1(noninc) IF ((oddv1(noninc) .NE. 0.0d0) .AND. 1 (noninc .LT. MAXODD)) THEN noninc = noninc + 1 GO TO 4 END IF IF (oddv1(noninc) .EQ. 0.0d0) THEN noninc = noninc - 1 ELSE WRITE(wterm,241) MAXODD 241 FORMAT(/,' Only ',i3,' coordinates separated', 1 ' by unequal increments',/,' can be', 2 ' processed during one SUPCRT92 execution',/) END IF END IF END IF ELSE ***** saturation curve option curve disabled ***** IF (iopt .EQ. 1) THEN univar = 0 ELSE ***** prompt for / read univar ***** 5 WRITE(wterm,70) 70 FORMAT(/,' would you like to use the univariant curve', 1 ' option;', 2 /,' i.e., calculate T(logK,P) or P(logK,T) ', 3 ' (y/n)',/) READ(rterm,75) ans 75 FORMAT(a1) IF ((ans .NE. 'y') .AND. (ans .NE. 'Y') .AND. 1 (ans .NE. 'n') .AND. (ans .NE. 'N')) THEN GO TO 5 END IF IF ((ans .EQ. 'y') .OR. (ans .EQ. 'Y')) THEN univar = 1 ELSE univar = 0 END IF END IF IF (univar .EQ. 0) THEN ***** univariant curve option disabled ***** ***** prompt for / read iplot ***** 6 WRITE(wterm,80) ptype1(iopt), ptype2(iopt) 80 FORMAT(/,' specify tablulation option:', 1 /,' 1 = calculate ISO',a6,'(T) tables, ', 2 /,' 2 = calculate ISOTHERMAL(',a1,') ', 3 'tables ',/) READ(rterm,*) iplot IF ((iplot .NE. 1) .AND. (iplot .NE. 2)) THEN GO TO 6 END IF ***** prompt for / read noninc ***** 7 WRITE(wterm,40) READ(rterm,*) noninc IF ((noninc .NE. 1) .AND. (noninc .NE. 2)) THEN GO TO 7 ELSE noninc = noninc - 1 END IF IF (noninc .EQ. 0) THEN ***** prompt for / read state condition ranges in one-phase region ***** 445 WRITE(wterm,100) isovar(iopt,iplot) 100 FORMAT(/,' specify ISO',a12, 1 /,' min, max, increment',/) READ(rterm,*) isomin, isomax, isoinc IF (isomin .EQ. isomax) THEN niso = 1 ELSE IF (isoinc .EQ. 0.0d0) THEN WRITE(wterm,935) GO TO 445 END IF fpniso = 1.0d0 + ((isomax - isomin)/isoinc) niso = NINT(fpniso) IF (DABS(fpniso-DBLE(niso)) .GT. TOL) THEN WRITE(wterm,935) GO TO 445 END IF END IF IF (niso .GT. MAXISO) THEN WRITE(wterm,31) niso, MAXISO GO TO 445 END IF 446 WRITE(wterm,110) incv(iopt,iplot) 110 FORMAT(/,' specify ',a10,' range', 1 /,' min, max, increment',/) READ(rterm,*) v2min, v2max, v2inc IF (v2min .EQ. v2max) THEN nv2 = 1 ELSE IF (v2inc .EQ. 0.0d0) THEN WRITE(wterm,935) GO TO 446 END IF fpnv2 = 1.0d0 + ((v2max - v2min)/v2inc) nv2 = NINT(fpnv2) IF (DABS(fpnv2-DBLE(nv2)) .GT. TOL) THEN WRITE(wterm,935) GO TO 446 END IF END IF IF (nv2 .GT. MAXINC) THEN WRITE(wterm,32) nv2, MAXINC 32 FORMAT(/,' Number of specified increments' 1 ,' (',i4,') exceeds MAXINC (',i3,').', 2 /,' Revise specifications.') GO TO 446 END IF ELSE ***** prompt for / read [noninc] non-incremental state ***** ***** condition points in the one-phase region ***** WRITE(wterm,120) isov(iopt,iplot), incv(iopt,iplot) 120 FORMAT(/,' specify ',a10,', ',a10,' values; ', 1 /,' one pair per line, concluding with 0,0:',/) 8 READ(rterm,*) oddv1(noninc), oddv2(noninc) IF ((oddv1(noninc) .NE. 0.0d0) .AND. 1 (noninc .LT. MAXODD)) THEN noninc = noninc + 1 GO TO 8 END IF IF (oddv1(noninc) .EQ. 0.0d0) THEN noninc = noninc - 1 ELSE WRITE(wterm,241) END IF END IF ELSE ***** univariant curve option enabled ***** ***** set noninc ***** noninc = 0 ***** prompt for / read iplot ***** 9 WRITE(wterm,130) 130 FORMAT(/,' specify univariant calculation option:', 1 /,' 1 = calculate T(logK,isobars), ', 2 /,' 2 = calculate P(logK,isotherms): ',/) READ(rterm,*) iplot IF ((iplot .NE. 1) .AND. (iplot .NE. 2)) THEN GO TO 9 END IF ***** prompt for / read state condition ranges in one-phase region ***** 447 WRITE(wterm,140) isovar(iopt,iplot) 140 FORMAT(/,' specify ISO',a12, 1 /,' min, max, increment ',/) READ(rterm,*) isomin, isomax, isoinc IF (isomin .EQ. isomax) THEN niso = 1 ELSE IF (isoinc .EQ. 0.0d0) THEN WRITE(wterm,935) GO TO 447 END IF fpniso = 1.0d0 + ((isomax - isomin)/isoinc) niso = NINT(fpniso) IF (DABS(fpniso-DBLE(niso)) .GT. TOL) THEN WRITE(wterm,935) GO TO 447 END IF END IF IF (niso .GT. MAXISO) THEN WRITE(wterm,31) niso, MAXISO GO TO 447 END IF 448 WRITE(wterm,150) 150 FORMAT(/,' specify logK range: ', 1 /,' Kmin, Kmax, Kincrement: ',/) READ(rterm,*) Kmin, Kmax, Kinc IF (Kmin .EQ. Kmax) THEN nlogK = 1 ELSE IF (Kinc .EQ. 0.0d0) THEN WRITE(wterm,935) GO TO 448 END IF fpnK = 1.0d0 + ((Kmax - Kmin)/Kinc) nlogK = NINT(fpnK) IF (DABS(fpnK-DBLE(nlogK)) .GT. TOL) THEN WRITE(wterm,935) GO TO 448 END IF END IF 449 WRITE(wterm,151) incv(iopt,iplot), 1 TP(iplot), TP(iplot) 151 FORMAT(/,' specify bounding ',a10,' range:', 1 /,1x,a1,'min, ',a1,'max: ',/) READ(rterm,*) v2min, v2max IF (v2min .LT. v2max) THEN v2inc = 0.0d0 ELSE WRITE(wterm,152) TP(iplot), TP(iplot) 152 FORMAT(/,1x,a1,'min >= ',a1,'max ', 1 /,1x,' revise specifications') GO TO 449 END IF END IF END IF *************************************************************** *** variable assignments for distribution version useLVS = 1 epseqn = 4 geqn = 3 *** select equation options for development version * CALL geteqn(useLVS,epseqn,geqn) *************************************************************** ***** set unirun ****** unirun = (univar .EQ. 1) ***** write input parameters to new file if desired ***** 16 WRITE(wterm,210) 210 FORMAT(/,' would you like to save these reaction-independent', 1 /,' parameters to a file (y/n):',/) READ(rterm,75) ans IF ((ans .NE. 'y') .AND. (ans .NE. 'Y') .AND. 1 (ans .NE. 'n') .AND. (ans .NE. 'N')) GO TO 16 savecf = ((ans .EQ. 'y') .OR. (ans .EQ. 'Y')) IF (savecf) THEN 17 WRITE(wterm,230) 230 FORMAT(/,' specify file name:',/) READ(rterm,240) namecf 240 FORMAT(a20) IF (.NOT. openf(wterm,iconf,namecf,2,1,1,132)) THEN GO TO 17 END IF ****************************************************************** WRITE(iconf,250) *** statement 250 for distribution versions 250 FORMAT(' Line 1 (free format):', 1 ' isat, iopt, iplot, univar, noninc') *** statement 250 for development versions *250 FORMAT(' Line 1 (free format): isat, iopt, iplot,', * 1 ' univar, noninc, useLVS, epseqn, geqn') ****************************************************************** IF (noninc .EQ. 0) THEN IF (isat .EQ. 1) THEN WRITE(iconf,251) 251 FORMAT(' Line 2 (free format): v2min, v2max, v2inc') WRITE(iconf,256) 256 FORMAT(66('*')) ELSE WRITE(iconf,249) 249 FORMAT(' Line 2 (free format): isomin, isomax, isoinc') END IF ELSE IF (isat .EQ. 1) THEN WRITE(iconf,252) noninc + 1 252 FORMAT(' Lines i=2..',i3, 1 ' (free format): oddv1(i)') ELSE WRITE(iconf,253) noninc + 1 253 FORMAT(' Lines i=2..',i3, 1 ' (free format): oddv1(i), oddv2(i)') END IF WRITE(iconf,256) END IF IF ((isat .EQ. 0) .AND. (noninc .EQ. 0)) THEN IF (univar .EQ. 0) THEN WRITE(iconf,254) 254 FORMAT(' Line 3 (free format):', 1 ' v2min, v2max, v2inc') ELSE WRITE(iconf,255) 255 FORMAT(' Line 3 (free format):', 1 ' Kmin, Kmax, Kinc') WRITE(iconf,259) 259 FORMAT(' Line 4 (free format):', 1 ' v2min, v2max') END IF END IF IF (univar .EQ. 0) THEN WRITE(iconf,256) END IF ************************************************************* *** WRITE statement for distribution version WRITE(iconf,350) isat, iopt, iplot, univar, noninc 350 FORMAT(5(1x,i3)) *** WRITE statement for development version * WRITE(iconf,350) isat, iopt, iplot, univar, noninc, * 1 useLVS, epseqn, geqn *350 FORMAT(8(1x,i3)) ************************************************************* IF (noninc .EQ. 0) THEN IF (isat .EQ. 1) THEN WRITE(iconf,*) v2min, v2max, v2inc ELSE WRITE(iconf,*) isomin, isomax, isoinc END IF ELSE DO 360 i = 1,noninc IF (isat .EQ. 1) THEN WRITE(iconf,*) oddv1(i) ELSE WRITE(iconf,*) oddv1(i), oddv2(i) END IF 360 CONTINUE END IF IF ((isat .EQ. 0) .AND. (noninc .EQ. 0)) THEN IF (univar .EQ. 0) THEN WRITE(iconf,*) v2min, v2max, v2inc ELSE WRITE(iconf,*) Kmin, Kmax, Kinc WRITE(iconf,*) v2min, v2max END IF END IF END IF END ************************************************************************ *** geteqn - prompt for / read useLVS, epseqn, geqn. SUBROUTINE geteqn(useLVS,epseqn,geqn) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPLOTF = 8) CHARACTER*1 ans INTEGER useLVS, epseqn, geqn, rterm, wterm, reacf, 1 pronf, tabf, plotf(NPLOTF), outflg COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg SAVE 11 WRITE(wterm,160) 160 FORMAT(/,' would you like to use the Levelt Sengers et al. (1983)' 1 ,/,' equation of state for H2O in the critical region (y/n)' 2 ,/) READ(rterm,165) ans 165 FORMAT(a1) IF ((ans .NE. 'y') .AND. (ans .NE. 'Y') .AND. 1 (ans .NE. 'n') .AND. (ans .NE. 'N')) GO TO 11 IF ((ans .EQ. 'y') .OR. (ans .EQ. 'Y')) THEN useLVS = 1 ELSE useLVS = 0 END IF 12 WRITE(wterm,170) 170 FORMAT(/,' specify dielectric option: ', 1 /,' 1 = use Helgeson-Kirkham (1974) equation', 2 /,' 2 = use Pitzer (1983) equation', 3 /,' 3 = use Uematsu-Franck (1980) equation', 4 /,' 4 = use Johnson-Norton (1991) equation', 5 /,' 5 = use Archer-Wang (1990) equation',/) READ(rterm,*) epseqn IF ((epseqn .LT. 1) .OR. (epseqn .GT. 5)) GO TO 12 13 WRITE(wterm,180) 180 FORMAT(/,' specify g-function option', 1 /,' 1 = use Tanger-Helgeson (1988) equation', 2 /,' 2 = use Shock et al. (in prep.) equation', 3 /,' 3 = use modified Shock et al. equation',/) READ(rterm,*) geqn IF ((geqn .LT. 1) .OR. (geqn .GT. 3)) GO TO 13 END ************************************************************************ *** getrxn - Open and read an existing reaction (RXN) file or *** prompt for, create, [and save] a new reaction file. SUBROUTINE getrxn(nreac,wetrxn) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPLOTF = 8) LOGICAL wetrxn INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), outflg COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg SAVE 1 WRITE(wterm,10) 10 FORMAT(/,' choose file option for specifying reactions ', 1 /,' 1 = use an existing reaction file', 2 /,' 2 = build a new reaction file:',/) READ(rterm,*) ifopt IF ((ifopt .NE. 1) .AND. (ifopt .NE. 2)) GO TO 1 IF (ifopt .EQ. 1) THEN CALL readrf(nreac,wetrxn) ELSE CALL makerf(nreac,wetrxn) END IF END ******************************************************************** *** parse - If the first non-blank substring of the input character *** string (chrstr) represents a valid integer or *** non-exponential floating-point number, parse returns *** .TRUE. and converts this first substring into the *** corresponding real number (r8num), then transfers the *** second such subset into a CHAR*20 variable (name); *** otherwise, parse returns .FALSE. LOGICAL FUNCTION parse(chrstr,r8num,name) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXLEN = 20) CHARACTER*(*) chrstr CHARACTER*20 numstr, name LOGICAL sign, deci INTEGER chrlen, tempf COMMON /io2/ tempf SAVE *** calculate length of chrstr *** chrlen = LEN(chrstr) *** read through leading blanks *** nblank = 0 DO 10 i = 1,chrlen IF (chrstr(i:i) .EQ. ' ') THEN nblank = nblank + 1 ELSE GO TO 2 END IF 10 CONTINUE *** initialize local variables *** 2 sign = .FALSE. deci = .FALSE. *** extract numerical string (integer or *** non-exponentiated floating-point numbers only) numlen = 0 DO 20 i = nblank+1,chrlen IF (chrstr(i:i) .EQ. ' ') THEN IF (((numlen .EQ. 1) .AND. (sign .OR. deci)) .OR. 1 ((numlen .EQ. 2) .AND. (sign .AND. deci))) THEN parse = .FALSE. RETURN ELSE *** valid integer or non-exponentiated floating-point *** number has been read; pad numerical string with blanks; *** read numerical numerical character string numstr into *** real*8 variable r8num; jump below to read in name. parse = .TRUE. DO 30 j = numlen+1,MAXLEN numstr(j:j) = ' ' 30 CONTINUE *** the following CHARACTER-to-DOUBLE PRECISION conversion is acceptable *** to most compilers ... but not all * READ(numstr,*) r8num *** hence, portability considerations require use of the following *** procedure, which is equivalent and universally acceptable *** ... albeit ugly OPEN(UNIT=tempf,FILE='zero.dat') WRITE(tempf,*) numstr BACKSPACE(tempf) READ(tempf,*) r8num CLOSE(UNIT=tempf) GO TO 3 END IF END IF IF ((chrstr(i:i) .EQ. '-') .OR. (chrstr(i:i) .EQ. '+')) THEN IF ((.NOT. sign) .AND. (numlen .EQ. 0)) THEN sign = .TRUE. numlen = numlen + 1 numstr(numlen:numlen) = chrstr(i:i) ELSE parse = .FALSE. RETURN END IF ELSE IF (chrstr(i:i) .EQ. '.') THEN IF (.NOT. deci) THEN deci = .TRUE. numlen = numlen + 1 numstr(numlen:numlen) = chrstr(i:i) ELSE parse = .FALSE. RETURN END IF ELSE IF ((chrstr(i:i) .GE. '0') .AND. 1 (chrstr(i:i) .LE. '9')) THEN numlen = numlen + 1 numstr(numlen:numlen) = chrstr(i:i) ELSE parse = .FALSE. RETURN END IF 20 CONTINUE *** read through blanks that separate the *** number string from the name string 3 DO 40 name1 = nblank+numlen+1,chrlen IF (chrstr(name1:name1) .NE. ' ') GO TO 4 40 CONTINUE *** transfer non-blank substring beginning *** at chrstr(name1:name1) into name 4 j = 0 DO 50 i = name1,chrlen IF (chrstr(i:i) .NE. ' ') THEN j = j + 1 name(j:j) = chrstr(i:i) ELSE IF (j .NE. 0) THEN *** valid non-blank substring has been read into *** CHAR*20 variable name; pad name with blanks; *** return GO TO 5 ELSE parse = .FALSE. RETURN END IF END IF 50 CONTINUE 5 DO 60 i = j+1,MAXLEN name(i:i) = ' ' 60 CONTINUE RETURN END ************************************************************************ *** getout - Prompt for and read names for output files. SUBROUTINE getout PARAMETER (NPLOTF = 8) LOGICAL openf, EQ3run CHARACTER*4 suffx(NPLOTF) CHARACTER*13 prefx2 CHARACTER*16 prefx1 CHARACTER*20 namecf, namerf, nametf, namepf(NPLOTF) INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 univar, useLVS, epseqn, geqn, xyplot, end, outflg COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /fnames/ namecf, namerf, nametf, namepf COMMON /plottr/ xyplot, end, nplots COMMON /EQ36/ EQ3run SAVE DATA suffx / '.kxy', '.gxy', '.hxy', '.sxy', 1 '.cxy', '.vxy', '.dxy', '.2xy' / 1 WRITE(wterm,10) 10 FORMAT(/,' specify name for tabulated output file:',/) READ(rterm,20) nametf 20 FORMAT(a20) IF (.NOT. openf(wterm,tabf,nametf,2,1,1,132)) THEN GO TO 1 END IF *JP___________ OUTFLG = 1 22 WRITE (wterm,25) 25 FORMAT (/,' specify option for tabulated output file:' 1 /,' 1 = Normal output' 2 /,' 2 = T, P, logK, DG, DH, and DS only',/) READ (*,*) OUTFLG IF ((OUTFLG.NE.1) .AND. (OUTFLG.NE.2)) GOTO 22 *JP___________ IF ((noninc .GT. 0) .AND. (.NOT. EQ3run)) THEN xyplot = 0 RETURN ELSE 2 WRITE(wterm,30) 30 FORMAT(/,' specify option for x-y plot files:', 1 /,' logK, G, H, S, Cp, and V of reaction: ', 1 /,' 1 = do not generate plot files ', 2 /,' 2 = generate plot files in generic format', 3 /,' 3 = generate plot files in KaleidaGraph format',/) READ(rterm,*) xyplot IF ((xyplot .LT. 1) .OR. (xyplot .GT. 3)) THEN GO TO 2 ELSE xyplot = xyplot - 1 END IF END IF IF (xyplot .EQ. 0) RETURN IF (xyplot .EQ. 1) THEN IF (EQ3run) THEN nplots = NPLOTF ELSE IF (univar .EQ. 1) THEN nplots = 1 ELSE nplots = (NPLOTF-1)+isat END IF END IF IF (univar .EQ. 1) THEN WRITE(wterm,35) 35 FORMAT(/,' specify prefix for name of x-y plot file;', 1 /,' suffix will be ".uxy"',/) ELSE WRITE(wterm,40) 40 FORMAT(/,' specify prefix for names of x-y plot files;', 1 /,' suffix will be ".[d,[2],k,g,h,s,c,v]xy"',/) END IF READ(rterm,50) prefx1 50 FORMAT(a16) DO 60 i = 1,LEN(prefx1) IF (prefx1(i:i) .EQ. ' ') THEN end = i-1 GO TO 65 END IF 60 CONTINUE 65 IF (univar .EQ. 1) THEN namepf(1)(1:end) = prefx1(1:end) namepf(1)(end+1:end+4) = '.uxy' ELSE DO 70 i = 1,nplots namepf(i)(1:end) = prefx1(1:end) namepf(i)(end+1:end+4) = suffx(i) 70 CONTINUE END IF RETURN END IF *** xyplot = 2 IF ((isat .EQ. 1) .OR. EQ3run) THEN nplots = 1 WRITE(wterm,80) 80 FORMAT(/,' specify prefix for names of x-y plot files;', 1 /,' suffix will be "R#.axy"',/) READ(rterm,90) prefx2 90 FORMAT(a13) ELSE IF (univar .EQ. 1) THEN nplots = 1 WRITE(wterm,100) 100 FORMAT(/,' specify prefix for names of x-y plot files;', 1 /,' suffix will be "R#.uxy"',/) READ(rterm,90) prefx2 ELSE nplots = NPLOTF-1 WRITE(wterm,110) 110 FORMAT(/,' specify prefix for names of x-y plot files;', 1 /,' suffix will be "R#.[d,[2],k,g,h,s,c,v]xy"',/) READ(rterm,90) prefx2 END IF END IF DO 120 i = 1,LEN(prefx2) IF (prefx2(i:i) .EQ. ' ') THEN end = i-1 GO TO 125 END IF 120 CONTINUE 125 IF ((isat .EQ. 1) .OR. EQ3run) THEN namepf(1)(1:end) = prefx2(1:end) namepf(1)(end+1:end+3) = 'R01' namepf(1)(end+4:end+7) = '.axy' RETURN END IF IF (univar .EQ. 1) THEN namepf(1)(1:end) = prefx2(1:end) namepf(1)(end+1:end+3) = 'R01' namepf(1)(end+4:end+7) = '.uxy' RETURN END IF DO 130 i = 1,nplots namepf(i)(1:end) = prefx2(1:end) namepf(i)(end+1:end+3) = 'R01' namepf(i)(end+4:end+7) = suffx(i) 130 CONTINUE END ************************************************************************ *** getH2O - Calculate/store requisite H2O properties over the *** user-specified state condition grid. SUBROUTINE getH2O(unirun) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPROP2 = 46) LOGICAL unirun, error INTEGER univar, useLVS, epseqn, geqn, specs(10) DOUBLE PRECISION states(4), props(NPROP2), mwH2O COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn SAVE DATA specs / 2,2,2,5,1,0,0,0,0,0 / DATA states / 4*0.0d0 / specs(8) = useLVS specs(9) = epseqn ***************************************************************** *** assignment of [Z,Y]PrTr to Johnson-Norton (1991) *** values for distribution version ZPrTr = -0.1278034682d-1 YPrTr = -0.5798650444d-4 *** set ZPrTr and YPrTR per espeqn value for development version * CALL seteps(Tref-273.15d0,Pref,epseqn,ZPrTr,YPrTr) ***************************************************************** ***** calculate H2O properties at standard state of 25 degC, 1 bar states(1) = Tref-273.15d0 states(2) = Pref specs(6) = 0 specs(7) = 2 CALL H2O92(specs,states,props,error) CALL H2Ostd(states,props) IF (unirun) RETURN IF (noninc .GT. 0) THEN CALL oddH2O RETURN END IF IF (isat .EQ. 0) THEN CALL oneH2O ELSE CALL twoH2O END IF END ************************************************************************ *** oddH2O - Calculate/store requisite H2O properties over the *** user-specified set of state conditions. SUBROUTINE oddH2O IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXOdd = 3000, MAXINC = 3000, MAXISO = 21, NPROP2 = 46) LOGICAL error, lvdome(MAXINC,MAXISO), 1 H2Oerr(MAXINC,MAXISO), EQ3run INTEGER mapiso(2,3), mapinc(2,3), mapv3(2,3), 1 univar, useLVS, epseqn, geqn, specs(10) DOUBLE PRECISION states(4), props(NPROP2), 1 isomin, isomax, isoinc, Kmin, Kmax, Kinc, 2 oddv1(MAXODD), oddv2(MAXODD) COMMON /TPDmap/ mapiso, mapinc, mapv3 COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /grid/ isomin, isomax, isoinc, v2min, v2max, v2inc, 1 oddv1, oddv2, Kmin, Kmax, Kinc, niso, nv2, nlogK COMMON /badtd/ lvdome, H2Oerr COMMON /EQ36/ EQ3run SAVE DATA specs / 2,2,2,5,1,0,0,0,0,0 / DATA states / 4*0.0d0 / specs(6) = isat specs(7) = iopt specs(8) = useLVS specs(9) = epseqn DO 30 iodd = 1,noninc states(mapiso(iopt,iplot)) = oddv1(iodd) IF (isat .EQ. 0) THEN states(mapinc(iopt,iplot)) = oddv2(iodd) END IF CALL H2O92(specs,states,props,error) H2Oerr(iodd,1) = error IF (.NOT. error) THEN lvdome(iodd,1) = ((iplot .NE. 3) .AND. 1 (specs(6) .EQ. 1) .AND. 2 (.NOT. EQ3run)) IF (lvdome(iodd,1)) THEN specs(6) = 0 ELSE IF (EQ3run .AND. (specs(6) .EQ. 1)) THEN isat = 1 specs(7) = 1 END IF CALL H2Osav(iodd,1,states,props) END IF END IF 30 CONTINUE IF (EQ3run) isat = 0 END ************************************************************************ *** oneH2O - Calculate/store requisite H2O properties over the *** user-specified state condition grid in the *** one-phase region. SUBROUTINE oneH2O IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXOdd = 3000, MAXINC = 3000, MAXISO = 21, NPROP2 = 46) LOGICAL error, lvdome(MAXINC,MAXISO), H2Oerr(MAXINC,MAXISO) INTEGER mapiso(2,3), mapinc(2,3), mapv3(2,3), 1 univar, useLVS, epseqn, geqn, specs(10) DOUBLE PRECISION states(4), props(NPROP2), 1 isomin, isomax, isoinc, Kmin, Kmax, Kinc, 2 oddv1(MAXODD), oddv2(MAXODD) COMMON /TPDmap/ mapiso, mapinc, mapv3 COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /grid/ isomin, isomax, isoinc, v2min, v2max, v2inc, 1 oddv1, oddv2, Kmin, Kmax, Kinc, niso, nv2, nlogK COMMON /badtd/ lvdome, H2Oerr SAVE DATA specs / 2,2,2,5,1,0,0,0,0,0 / DATA states / 4*0.0d0 / specs(6) = isat specs(7) = iopt specs(8) = useLVS specs(9) = epseqn DO 10 iso = 1,niso states(mapiso(iopt,iplot)) = isomin + (iso-1)*isoinc DO 10 inc = 1,nv2 specs(6) = isat specs(7) = iopt states(mapinc(iopt,iplot)) = v2min + (inc-1)*v2inc CALL H2O92(specs,states,props,error) H2Oerr(inc,iso) = error IF (error) THEN states(mapiso(iopt,iplot)) = isomin + 1 (iso-1)*isoinc ELSE lvdome(inc,iso) = (specs(6) .EQ. 1) IF (lvdome(inc,iso)) THEN specs(6) = 0 states(mapiso(iopt,iplot)) = 1 isomin + (iso-1)*isoinc ELSE CALL H2Osav(inc,iso,states,props) END IF END IF 10 CONTINUE END ************************************************************************ *** twoH2O - Calculate/store requisite H2O properties over the *** user-specified state condition grid along the *** vaporization boundary. SUBROUTINE twoH2O IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXOdd = 3000, MAXINC = 3000, MAXISO = 21, NPROP2 = 46) PARAMETER (TS1BAR = 99.6324d0) LOGICAL error, lvdome(MAXINC,MAXISO), 1 H2Oerr(MAXINC,MAXISO), lv1bar INTEGER mapiso(2,3), mapinc(2,3), mapv3(2,3), 1 univar, useLVS, epseqn, geqn, specs(10) DOUBLE PRECISION states(4), props(NPROP2), mwH2O, satmin(2), 1 isomin, isomax, isoinc, Kmin, Kmax, Kinc, 2 oddv1(MAXODD), oddv2(MAXODD) COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr COMMON /TPDmap/ mapiso, mapinc, mapv3 COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /grid/ isomin, isomax, isoinc, v2min, v2max, v2inc, 1 oddv1, oddv2, Kmin, Kmax, Kinc, niso, nv2, nlogK COMMON /satend/ satmin COMMON /badtd/ lvdome, H2Oerr COMMON /lv1b/ lv1bar SAVE DATA specs / 2,2,2,5,1,0,0,0,0,0 / DATA states / 4*0.0d0 / specs(6) = isat specs(7) = iopt specs(8) = useLVS specs(9) = epseqn lv1bar = (iopt .EQ. 1) .AND. (v2min .LE. TS1BAR) DO 10 inc = 1,nv2 IF ((inc .EQ. 1) .AND. (v2min. EQ. 0.0d0)) THEN states(mapiso(iopt,iplot)) = satmin(iopt) ELSE states(mapiso(iopt,iplot)) = v2min+(inc-1)*v2inc END IF IF (lv1bar .AND. (states(mapiso(iopt,iplot)) 1 .LE. TS1BAR)) THEN isat = 0 specs(6) = 0 specs(7) = 2 states(2) = Pref ELSE IF (lv1bar) THEN isat = 1 END IF specs(6) = isat specs(7) = iopt END IF CALL H2O92(specs,states,props,error) H2Oerr(inc,1) = error IF (.NOT. error) CALL H2Osav(inc,1,states,props) 10 CONTINUE END ************************************************************************ *** seteps - Set ZPrTr and YPrTR per espeqn value. SUBROUTINE seteps(TCref,Pref,epseqn,ZPrTr,YPrTr) IMPLICIT DOUBLE PRECISION (a-h,o-z) LOGICAL error INTEGER epseqn, specs(10) DOUBLE PRECISION states(4), props(46) SAVE DATA specs / 2,2,2,5,1,0,2,0,0,0 / specs(9) = epseqn states(1) = TCref states(2) = Pref states(3) = 0.0d0 CALL H2O92(specs,states,props,error) ZPrTr = props(37) YPrTr = props(39) END ************************************************************************ *** H2Ostd - Archive requisite H2O properties for the *** standard state of 25 degC, 1 bar. SUBROUTINE H2Ostd(states,props) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPROP2 = 46) INTEGER A, G, S, U, H, Cv, Cp, vs, al, be, 1 di, vi, tc, st, td, Pr, vik, albe, 2 Z, Y, Q, daldT, X DOUBLE PRECISION states(4), props(NPROP2), mwH2O DOUBLE PRECISION Dwss, Vwss, bewss, alwss, dalwss, Swss, 1 Cpwss, Hwss, Gwss, Zwss, Qwss, Ywss, Xwss COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr COMMON /H2Oss/ Dwss, Vwss, bewss, alwss, dalwss, Swss, 1 Cpwss, Hwss, Gwss, Zwss, Qwss, Ywss, Xwss SAVE DATA A, G, S, U, H, Cv, Cp, vs, al, be, di, vi, 1 tc, st, td, Pr, vik, albe, Z, Y, Q, daldT, X 2 / 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 3 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45 / *** archive requisite properties *** Dwss = states(3) Vwss = mwH2O/states(3) bewss = props(be) alwss = props(al) dalwss = props(daldT) Swss = props(S) Cpwss = props(Cp) Hwss = props(H) Gwss = props(G) Zwss = props(Z) Qwss = props(Q) Ywss = props(Y) Xwss = props(X) END ************************************************************************ *** H2Osav - Archive requisite H2O properties over the *** user-specified state condition grid. SUBROUTINE H2Osav(row,col,states,props) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPROP2 = 46, MAXINC = 3000, MAXISO = 21) LOGICAL EQ3run, lv1bar INTEGER row, col INTEGER mapiso(2,3), mapinc(2,3), mapv3(2,3), 1 univar, useLVS, epseqn, geqn INTEGER A, G, S, U, H, Cv, Cp, vs, al, be, 1 di, vi, tc, st, td, Pr, vik, albe, 2 Z, Y, Q, daldT, X DOUBLE PRECISION states(4), props(NPROP2), mwH2O DOUBLE PRECISION dsvar(MAXINC,MAXISO), Vw(MAXINC,MAXISO), 1 bew(MAXINC,MAXISO), alw(MAXINC,MAXISO), 2 dalw(MAXINC,MAXISO), Sw(MAXINC,MAXISO), 3 Cpw(MAXINC,MAXISO), Hw(MAXINC,MAXISO), 4 Gw(MAXINC,MAXISO), Zw(MAXINC,MAXISO), 5 Qw(MAXINC,MAXISO), Yw(MAXINC,MAXISO), 6 Xw(MAXINC,MAXISO) COMMON /EQ36/ EQ3run COMMON /lv1b/ lv1bar COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr COMMON /TPDmap/ mapiso, mapinc, mapv3 COMMON /H2Ogrd/ dsvar, Vw, bew, alw, dalw, Sw, Cpw, Hw, Gw, 1 Zw, Qw, Yw, Xw SAVE DATA A, G, S, U, H, Cv, Cp, vs, al, be, di, vi, 1 tc, st, td, Pr, vik, albe, Z, Y, Q, daldT, X 2 / 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 3 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45 / *** archive dependent state variables *** IF (isat .EQ. 1) THEN IF (EQ3run) THEN dsvar(row,col) = states(4) ELSE dsvar(row,col) = states(2/iopt) END IF ELSE IF (lv1bar) THEN dsvar(row,col) = states(2) ELSE dsvar(row,col) = states(mapv3(iopt,iplot)) END IF END IF *** archive requisite properties *** Vw(row,col) = mwH2O/states(3+isat) bew(row,col) = props(be+isat) alw(row,col) = props(al+isat) dalw(row,col) = props(daldT+isat) Sw(row,col) = props(S+isat) Cpw(row,col) = props(Cp+isat) Hw(row,col) = props(H+isat) Gw(row,col) = props(G+isat) Zw(row,col) = props(Z+isat) Qw(row,col) = props(Q+isat) Yw(row,col) = props(Y+isat) Xw(row,col) = props(X+isat) END ************************************************************************ *** getmgi - Read standard state properties, equation of state *** parameters, and heat capacity coefficients for all *** mineral, gas, and aqueous species in the current *** reaction. SUBROUTINE getmgi(ireac) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MAXGAS = 10, MAXAQS = 10, MAXRXN = 800) CHARACTER*80 rtitle(MAXRXN) LOGICAL m2reac(MAXRXN) INTEGER nm(MAXRXN), na(MAXRXN), ng(MAXRXN), nw(MAXRXN), 1 rec1m(MAXRXN,MAXMIN), rec1a(MAXRXN,MAXAQS), 2 rec1g(MAXRXN,MAXGAS) DOUBLE PRECISION coefm(MAXRXN,MAXMIN), coefa(MAXRXN,MAXAQS), 1 coefg(MAXRXN,MAXGAS), coefw(MAXRXN) COMMON /reac1/ rtitle COMMON /reac2/ coefm, coefa, coefg, coefw, nm, na, ng, nw, 1 rec1m, rec1a, rec1g, m2reac SAVE *** retrieve thermodynamic data for minerals DO 10 i = 1,nm(ireac) CALL getmin(i,rec1m(ireac,i)) 10 CONTINUE *** retrieve thermodynamic data for gases DO 20 i = 1,ng(ireac) CALL getgas(i,rec1g(ireac,i)) 20 CONTINUE *** retrieve thermodynamic data for aqueous species DO 30 i = 1,na(ireac) CALL getaqs(i,rec1a(ireac,i)) 30 CONTINUE END ************************************************************************ *** getmin - Read, from dprons.dat or an analogous database (starting *** at record rec1), standard state parameters for the i[th] *** one-phase mineral species in the current reaction; *** set ntran(i) to zero. SUBROUTINE getmin(i,rec1) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MXTRAN = 3, IABC = 4, MAXMK = 4, 1 NPLOTF = 8) INTEGER rec1, ntran(MAXMIN) INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 rec1m1, rec1m2, rec1m3, rec1m4, rec1gg, rec1aa, 2 outflg CHARACTER*20 mname(MAXMIN) CHARACTER*30 mform(MAXMIN), mnform, aqform DOUBLE PRECISION Gfmin(MAXMIN), Hfmin(MAXMIN), 1 VPrTrm(MAXMIN), SPrTrm(MAXMIN), 3 MK1(IABC,MAXMIN), MK2(IABC,MAXMIN), 4 MK3(IABC,MAXMIN), MK4(IABC,MAXMIN), 5 Ttran(MXTRAN,MAXMIN), Htran(MXTRAN,MAXMIN), 6 Vtran(MXTRAN,MAXMIN), dPdTtr(MXTRAN,MAXMIN), 7 Tmaxm(MAXMIN), mvolum COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /rlimit/ nmin1, nmin2, nmin3, nmin4, ngas, naqs, 1 rec1m1, rec1m2, rec1m3, rec1m4, rec1gg, rec1aa COMMON /mnames/ mname, mform COMMON /minref/ Gfmin, Hfmin, SPrTrm, VPrTrm, MK1, MK2, MK3, MK4, 1 Ttran, Htran, Vtran, dPdTtr, Tmaxm, ntran **JP* Add mvolum, mnform, aqform for post-processing to make Soltherm records. Common /solth1/ mvolum Common /solth2/ mnform, aqform SAVE mnform(1:30) = ' ' mvolum = 0.0 **JP* following 4 statements added to allow additional heat capacity coef d. **JP* Need to reset to zero when used by minerals that don't use d. MK1(4,i)=0. MK2(4,i)=0. MK3(4,i)=0. MK4(4,i)=0. IF (rec1 .LT. rec1m2) THEN ntran(i) = 0 GO TO 1 END IF IF (rec1 .LT. rec1m3) THEN ntran(i) = 1 GO TO 1 END IF IF (rec1 .LT. rec1m4) THEN ntran(i) = 2 GO TO 1 END IF ntran(i) = 3 1 READ(pronf,10,REC=rec1) mname(i), mform(i) 10 FORMAT(1x,a20,a30) READ(pronf,20,REC=rec1+3) Gfmin(i), Hfmin(i), SPrTrm(i), VPrTrm(i) 20 FORMAT(4x,2(2x,f12.1),2(2x,f8.3)) mnform = mform(i) mvolum = VPrTrm(i) IF (ntran(i) .EQ. 0) THEN **JP* READ(pronf,30,REC=rec1+4) (MK1(j,i), j=1,3) **JP* 30 FORMAT(4x,3(2x,f12.6)) READ(pronf,30,REC=rec1+4) (MK1(j,i), j=1,4) 30 FORMAT(4x,4(2x,f12.6)) 31 FORMAT(4x,3(2x,f12.6)) CMR*** adjust magnitude for coefficient d MK1(4,i), also **JP* adjustment of MK1(4,i) not neccessary since already adjusted in **JP* HPRONS.FOR---however MK1(2,i) and MK1(3,i) need to **JP* be "deadjusted" in HPRONS.FOR (CPB and CPC in that program) **JP* so as to avoid modifying the code here. Line for MK1(4,i) with **JP* coef of 1.0 added anyway to facilitate later modification **** adjust magnitude for Cp coeffs MK1(2,i) = MK1(2,i)*1.0d-3 MK1(3,i) = MK1(3,i)*1.0d5 **JP* MK1(4,i) = MK1(4,i)*1.0d0 READ(pronf,40,REC=rec1+5) Tmaxm(i) 40 FORMAT(8x,f7.2) RETURN END IF IF (ntran(i) .EQ. 1) THEN READ(pronf,50,REC=rec1+4) (MK1(j,i), j=1,3), 1 Ttran(1,i), Htran(1,i), Vtran(1,i), dPdTtr(1,i) * write(*,50) (MK1(j,i), j=1,3), * 1 Ttran(1,i), Htran(1,i), Vtran(1,i), dPdTtr(1,i) 50 FORMAT(4x,3(2x,f12.6),2x,f7.2,2x,f8.1,2(2x,f10.3)) ***** adjust magnitude for Cp coeffs MK1(2,i) = MK1(2,i)*1.0d-3 MK1(3,i) = MK1(3,i)*1.0d5 **JP* READ(pronf,30,REC=rec1+5) (MK2(j,i), j=1,3) READ(pronf,31,REC=rec1+5) (MK2(j,i), j=1,3) * write(*,31) (MK2(j,i), j=1,3) ***** adjust magnitude for Cp coeffs MK2(2,i) = MK2(2,i)*1.0d-3 MK2(3,i) = MK2(3,i)*1.0d5 READ(pronf,40,REC=rec1+6) Tmaxm(i) RETURN END IF IF (ntran(i) .EQ. 2) THEN READ(pronf,50,REC=rec1+4) (MK1(j,i), j=1,3), 1 Ttran(1,i), Htran(1,i), Vtran(1,i), dPdTtr(1,i) ***** adjust magnitude for Cp coeffs MK1(2,i) = MK1(2,i)*1.0d-3 MK1(3,i) = MK1(3,i)*1.0d5 * write(*,50) (MK1(j,i), j=1,3), * 1 Ttran(1,i), Htran(1,i), Vtran(1,i), dPdTtr(1,i) READ(pronf,50,REC=rec1+5) (MK2(j,i), j=1,3), 1 Ttran(2,i), Htran(2,i), Vtran(2,i), dPdTtr(2,i) ***** adjust magnitude for Cp coeffs MK2(2,i) = MK2(2,i)*1.0d-3 MK2(3,i) = MK2(3,i)*1.0d5 * write(*,50) (MK1(j,i), j=1,3), * 1 Ttran(1,i), Htran(1,i), Vtran(1,i), dPdTtr(1,i) READ(pronf,31,REC=rec1+6) (MK3(j,i), j=1,3) ***** adjust magnitude for Cp coeffs MK3(2,i) = MK3(2,i)*1.0d-3 MK3(3,i) = MK3(3,i)*1.0d5 READ(pronf,40,REC=rec1+7) Tmaxm(i) RETURN END IF IF (ntran(i) .EQ. 3) THEN READ(pronf,50,REC=rec1+4) (MK1(j,i), j=1,3), 1 Ttran(1,i), Htran(1,i), Vtran(1,i), dPdTtr(1,i) ***** adjust magnitude for Cp coeffs MK1(2,i) = MK1(2,i)*1.0d-3 MK1(3,i) = MK1(3,i)*1.0d5 READ(pronf,50,REC=rec1+5) (MK2(j,i), j=1,3), 1 Ttran(2,i), Htran(2,i), Vtran(2,i), dPdTtr(2,i) ***** adjust magnitude for Cp coeffs MK2(2,i) = MK2(2,i)*1.0d-3 MK2(3,i) = MK2(3,i)*1.0d5 READ(pronf,50,REC=rec1+6) (MK3(j,i), j=1,3), 1 Ttran(3,i), Htran(3,i), Vtran(3,i), dPdTtr(3,i) ***** adjust magnitude for Cp coeffs MK3(2,i) = MK3(2,i)*1.0d-3 MK3(3,i) = MK3(3,i)*1.0d5 READ(pronf,31,REC=rec1+7) (MK4(j,i), j=1,3) ***** adjust magnitude for Cp coeffs MK4(2,i) = MK4(2,i)*1.0d-3 MK4(3,i) = MK4(3,i)*1.0d5 READ(pronf,40,REC=rec1+8) Tmaxm(i) RETURN END IF END ************************************************************************ *** getgas - Read, from dprons.dat or an analogous database (starting *** at record rec1), standard state parameters for the i[th] *** gas species in the current reaction. SUBROUTINE getgas(i,rec1) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXGAS = 10, IABC = 4, NPLOTF = 8) INTEGER rec1 INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), outflg CHARACTER*20 gname(MAXGAS) CHARACTER*30 gform(MAXGAS), mnform, aqform DOUBLE PRECISION Gfgas(MAXGAS), Hfgas(MAXGAS), VPrTrg(MAXGAS), 1 SPrTrg(MAXGAS), MKg(IABC,MAXGAS), Tmaxg(MAXGAS), 2 mvolum COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /gnames/ gname, gform COMMON /gasref/ Gfgas, Hfgas, SPrTrg, VPrTrg, MKg, Tmaxg Common /solth1/ mvolum Common /solth2/ mnform, aqform SAVE mnform(1:30) = ' ' mvolum = 0.0 **JP* following statement added to allow additional heat capacity coef d. **JP* Need to reset to zero when used by minerals that don't use d. MKg(4,i)=0. READ(pronf,20,REC=rec1) gname(i), gform(i) 20 FORMAT(1x,a20,a30) READ(pronf,30,REC=rec1+3) Gfgas(i), Hfgas(i), SPrTrg(i), VPrTrg(i) 30 FORMAT(4x,2(2x,f12.1),2(2x,f8.3)) mnform = gform(i) mvolum = VPrTrg(i) **JP* READ(pronf,40,REC=rec1+4) MKg(1,i), MKg(2,i), MKg(3,i) **JP* 40 FORMAT(4x,3(2x,f12.6)) READ(pronf,40,REC=rec1+4) MKg(1,i), MKg(2,i), MKg(3,i), MKg(4,i) 40 FORMAT(4x,4(2x,f12.6)) READ(pronf,50,REC=rec1+5) Tmaxg(i) 50 FORMAT(8x,f7.2) ***** adjust magnitude for Cp coeffs MKg(2,i) = MKg(2,i)*1.0d-3 MKg(3,i) = MKg(3,i)*1.0d5 END ************************************************************************ *** getaqs - Read, from dprons.dat or an analogous database (starting *** at record rec1), standard state parameters for the i[th] *** aqueous species in the current reaction. SUBROUTINE getaqs(i,rec1) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXAQS = 10, NPLOTF = 8) INTEGER rec1 INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), outflg CHARACTER*20 aname(MAXAQS) CHARACTER*30 aform(MAXAQS), mnform, aqform DOUBLE PRECISION Gfaqs(MAXAQS), Hfaqs(MAXAQS), SPrTra(MAXAQS), 1 a(4,MAXAQS), c(2,MAXAQS), 2 wref(MAXAQS), chg(MAXAQS) COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /anames/ aname, aform COMMON /aqsref/ Gfaqs, Hfaqs, SPrTra, c, a, wref, chg **JP* Add mvolum, mnform, aqform for post-processing to make Soltherm records. Common /solth2/ mnform, aqform SAVE READ(pronf,20,REC=rec1) aname(i), aform(i) 20 FORMAT(1x,a20,a30) aqform = aform(1) READ(pronf,30,REC=rec1+3) Gfaqs(i), Hfaqs(i), SPrTra(i) 30 FORMAT(4x,2(2x,f10.0),4x,f8.3) READ(pronf,40,REC=rec1+4) a(1,i), a(2,i), a(3,i), a(4,i) 40 FORMAT(4x,4(2x,f8.4,2x)) READ(pronf,50,REC=rec1+5) c(1,i), c(2,i), wref(i), chg(i) 50 FORMAT(4x,3(2x,f8.4,2x),9x,f3.0) ***** adjust magnitude for e-o-s coefficients and omega a(1,i) = a(1,i)*1.0d-1 a(2,i) = a(2,i)*1.0d2 a(4,i) = a(4,i)*1.0d4 c(2,i) = c(2,i)*1.0d4 wref(i) = wref(i)*1.0d5 END ************************************************************************ *** runrxn - Calculate the standard molal thermodynamic properties of *** the i[th] reaction over the range of user-specified state *** conditions. SUBROUTINE runrxn(i,wetrun) IMPLICIT DOUBLE PRECISION (a-h,o-z) INTEGER univar, useLVS, epseqn, geqn LOGICAL wetrun COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn SAVE IF (univar .EQ. 1) THEN ***** univariant curve option enabled ***** CALL rununi(i) RETURN END IF IF (noninc .EQ. 0) THEN ***** run orthogonal T-d or T-P grid ***** CALL rungrd(i,wetrun) ELSE ***** run "oddball" T,P or T,d pairs ***** CALL runodd(i) END IF END ************************************************************************ *** rungrd - Calculate the standard molal thermodynamic properties of *** the i[th] reaction over the user-specified *** state-condition grid. SUBROUTINE rungrd(i,wetrun) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MAXGAS = 10, MAXAQS = 10, MXTRAN = 3, 1 MAXINC = 3000, MAXISO = 21, MAXOdd = 3000, 2 MAXRXN = 800, NPLOTF = 8) LOGICAL m2reac(MAXRXN), rptran, newiso, wetrun, 1 lvdome(MAXINC,MAXISO), H2Oerr(MAXINC,MAXISO) CHARACTER*80 rtitle(MAXRXN) INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 mapiso(2,3), mapinc(2,3), mapv3(2,3), 2 univar, useLVS, epseqn, geqn, ptrans(MAXMIN), 3 outflg INTEGER nm(MAXRXN), na(MAXRXN), ng(MAXRXN), nw(MAXRXN), 1 rec1m(MAXRXN,MAXMIN), rec1a(MAXRXN,MAXAQS), 2 rec1g(MAXRXN,MAXGAS) DOUBLE PRECISION coefm(MAXRXN,MAXMIN), coefa(MAXRXN,MAXAQS), 1 coefg(MAXRXN,MAXGAS), coefw(MAXRXN) DOUBLE PRECISION isomin, isomax, isoinc, Kmin, Kmax, Kinc, 1 logKr, oddv1(MAXODD), oddv2(MAXODD), 2 TPD(3), TPDtrn(MAXMIN,MXTRAN,3), 3 mwH2O, satmin(2) DOUBLE PRECISION dsvar(MAXINC,MAXISO), Vw(MAXINC,MAXISO), 1 bew(MAXINC,MAXISO), alw(MAXINC,MAXISO), 2 dalw(MAXINC,MAXISO), Sw(MAXINC,MAXISO), 3 Cpw(MAXINC,MAXISO), Hw(MAXINC,MAXISO), 4 Gw(MAXINC,MAXISO), Zw(MAXINC,MAXISO), 5 Qw(MAXINC,MAXISO), Yw(MAXINC,MAXISO), 6 Xw(MAXINC,MAXISO) COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /TPDmap/ mapiso, mapinc, mapv3 COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /grid/ isomin, isomax, isoinc, v2min, v2max, v2inc, 1 oddv1, oddv2, Kmin, Kmax, Kinc, niso, nv2, nlogK COMMON /H2Ogrd/ dsvar, Vw, bew, alw, dalw, Sw, Cpw, Hw, Gw, 1 Zw, Qw, Yw, Xw COMMON /reac1/ rtitle COMMON /reac2/ coefm, coefa, coefg, coefw, nm, na, ng, nw, 1 rec1m, rec1a, rec1g, m2reac COMMON /fmeq/ dVr, dSr, dCpr, dHr, dGr, logKr, dlogKT, dlogKP COMMON /satend/ satmin COMMON /badtd/ lvdome, H2Oerr SAVE DO 10 iso = 1,niso IF (isat .EQ. 0) 1 TPD(mapiso(iopt,iplot)) = isomin + (iso-1)*isoinc DO 20 inc = 1,nv2 IF (isat .EQ. 0) THEN TPD(mapinc(iopt,iplot)) = v2min + (inc-1)*v2inc TPD(mapv3(iopt,iplot)) = dsvar(inc,iso) ELSE IF ((inc .EQ. 1) .AND. (v2min .EQ. 0.0d0)) THEN TPD(mapiso(iopt,iplot)) = satmin(iopt) ELSE TPD(mapiso(iopt,iplot)) = v2min + (inc-1)*v2inc END IF TPD(mapinc(iopt,iplot)) = dsvar(inc,iso) TPD(mapv3(iopt,iplot)-isat) = mwH2O/Vw(inc,iso) END IF IF (.NOT. (lvdome(inc,iso) .OR. H2Oerr(inc,iso))) THEN CALL reac92(i,TPD(2),TPD(1),TPD(3),Vw(inc,iso), 1 bew(inc,iso), alw(inc,iso), dalw(inc,iso), 2 Sw(inc,iso), Cpw(inc,iso), Hw(inc,iso), 3 Gw(inc,iso), Zw(inc,iso), Qw(inc,iso), 4 Yw(inc,iso), Xw(inc,iso), geqn) END IF IF (.NOT. m2reac(i)) THEN rptran = .FALSE. ELSE newiso = ((inc .EQ. 1) .OR. lvdome(inc-1,iso) .OR. 1 H2Oerr(inc-1,iso)) CALL m2tran(inc,iso,newiso,nm(i), 1 rptran,ptrans,TPD,TPDtrn,wetrun) END IF CALL report(i,iso,inc,TPD,TPDtrn,rptran,ptrans, 1 dVr,dSr,dCpr,dHr,dGr,logKr, 2 lvdome(inc,iso),H2Oerr(inc,iso), 3 .FALSE.) 20 CONTINUE 10 CONTINUE END ******************************************************************* *** m2tran - Returns rptran = .TRUE. if a phase transition occurs *** for one or more minerals in the current reaction between *** the immediately previous and current state conditions. SUBROUTINE m2tran(inc,iso,newiso,nmreac,rptran,ptrans,TPD,TPDtrn, 1 wetrun) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MXTRAN = 3, MAXMIN = 10) LOGICAL rptran, newiso, wetrun INTEGER phaser(MAXMIN), prprev(MAXMIN), ptrans(MAXMIN) DOUBLE PRECISION TPD(3), TPDtrn(MAXMIN,MXTRAN,3) DOUBLE PRECISION Vmin(MAXMIN), Smin(MAXMIN), Cpmin(MAXMIN), 2 Hmin(MAXMIN), Gmin(MAXMIN) COMMON /minsp/ Vmin, Smin, Cpmin, Hmin, Gmin, phaser SAVE rptran = .FALSE. IF (newiso) THEN DO 10 imin = 1,nmreac prprev(imin) = phaser(imin) ptrans(imin) = 0 10 CONTINUE ELSE DO 20 imin = 1,nmreac IF (prprev(imin) .EQ. phaser(imin)) THEN ptrans(imin) = 0 ELSE rptran = .TRUE. ptrans(imin) = IABS(phaser(imin) - prprev(imin)) prprev(imin) = phaser(imin) CALL getsct(inc,iso,imin,phaser(imin), 1 ptrans(imin),TPD,TPDtrn,wetrun) END IF 20 CONTINUE END IF END ********************************************************************* *** getsct - Get s[tate] c[onditions of phase] t[ransition] *** iphase for mineral imin. SUBROUTINE getsct(inc,iso,imin,iphase,ntrans,TPD,TPDtrn,wetrun) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MXTRAN = 3, MAXMIN = 10, IABC = 4, NPROP2 = 46, 1 MAXINC = 3000, MAXISO = 21, MAXOdd = 3000, NPLOTF = 8) LOGICAL error, wetrun CHARACTER*20 mname(MAXMIN) CHARACTER*30 mform(MAXMIN) INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 outflg INTEGER univar, useLVS, epseqn, geqn, ntran(MAXMIN), 1 mapiso(2,3), mapinc(2,3), mapv3(2,3), specs(10) DOUBLE PRECISION TPDtrn(MAXMIN,MXTRAN,3), TtranP(MXTRAN,MAXMIN), 2 PtranT(MXTRAN,MAXMIN), states(4), props(NPROP2), 3 isomin, isomax, isoinc, Kmin, Kmax, Kinc, 4 oddv1(MAXODD), oddv2(MAXODD), TPD(3) DOUBLE PRECISION Gfmin(MAXMIN), Hfmin(MAXMIN), 1 VPrTrm(MAXMIN), SPrTrm(MAXMIN), 3 MK1(IABC,MAXMIN), MK2(IABC,MAXMIN), 4 MK3(IABC,MAXMIN), MK4(IABC,MAXMIN), 5 Ttran(MXTRAN,MAXMIN), Htran(MXTRAN,MAXMIN), 6 Vtran(MXTRAN,MAXMIN), dPdTtr(MXTRAN,MAXMIN), 7 Tmaxm(MAXMIN) DOUBLE PRECISION dsvar(MAXINC,MAXISO), Vw(MAXINC,MAXISO), 1 bew(MAXINC,MAXISO), alw(MAXINC,MAXISO), 2 dalw(MAXINC,MAXISO), Sw(MAXINC,MAXISO), 3 Cpw(MAXINC,MAXISO), Hw(MAXINC,MAXISO), 4 Gw(MAXINC,MAXISO), Zw(MAXINC,MAXISO), 5 Qw(MAXINC,MAXISO), Yw(MAXINC,MAXISO), 6 Xw(MAXINC,MAXISO) COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /TPDmap/ mapiso, mapinc, mapv3 COMMON /PTtran/ TtranP, PtranT COMMON /H2Ogrd/ dsvar, Vw, bew, alw, dalw, Sw, Cpw, Hw, Gw, 1 Zw, Qw, Yw, Xw COMMON /mnames/ mname, mform COMMON /minref/ Gfmin, Hfmin, SPrTrm, VPrTrm, MK1, MK2, MK3, MK4, 1 Ttran, Htran, Vtran, dPdTtr, Tmaxm, ntran COMMON /grid/ isomin, isomax, isoinc, v2min, v2max, v2inc, 1 oddv1, oddv2, Kmin, Kmax, Kinc, niso, nv2, nlogK SAVE DATA specs / 2,2,2,5,1,0,0,0,0,0 / DATA states / 4*0.0d0 / DATA Tfssat / 139.8888149d0 / specs(6) = isat specs(7) = iopt specs(8) = useLVS specs(9) = epseqn *** ntrans = # phase transitions for mineral imin between *** current and last isopleth locations. DO 10 itran = ntrans,1,-1 IF (isat .EQ. 1) THEN *** vaporization boundary IF (mname(imin)(1:11) .EQ. 'FERROSILITE') THEN states(1) = Tfssat ELSE states(1) = TtranP(iphase-itran,imin) - 273.15d0 END IF IF (specs(7) .EQ. 2) THEN specs(7) = 1 END IF ELSE IF (iplot .EQ. 2) THEN *** isotherms(pres or dens) states(1) = TPD(mapiso(iopt,iplot)) states(2) = PtranT(iphase-itran+1,imin) IF (specs(7) .EQ. 1) THEN specs(7) = 2 END IF ELSE IF (iopt .EQ. 2) THEN *** isobars(temp) states(1) = TtranP(iphase-itran,imin) 1 - 273.15d0 states(2) = TPD(mapiso(iopt,iplot)) ELSE *** isochores(temp) states(3) = TPD(mapiso(iopt,iplot)) IF (dPdTtr(iphase-1,imin) .EQ. 0.0d0) THEN states(1) = TtranP(iphase-itran,imin) 1 - 273.15d0 ELSE *** special case, make *** appropriate approximation P1 = dsvar(inc-1,iso) P2 = dsvar(inc,iso) T1 = v2min + (inc-2)*v2inc T2 = v2min + (inc-1)*v2inc states(1) = Tint(P1,P2,T1,T2, 1 TtranP(iphase-itran,imin)-273.15d0, 2 dPdTtr(iphase-itran,imin)) END IF END IF END IF END IF IF (wetrun) THEN CALL H2O92(specs,states,props,error) ELSE error = .FALSE. states(isat+3) = 0.0d0 END IF IF (error) THEN WRITE(wterm,20) (states(jjj), jjj=1,3) WRITE(tabf,20) (states(jjj), jjj=1,3) 20 format(/,' State conditions fall beyond validity limits of', 1 /,' the Haar et al. (1984) H2O equation of state:', 2 /,' T < Tfusion@P; T > 2250 degC; or P > 30kb.', 3 /,' SUPCRT92 stopped in SUBROUTINE getsct:', 4 //,' T = ',e12.5, 5 /,' P = ',e12.5, 6 /,' D = ',e12.5,/) STOP ELSE TPDtrn(imin,itran,1) = states(1) TPDtrn(imin,itran,2) = states(2) TPDtrn(imin,itran,3) = states(isat+3) END IF 10 CONTINUE END ********************************************************************* *** Tint - Returns the temperature intersection of isochore(T) *** with a mineral phase transition boundary where *** (dP/dT)tr .NE. 0. Approximation involves assumption *** that (dP/dT)isochore is linear between P1,T1,D *** and P2,T2,D (consecutive locations on isochore D(T)) *** that bridge the phase transition. DOUBLE PRECISION FUNCTION Tint(P1,P2,T1,T2,TtrnP2,dPdTtr) IMPLICIT DOUBLE PRECISION (a-h,o-z) SAVE bmin = P2 - dPdTtr*TtrnP2 dPdTi = (P2 - P1)/(T2 - T1) biso = P2 - dPdTi*T2 Tint = (bmin - biso)/(dPdTi - dPdTtr) END ************************************************************************ *** runodd - Calculate the standard molal thermodynamic properties of *** the i[th] reaction over the user-specified set of *** nonincremental state condition pairs. SUBROUTINE runodd(i) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MAXGAS = 10, MAXAQS = 10, MXTRAN = 3, 1 MAXINC = 3000, MAXISO = 21, MAXOdd = 3000, NPLOTF = 8) LOGICAL rptdum, lvdome(MAXINC,MAXISO), H2Oerr(MAXINC,MAXISO) INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 mapiso(2,3), mapinc(2,3), mapv3(2,3), 2 univar, useLVS, epseqn, geqn, ptdumb(MAXMIN), 3 outflg DOUBLE PRECISION isomin, isomax, isoinc, Kmin, Kmax, Kinc, 1 logKr, oddv1(MAXODD), oddv2(MAXODD), 2 TPD(3), mwH2O DOUBLE PRECISION dsvar(MAXINC,MAXISO), Vw(MAXINC,MAXISO), 1 bew(MAXINC,MAXISO), alw(MAXINC,MAXISO), 2 dalw(MAXINC,MAXISO), Sw(MAXINC,MAXISO), 3 Cpw(MAXINC,MAXISO), Hw(MAXINC,MAXISO), 4 Gw(MAXINC,MAXISO), Zw(MAXINC,MAXISO), 5 Qw(MAXINC,MAXISO), Yw(MAXINC,MAXISO), 6 Xw(MAXINC,MAXISO), 7 TPDdum(MAXMIN,MXTRAN,3) COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /TPDmap/ mapiso, mapinc, mapv3 COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /grid/ isomin, isomax, isoinc, v2min, v2max, v2inc, 1 oddv1, oddv2, Kmin, Kmax, Kinc, niso, nv2, nlogK COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr COMMON /H2Ogrd/ dsvar, Vw, bew, alw, dalw, Sw, Cpw, Hw, Gw, 1 Zw, Qw, Yw, Xw COMMON /fmeq/ dVr, dSr, dCpr, dHr, dGr, logKr, dlogKT, dlogKP COMMON /badtd/ lvdome, H2Oerr SAVE *** MAXMIN*MXTRAN*3 = 90 *** DATA TPDdum / 90*0.0d0 / DATA rptdum / .FALSE. / *** MAXMIN*0 DATA ptdumb / 10*0 / DO 10 iodd = 1,noninc TPD(mapiso(iopt,iplot)) = oddv1(iodd) IF (isat .EQ. 0) THEN TPD(mapinc(iopt,iplot)) = oddv2(iodd) TPD(mapv3(iopt,iplot)) = dsvar(iodd,1) ELSE TPD(mapinc(iopt,iplot)) = dsvar(iodd,1) TPD(mapv3(iopt,iplot)-isat) = mwH2O/Vw(iodd,1) END IF IF (.NOT. (lvdome(iodd,1) .OR. H2Oerr(iodd,1))) THEN CALL reac92(i,TPD(2),TPD(1),TPD(3),Vw(iodd,1), 1 bew(iodd,1), alw(iodd,1), dalw(iodd,1), 2 Sw(iodd,1), Cpw(iodd,1), Hw(iodd,1), 3 Gw(iodd,1), Zw(iodd,1), Qw(iodd,1), 4 Yw(iodd,1), Xw(iodd,1), geqn) END IF CALL report(i, 1, iodd, TPD, TPDdum, rptdum, ptdumb, 1 dVr, dSr, dCpr, dHr, dGr, logKr, 2 lvdome(iodd,1), H2Oerr(iodd,1),.FALSE.) 10 CONTINUE END ************************************************************************ *** rununi - Calculate the standard molal thermodynamic properties of *** the i[th] reaction over the user-specified set of T,logK *** or P,logK pairs. SUBROUTINE rununi(i) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MAXAQS = 10, MAXGAS = 10, MAXRXN = 800, 1 MAXOdd = 3000, MXTRAN = 3, NPLOTF = 8) LOGICAL foundK, Kfound, wetrxn, m2reac(MAXRXN), rptdum CHARACTER*80 rtitle(MAXRXN) INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 mapiso(2,3), mapinc(2,3), mapv3(2,3), 2 univar, useLVS, epseqn, geqn, ptdumb(MAXMIN), 3 outflg INTEGER nm(MAXRXN), na(MAXRXN), ng(MAXRXN), nw(MAXRXN), 1 rec1m(MAXRXN,MAXMIN), rec1a(MAXRXN,MAXAQS), 2 rec1g(MAXRXN,MAXGAS) DOUBLE PRECISION isomin, isomax, isoinc, Kmin, Kmax, Kinc, 1 Kfind, logKr, isoval, oddv1(MAXODD), 2 oddv2(MAXODD), TPD(3), TPDdum(MAXMIN,MXTRAN,3) DOUBLE PRECISION coefm(MAXRXN,MAXMIN), coefa(MAXRXN,MAXAQS), 1 coefg(MAXRXN,MAXGAS), coefw(MAXRXN) COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /TPDmap/ mapiso, mapinc, mapv3 COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /grid/ isomin, isomax, isoinc, v2min, v2max, v2inc, 1 oddv1, oddv2, Kmin, Kmax, Kinc, niso, nv2, nlogK COMMON /reac1/ rtitle COMMON /reac2/ coefm, coefa, coefg, coefw, nm, na, ng, nw, 1 rec1m, rec1a, rec1g, m2reac COMMON /fmeq/ dVr, dSr, dCpr, dHr, dGr, logKr, dlogKT, dlogKP SAVE *** MAXMIN*MXTRAN*3 = 90 *** DATA TPDdum / 90*0.0d0 / DATA rptdum / .FALSE. / *** MAXMIN*0 DATA ptdumb / 10*0 / nv2 = nlogK wetrxn = ((nw(i) .GT. 0) .OR. (na(i) .GT. 0)) DO 10 iso = 1,niso isoval = isomin + (iso-1)*isoinc DO 10 inc = 1,nlogK Kfind = Kmin + (inc-1)*Kinc Kfound = foundK(i,wetrxn,Kfind,isoval, 1 v2min,v2max,v2val,dH2O) IF (.NOT. Kfound) logKr = Kfind TPD(mapiso(iopt,iplot)) = isoval TPD(mapinc(iopt,iplot)) = v2val TPD(3) = dH2O CALL report(i, iso, inc, TPD, TPDdum, rptdum, 1 ptdumb, dVr, dSr, dCpr, dHr, dGr, logKr, 2 .FALSE.,.FALSE.,Kfound) 10 CONTINUE END ******************************************************************** *** SUBRs report, wrtrxn, wrtssp, report *** SUBR blanks ******************************************************************** *** foundK - Returns '.TRUE.' and v2Kfnd[T|P](isoval[P|T],Kfind) if *** (1) logK(isoval,var2=v2min..v2max) for the i[th] reaction *** is unimodal, and (2) logK value Kfind at isoval occurs *** within v2min..v2max; otherwise returns '.FALSE.'. *** v2Kfnd(usival,Kfind) is isolated using a straightforward *** implementation of the golden section search algorithm *** (e.g., Miller (1984), pp. 130-133.) LOGICAL FUNCTION foundK(i,wetrxn,Kfind,isoval,v2min,v2max, 1 v2val,dH2O) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPROP2 = 46, MXEVAL = 50, TOL = 1.0d6, NPLOTF = 8) LOGICAL wetrxn, error INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 outflg INTEGER mapiso(2,3), mapinc(2,3), mapv3(2,3), 1 univar, useLVS, epseqn, geqn, specs(10) INTEGER AA, G, S, U, H, Cv, Cp, vs, al, be, 1 di, vi, tc, st, td, Pr, vik, albe, 2 Z, Y, Q, daldT, X DOUBLE PRECISION isoval, Kfind, major, logKr, mwH2O, 1 states(4), props(NPROP2) COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /refval/ mwH2O, RR, Pref, Tref, ZPrTr, YPrTr COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /TPDmap/ mapiso, mapinc, mapv3 COMMON /fmeq/ dVr, dSr, dCpr, dHr, dGr, 1 logKr, dlogKT, dlogKP SAVE DATA AA, G, S, U, H, Cv, Cp, vs, al, be, di, vi, 1 tc, st, td, Pr, vik, albe, Z, Y, Q, daldT, X 2 / 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 3 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45 / DATA specs / 2,2,2,5,1,0,2,0,0,0 / DATA props / 46*0.0d0 / DATA error / .FALSE. / foundK = .TRUE. j = 0 a = v2min b = v2max r = (3.0d0 - DSQRT(5.0d0)) / 2.0d0 major = r * (b-a) c = a + major d = b - major *** set acceptance tolerance per TOL accept = (1.0d0 + DABS(Kfind))/TOL states(mapiso(iopt,iplot)) = isoval states(mapinc(iopt,iplot)) = c states(3) = 1.0d0 IF (wetrxn) THEN specs(8) = useLVS specs(9) = epseqn CALL H2O92(specs,states,props,error) IF (error) THEN WRITE(wterm,10) (states(jjj), jjj=1,3) WRITE(tabf,10) (states(jjj), jjj=1,3) 10 format(/,' State conditions fall beyond validity limits of', 1 /,' the Haar et al. (1984) H2O equation of state:', 2 /,' T < Tfusion@P; T > 2250 degC; or P > 30kb.', 3 /,' SUPCRT92 stopped in LOGICAL FUNCTION foundK:', 4 //,' T = ',e12.5, 5 /,' P = ',e12.5, 6 /,' D = ',e12.5,/) STOP END IF END IF CALL reac92(i,states(2),states(1),states(3), 1 mwH2O/states(3),props(be),props(al),props(daldT), 2 props(S),props(Cp),props(H),props(G),props(Z),props(Q), 3 props(Y),props(X),geqn) fc = DABS(logKr - Kfind) states(mapiso(iopt,iplot)) = isoval states(mapinc(iopt,iplot)) = d IF (wetrxn) THEN CALL H2O92(specs,states,props,error) IF (error) THEN WRITE(wterm,10) STOP END IF END IF CALL reac92(i,states(2),states(1),states(3), 1 mwH2O/states(3),props(be),props(al),props(daldT), 2 props(S),props(Cp),props(H),props(G),props(Z),props(Q), 3 props(Y),props(X),geqn) fd = DABS(logKr - Kfind) 1 IF (fc .LE. accept) THEN states(mapiso(iopt,iplot)) = isoval states(mapinc(iopt,iplot)) = c IF (wetrxn) THEN CALL H2O92(specs,states,props,error) IF (error) THEN WRITE(wterm,10) STOP END IF END IF CALL reac92(i,states(2),states(1),states(3), 1 mwH2O/states(3),props(be),props(al),props(daldT), 2 props(S),props(Cp),props(H),props(G),props(Z),props(Q), 3 props(Y),props(X),geqn) v2val = c IF (wetrxn) THEN dH2O = states(3) ELSE dH2O = 0.0d0 END IF RETURN END IF IF (fd .LE. accept) THEN states(mapiso(iopt,iplot)) = isoval states(mapinc(iopt,iplot)) = d IF (wetrxn) THEN CALL H2O92(specs,states,props,error) IF (error) THEN WRITE(wterm,10) STOP END IF END IF CALL reac92(i,states(2),states(1),states(3), 1 mwH2O/states(3),props(be),props(al),props(daldT), 2 props(S),props(Cp),props(H),props(G),props(Z),props(Q), 3 props(Y),props(X),geqn) v2val = d IF (wetrxn) THEN dH2O = states(3) ELSE dH2O = 0.0d0 END IF RETURN END IF IF (j .GT. MXEVAL) THEN foundK = .FALSE. IF (wetrxn) THEN dH2O = states(3) ELSE dH2O = 0.0d0 END IF RETURN ELSE j = j + 1 END IF IF (fc .LT. fd) THEN b = d d = c fd = fc c = a + r*(b-a) states(mapiso(iopt,iplot)) = isoval states(mapinc(iopt,iplot)) = c IF (wetrxn) THEN CALL H2O92(specs,states,props,error) IF (error) THEN WRITE(wterm,10) STOP END IF END IF CALL reac92(i,states(2),states(1),states(3), 1 mwH2O/states(3),props(be),props(al),props(daldT), 2 props(S),props(Cp),props(H),props(G),props(Z), 3 props(Q),props(Y),props(X),geqn) fc = DABS(logKr - Kfind) ELSE a = c c = d fc = fd d = b - r*(b-a) states(mapiso(iopt,iplot)) = isoval states(mapinc(iopt,iplot)) = d IF (wetrxn) THEN CALL H2O92(specs,states,props,error) IF (error) THEN WRITE(wterm,10) STOP END IF END IF CALL reac92(i,states(2),states(1),states(3), 1 mwH2O/states(3),props(be),props(al),props(daldT), 2 props(S),props(Cp),props(H),props(G),props(Z), 3 props(Q),props(Y),props(X),geqn) fd = DABS(logKr - Kfind) END IF GO TO 1 END ********************************************************************* *** makerf - Prompt for and create a reaction (RXN) file. SUBROUTINE makerf(nreac,wetrxn) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MAXAQS = 10, MAXGAS = 10, MAXRXN = 800, 1 MAXBAD = 10, NPLOTF = 8) CHARACTER*1 ans CHARACTER*20 namecf, namerf, nametf, namepf(NPLOTF) CHARACTER*20 specie, namem(MAXRXN,MAXMIN), 1 namea(MAXRXN,MAXAQS), nameg(MAXRXN,MAXGAS), 2 sbad(MAXBAD) CHARACTER*30 form, formm(MAXRXN,MAXMIN), formg(MAXRXN,MAXGAS), 1 forma(MAXRXN,MAXAQS) CHARACTER*80 rtitle(MAXRXN), string LOGICAL openf, wetrxn, m2reac(MAXRXN), parse, 1 savecf, saverf, rxnok, match INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), rec1, 1 nm(MAXRXN), na(MAXRXN), ng(MAXRXN), nw(MAXRXN), 2 rec1m(MAXRXN,MAXMIN), rec1a(MAXRXN,MAXAQS), 3 rec1g(MAXRXN,MAXGAS), univar, useLVS, epseqn, geqn, 4 rec1m1, rec1m2, rec1m3, rec1m4, rec1gg, rec1aa, outflg DOUBLE PRECISION coefm(MAXRXN,MAXMIN), coefa(MAXRXN,MAXAQS), 1 coefg(MAXRXN,MAXGAS), coefw(MAXRXN) COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /rlimit/ nmin1, nmin2, nmin3, nmin4, ngas, naqs, 1 rec1m1, rec1m2, rec1m3, rec1m4, rec1gg, rec1aa COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /reac1/ rtitle COMMON /reac2/ coefm, coefa, coefg, coefw, nm, na, ng, nw, 1 rec1m, rec1a, rec1g, m2reac COMMON /fnames/ namecf, namerf, nametf, namepf COMMON /saveif/ savecf, saverf SAVE nm1234 = nmin1 + nmin2 + nmin3 + nmin4 nmga = nm1234 + ngas + naqs ***** prompt for / read nreac ***** 1 WRITE(wterm,5) 5 FORMAT(/,' specify number of reactions to be processed: ',/) READ(rterm,*) nreac IF (nreac .LE. 0) GO TO 1 DO 10 ireac = 1,nreac ***** prompt for / read specifications for next reaction ***** WRITE(wterm,15) ireac, nreac 15 FORMAT(/,' input title for reaction ',i3,' of ',i3,':',/) READ(rterm,25) rtitle(ireac) 25 FORMAT(a80) 333 WRITE(wterm,35) ireac 35 FORMAT(/,' enter [coeff species] pairs, separated by' 1 /,' blanks, one pair per line, for reaction ',i3, 2 /,' (conclude with [0 done]) ',/) ibad = 0 m2reac(ireac) = .FALSE. nm(ireac) = 0 ng(ireac) = 0 na(ireac) = 0 nw(ireac) = 0 111 READ(rterm,112) string 112 FORMAT(a80) IF (.NOT. parse(string,coeff,specie)) THEN WRITE(wterm,113) 113 FORMAT(/,' ill-defined [coeff species] pair; ', 1 'try again',/) GO TO 111 END IF IF (coeff .EQ. 0.0d0) THEN ****** reaction stoichiometry complete ****** IF (ibad .NE. 0) THEN CALL wrtbad(ibad,sbad) GO TO 111 ELSE ****** ensure that stoichiometry is correct CALL chkrxn(ireac,namem,namea,nameg, 1 formm,forma,formg,rxnok) IF (.NOT. rxnok) THEN GO TO 333 END IF END IF ELSE ****** determine disposition of current specie: either H2O, ****** found or not found within the current database IF (specie .EQ. 'H2O') THEN nw(ireac) = 1 coefw(ireac) = coeff ELSE IF (match(specie,form,rec1,rec1m1,1,nmga,nm1234)) 1 THEN ****** update [n|coef|rec1][m|g|a]; continue CALL umaker(ireac,coeff,specie,form,rec1, 1 namem,namea,nameg,formm,forma,formg) ELSE ibad = ibad + 1 sbad(ibad) = specie END IF END IF GO TO 111 END IF 10 CONTINUE ****** set wetrxn variable ****** iwet = 0 wetrxn = .FALSE. IF ((isat .EQ. 1) .OR. (iopt .EQ. 1)) THEN wetrxn = .TRUE. iwet = 1 ELSE DO 70 ireac = 1,nreac IF ((nw(ireac) .EQ. 1) .OR. (na(ireac) .GT. 0)) THEN wetrxn = .TRUE. iwet = 1 GO TO 444 END IF 70 CONTINUE END IF ****** save reaction file if desired ****** 444 WRITE(wterm,125) 125 FORMAT(/,' would you like to save these reactions to a file ', 1 '(y/n)',/) READ(rterm,135) ans 135 FORMAT(a1) IF ((ans .NE. 'y') .AND. (ans .NE. 'Y') .AND. 1 (ans .NE. 'n') .AND. (ans .NE. 'N')) GO TO 444 saverf = ((ans .EQ. 'y') .OR. (ans .EQ. 'Y')) IF (saverf) THEN 555 WRITE(wterm,145) 145 FORMAT(/,' specify file name:',/) READ(rterm,155) namerf 155 FORMAT(a20) IF (.NOT. openf(wterm,reacf,namerf,2,1,1,132)) THEN GO TO 555 ELSE *** write generic header WRITE(reacf,205) 205 FORMAT(' Line 1: nreac, iwet',12x, 1 '(free format)') WRITE(reacf,210) 210 FORMAT(' Line 2: [blank]',16x, 1 '(free format)') WRITE(reacf,215) 215 FORMAT(' Line 3: descriptive title',6x, 1 '(a80)') WRITE(reacf,220) 220 FORMAT(' Line 4: nm, na, ng, nw',9x, 1 '(free format)') WRITE(reacf,225) 225 FORMAT(' nm Lines: coeff mname mform',2x, 1 '(1x,f9.3,2x,a20,2x,a30)') WRITE(reacf,230) 230 FORMAT(' ng Lines: coeff aname aform',2x, 1 '(1x,f9.3,2x,a20,2x,a30)') WRITE(reacf,235) 235 FORMAT(' na Lines: coeff gname gform',2x, 1 '(1x,f9.3,2x,a20,2x,a30)') WRITE(reacf,240) 240 FORMAT(' [1 Line: coeff H2O H2O] ',2x, 1 '(1x,f9.3,2x,a20,2x,a30)',/) WRITE(reacf,245) 245 FORMAT('*** each of the nreac reaction blocks',/, 1 '*** contains 3+nm+ng+na+nw lines',/) WRITE(reacf,250) 250 FORMAT(55('*'),/) *** write reaction information WRITE(reacf,165) nreac, iwet 165 FORMAT(2(1x,i3)) END IF DO 80 ireac = 1,nreac WRITE(reacf,175) rtitle(ireac), nm(ireac), 1 na(ireac), ng(ireac), nw(ireac) 175 FORMAT(/,1x,a80,/,4(1x,i3)) IF (nm(ireac) .GT. 0) WRITE(reacf,185) 1 (coefm(ireac,imin), namem(ireac,imin), 2 formm(ireac,imin), imin = 1,nm(ireac)) 185 FORMAT(1x,f9.3,2x,a20,2x,a30) IF (na(ireac) .GT. 0) WRITE(reacf,185) 1 (coefa(ireac,iaqs), namea(ireac,iaqs), 2 forma(ireac,iaqs), iaqs = 1,na(ireac)) IF (ng(ireac) .GT. 0) WRITE(reacf,185) 1 (coefg(ireac,igas), nameg(ireac,igas), 2 formg(ireac,igas), igas = 1,ng(ireac)) IF (nw(ireac) .EQ. 1) WRITE(reacf,195) 1 coefw(ireac), 'H2O ', 2 'H2O ' 195 FORMAT(1x,f9.3,2x,a20,2x,a30) 80 CONTINUE END IF END *************************************************************** *** nxtrec - Get rec1 for next database species. INTEGER FUNCTION nxtrec(irec,mga,nm1234) INTEGER rec1m1, rec1m2, rec1m3, rec1m4, rec1gg, rec1aa COMMON /rlimit/ nmin1, nmin2, nmin3, nmin4, ngas, naqs, 1 rec1m1, rec1m2, rec1m3, rec1m4, rec1gg, rec1aa SAVE IF ((mga .LE. nmin1) .OR. (mga .GT. nm1234)) THEN *** one-phase mineral, gas, or aqueous species nxtrec = irec + 6 RETURN END IF IF (mga .LE. (nmin1 + nmin2)) THEN *** two-phase mineral nxtrec = irec + 7 RETURN END IF IF (mga .LE. (nmin1 + nmin2 + nmin3)) THEN *** three-phase mineral nxtrec = irec + 8 ELSE *** four-phase mineral nxtrec = irec + 9 END IF RETURN END ******************************************************************* *** readrf - Open/read user-specified reaction (RXN) file. SUBROUTINE readrf(nreac,wetrxn) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MAXAQS = 10, MAXGAS = 10, MAXRXN = 800, 1 NPLOTF = 8) CHARACTER*20 namecf, namerf, nametf, spname, namepf(NPLOTF), 1 pfname CHARACTER*30 form CHARACTER*80 rtitle(MAXRXN) LOGICAL openf, wetrxn, m2reac(MAXRXN), savecf, saverf, match INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 rec1m1, rec1m2, rec1m3, rec1m4, rec1gg, rec1aa, outflg INTEGER nm(MAXRXN), na(MAXRXN), ng(MAXRXN), nw(MAXRXN), 1 rec1m(MAXRXN,MAXMIN), rec1a(MAXRXN,MAXAQS), 2 rec1g(MAXRXN,MAXGAS), rec1 DOUBLE PRECISION coefm(MAXRXN,MAXMIN), coefa(MAXRXN,MAXAQS), 1 coefg(MAXRXN,MAXGAS), coefw(MAXRXN) COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /reac1/ rtitle COMMON /reac2/ coefm, coefa, coefg, coefw, nm, na, ng, nw, 1 rec1m, rec1a, rec1g, m2reac COMMON /fnames/ namecf, namerf, nametf, namepf COMMON /saveif/ savecf, saverf COMMON /rlimit/ nmin1, nmin2, nmin3, nmin4, ngas, naqs, 1 rec1m1, rec1m2, rec1m3, rec1m4, rec1gg, rec1aa COMMON /dapron/ pfname SAVE nm1234 = nmin1 + nmin2 + nmin3 + nmin4 nmga = nm1234 + ngas + naqs 1 WRITE(wterm,10) 10 FORMAT(/,' specify name of reaction file:',/) READ(rterm,20) namerf 20 FORMAT(a20) IF (.NOT. openf(wterm,reacf,namerf,1,1,1,132)) GO TO 1 saverf = .TRUE. ***** read number of reactions and their wet/dry character ****** ***** skip first 13 comment lines READ(reacf,25) 25 FORMAT(////////////) READ(reacf,*) nreac, iwet wetrxn = (iwet .EQ. 1) DO 30 ireac = 1,nreac ***** read title, nm, na, ng, nw for next reaction ***** READ(reacf,40) rtitle(ireac) 40 FORMAT(/,1x,a80) READ(reacf,*) nm(ireac), na(ireac), ng(ireac), nw(ireac) ***** read mineral, aqueous species, gas, H2O stoichiometry ***** m2reac(ireac) = .FALSE. IF (nm(ireac) .GT. 0) THEN DO 50 imin = 1,nm(ireac) READ(reacf,51) coefm(ireac,imin), spname, form 51 FORMAT(1x,f9.3,2x,a20,2x,a30) IF (.NOT. match(spname,form,rec1,rec1m1,1, 1 nm1234,nm1234)) THEN GO TO 999 ELSE rec1m(ireac,imin) = rec1 IF (rec1m(ireac,imin) .GE. rec1m2) THEN m2reac(ireac) = .TRUE. END IF END IF 50 CONTINUE END IF IF (na(ireac) .GT. 0) THEN istart = nm1234 + ngas + 1 DO 60 iaqs = 1,na(ireac) READ(reacf,51) coefa(ireac,iaqs), spname, form IF (.NOT. match(spname,form,rec1,rec1aa,istart, 1 nmga,nm1234)) THEN GO TO 999 ELSE rec1a(ireac,iaqs) = rec1 END IF 60 CONTINUE END IF IF (ng(ireac) .GT. 0) THEN istart = nm1234 + 1 iend = nm1234 + ngas DO 70 igas = 1,ng(ireac) READ(reacf,51) coefg(ireac,igas), spname, form IF (.NOT. match(spname,form,rec1,rec1gg,istart, 1 iend,nm1234)) THEN GO TO 999 ELSE rec1g(ireac,igas) = rec1 END IF 70 CONTINUE END IF IF (nw(ireac) .EQ. 0) THEN coefw(ireac) = 0 ELSE READ(reacf,*) coefw(ireac) END IF 30 CONTINUE RETURN 999 WRITE(wterm,1000) ireac, spname, pfname 1000 FORMAT(//,' Reaction ',i3,' species ',a20, 1 /,' not found in database ',a20,/ 1 /,' re-run with correct database or re-create', 2 /,' reaction file from this database.',/) STOP END ************************************************************************ *** wrtbad - Write the list of species not found in database pfname; *** prompt for repeats. SUBROUTINE wrtbad(ibad,sbad) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPLOTF = 8, MAXBAD = 10) INTEGER rterm, wterm, iconf, reacf, pronf, tabf, 1 plotf(NPLOTF), outflg CHARACTER*20 sbad(MAXBAD), pfname COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /dapron/ pfname SAVE WRITE(wterm,45) pfname 45 FORMAT(/,' the following species were not', 1 /,' found in database ',a20,/) DO 20 i = 1,ibad WRITE(wterm,55) sbad(i) 55 FORMAT(5x,a20) 20 CONTINUE WRITE(wterm,65) 65 FORMAT(/,' input new [coeff species] pairs', 1 /,' to replace these incorrect entries', 2 /,' (conclude with [0 done]) ',/) ibad = 0 END ************************************************************************ *** chkrxn - Give the user a chance to look over rxn stoichiometry; *** if it's ok, then rxnok returns .TRUE.; otherwise, *** returns .FALSE. SUBROUTINE chkrxn(ireac,namem,namea,nameg,formm,forma,formg,rxnok) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MAXAQS = 10, MAXGAS = 10, MAXRXN = 800, 1 NPLOTF = 8) CHARACTER*1 ans CHARACTER*20 namem(MAXRXN,MAXMIN), namea(MAXRXN,MAXAQS), 1 nameg(MAXRXN,MAXGAS), namew CHARACTER*30 formm(MAXRXN,MAXMIN), formg(MAXRXN,MAXGAS), 1 forma(MAXRXN,MAXAQS), formw CHARACTER*80 rtitle(MAXRXN) LOGICAL m2reac(MAXRXN), rxnok INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 nm(MAXRXN), na(MAXRXN), ng(MAXRXN), nw(MAXRXN), 2 rec1m(MAXRXN,MAXMIN), rec1a(MAXRXN,MAXAQS), 3 rec1g(MAXRXN,MAXGAS), outflg DOUBLE PRECISION coefm(MAXRXN,MAXMIN), coefa(MAXRXN,MAXAQS), 1 coefg(MAXRXN,MAXGAS), coefw(MAXRXN) COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /reac1/ rtitle COMMON /reac2/ coefm, coefa, coefg, coefw, nm, na, ng, nw, 1 rec1m, rec1a, rec1g, m2reac SAVE DATA namew, formw / 1 'H2O ', 2 'H2O '/ WRITE(wterm,75) ireac 75 FORMAT(/,' reaction ',i3,' stoichiometry:',/) ***** write reactants DO 30 imin = 1,nm(ireac) IF (coefm(ireac,imin) .LT. 0.0d0) THEN WRITE(wterm,85) coefm(ireac,imin), 1 namem(ireac,imin), formm(ireac,imin) 85 FORMAT(6x,f7.3,3x,a20,3x,a30) END IF 30 CONTINUE DO 40 igas = 1,ng(ireac) IF (coefg(ireac,igas) .LT. 0.0d0) THEN WRITE(wterm,86) coefg(ireac,igas), 1 formg(ireac,igas)(1:20), nameg(ireac,igas) 86 FORMAT(6x,f7.3,3x,a20,3x,a20) END IF 40 CONTINUE DO 50 iaqs = 1,na(ireac) IF (coefa(ireac,iaqs) .LT. 0.0d0) THEN WRITE(wterm,85) coefa(ireac,iaqs), 1 namea(ireac,iaqs), forma(ireac,iaqs) END IF 50 CONTINUE IF ((nw(ireac) .EQ. 1) .AND. (coefw(ireac) .LT. 0.0d0)) THEN WRITE(wterm,85) coefw(ireac), namew, formw END IF ***** write products DO 31 imin = 1,nm(ireac) IF (coefm(ireac,imin) .GT. 0.0d0) THEN WRITE(wterm,85) coefm(ireac,imin), 1 namem(ireac,imin), formm(ireac,imin) END IF 31 CONTINUE DO 41 igas = 1,ng(ireac) IF (coefg(ireac,igas) .GT. 0.0d0) THEN WRITE(wterm,86) coefg(ireac,igas), 1 formg(ireac,igas)(1:20), nameg(ireac,igas) END IF 41 CONTINUE DO 51 iaqs = 1,na(ireac) IF (coefa(ireac,iaqs) .GT. 0.0d0) THEN WRITE(wterm,85) coefa(ireac,iaqs), 1 namea(ireac,iaqs), forma(ireac,iaqs) END IF 51 CONTINUE IF ((nw(ireac) .EQ. 1) .AND. (coefw(ireac) .GT. 0.0d0)) THEN WRITE(wterm,85) coefw(ireac), namew, formw END IF 222 WRITE(wterm,95) 95 FORMAT(/,' is this correct? (y/n)',/) READ(rterm,105) ans 105 FORMAT(a1) IF ((ans .NE. 'Y') .AND. (ans .NE. 'y') .AND. 1 (ans .NE. 'N') .AND. (ans .NE. 'n')) THEN GO TO 222 ELSE rxnok = ((ans .EQ. 'Y') .OR. (ans .EQ. 'y')) END IF END ******************************************************************* *** match - Returns .TRUE. (and rec1sp) if specie is found in *** database pfname; otherwise returns .FALSE. LOGICAL FUNCTION match(specie,form,rec1sp,rec1ty,first,last, 1 nm1234) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPLOTF = 8) CHARACTER*20 specie, name CHARACTER*30 form INTEGER rterm, wterm, iconf, reacf, pronf, tabf, 1 plotf(NPLOTF), rec1sp, rec1ty, first, last, 2 outflg COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg SAVE irec = rec1ty DO 60 mga = first,last READ(pronf,115,REC=irec) name, form 115 FORMAT(1x,a20,a30) IF (specie .EQ. name) THEN match = .TRUE. rec1sp = irec RETURN ELSE irec = nxtrec(irec,mga,nm1234) END IF 60 CONTINUE match = .FALSE. RETURN END ******************************************************************* *** umaker - Update /reac/ arrays to include current species. SUBROUTINE umaker(ireac,coeff,specie,form,rec1, 1 namem,namea,nameg,formm,forma,formg) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MAXAQS = 10, MAXGAS = 10, MAXRXN = 800) CHARACTER*20 specie, namem(MAXRXN,MAXMIN), namea(MAXRXN,MAXAQS), 1 nameg(MAXRXN,MAXGAS) CHARACTER*30 form, formm(MAXRXN,MAXMIN), formg(MAXRXN,MAXGAS), 1 forma(MAXRXN,MAXAQS) CHARACTER*80 rtitle(MAXRXN) LOGICAL m2reac(MAXRXN) INTEGER nm(MAXRXN), na(MAXRXN), ng(MAXRXN), nw(MAXRXN), 2 rec1m(MAXRXN,MAXMIN), rec1a(MAXRXN,MAXAQS), 3 rec1g(MAXRXN,MAXGAS), 4 rec1m1, rec1m2, rec1m3, rec1m4, rec1gg, rec1aa, rec1 DOUBLE PRECISION coefm(MAXRXN,MAXMIN), coefa(MAXRXN,MAXAQS), 1 coefg(MAXRXN,MAXGAS), coefw(MAXRXN) COMMON /rlimit/ nmin1, nmin2, nmin3, nmin4, ngas, naqs, 1 rec1m1, rec1m2, rec1m3, rec1m4, rec1gg, rec1aa COMMON /reac1/ rtitle COMMON /reac2/ coefm, coefa, coefg, coefw, nm, na, ng, nw, 1 rec1m, rec1a, rec1g, m2reac SAVE IF (rec1 .GE. rec1aa) THEN na(ireac) = na(ireac) + 1 coefa(ireac,na(ireac)) = coeff rec1a(ireac,na(ireac)) = rec1 namea(ireac,na(ireac)) = specie forma(ireac,na(ireac)) = form RETURN END IF IF (rec1 .GE. rec1gg) THEN ng(ireac) = ng(ireac) + 1 coefg(ireac,ng(ireac)) = coeff rec1g(ireac,ng(ireac)) = rec1 nameg(ireac,ng(ireac)) = specie formg(ireac,ng(ireac)) = form ELSE nm(ireac) = nm(ireac) + 1 coefm(ireac,nm(ireac)) = coeff rec1m(ireac,nm(ireac)) = rec1 namem(ireac,nm(ireac)) = specie formm(ireac,nm(ireac)) = form IF (rec1 .GE. rec1m2) THEN m2reac(ireac) = .TRUE. END IF END IF RETURN END ************************************************************************ *** openf - Returns .TRUE. and opens the file specified by fname, *** fstat, facces, fform, and frecl if this file exists and is *** accessible; otherwise, returns .FALSE. and prints an *** appropriate error message to the device specified by iterm. *** LOGICAL FUNCTION openf(iterm,iunit,fname,istat,iacces,iform,irecl) CHARACTER*11 fform(2) CHARACTER*10 facces(2) CHARACTER*20 fname CHARACTER*3 fstat(2) SAVE DATA fform / 'FORMATTED ', 'UNFORMATTED' / DATA facces / 'SEQUENTIAL', 'DIRECT ' / DATA fstat / 'OLD', 'NEW' / openf = .FALSE. IF ((iacces .LT. 1) .OR. (iacces .GT. 2) .OR. 1 (iform .LT. 1) .OR. (iform .GT. 2) .OR. 2 (istat .LT. 1) .OR. (istat .GT. 2)) GO TO 10 IF (iacces .EQ. 1) THEN OPEN(UNIT=iunit,FILE=fname,ACCESS=facces(iacces), 1 FORM=fform(iform),STATUS=fstat(istat),ERR=10) openf = .TRUE. RETURN ELSE OPEN(UNIT=iunit,FILE=fname,ACCESS=facces(iacces), 1 FORM=fform(iform),STATUS=fstat(istat),RECL=irecl, 2 ERR=10) openf = .TRUE. RETURN END IF 10 WRITE(iterm,20) 20 FORMAT(/,' nonexistant file or invalid specifications', 1 ' ... try again',/) RETURN END *** rep92 - Collection of routines that write the calculated standard *** molal thermodynamic properties of reactions to the TAB *** file and, optionally, the PLOT files. *** ********************************************************************* *** *** Author: James W. Johnson *** Earth Sciences Department, L-219 *** Lawrence Livermore National Laboratory *** Livermore, CA 94550 *** johnson@s05.es.llnl.gov *** *** Abandoned: 8 November 1991 *** ********************************************************************* *** tabtop - Write global header for output file. SUBROUTINE tabtop IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXOdd = 3000, NPLOTF = 8) LOGICAL savecf, saverf INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 mapiso(2,3), mapinc(2,3), mapv3(2,3), 2 univar, useLVS, epseqn, geqn, xyplot, end, 3 outflg DOUBLE PRECISION isomin, isomax, isoinc, Kmin, Kmax, Kinc, 1 oddv1(MAXODD), oddv2(MAXODD) CHARACTER*4 incvar(2,3) CHARACTER*10 isov(2,3), incv(2,3), var3(2,3), isosat(2) CHARACTER*12 isovar(2,3) CHARACTER*20 pfname, namecf, namerf, nametf, namepf(NPLOTF), 1 nosave COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /dapron/ pfname COMMON /stvars/ isosat, isovar, incvar COMMON /TPDmap/ mapiso, mapinc, mapv3 COMMON /headmp/ isov, incv, var3 COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /grid/ isomin, isomax, isoinc, v2min, v2max, v2inc, 2 oddv1, oddv2, Kmin, Kmax, Kinc, niso, nv2, nlogK COMMON /fnames/ namecf, namerf, nametf, namepf COMMON /saveif/ savecf, saverf COMMON /plottr/ xyplot, end, nplots SAVE DATA nosave / 'file not saved ' / IF (outflg.eq.2) Then If (iplot.eq.1) then WRITE(tabf,71) 'Name ',isov(iopt,iplot), 1 incv(iopt,iplot),' TEMP(K) ' 71 FORMAT(A8,12x,2x,a10,2x,a10,4x,a10, 1 2x,' LOG_K DG(cal) DH(cal)', 2 ' DS(cal/K)') endif If (iplot.eq.2.or.iplot.eq.3) then WRITE(tabf,73) 'Name ',isov(iopt,iplot),' TEMP(K) ', 1 incv(iopt,iplot) 73 FORMAT(A8,12x,2x,a10,2x,a10,2x,a10, 1 2x,' LOG_K DG(cal) DH(cal)', 2 ' DS(cal/K)') endif else WRITE(tabf,5) 5 FORMAT(' ***** SUPCRT92: input/output specifications for', 1 ' this run',/) IF (savecf) THEN WRITE(tabf,15) namecf ELSE WRITE(tabf,15) nosave END IF 15 FORMAT( ' USER-SPECIFIED CON FILE containing ', 1 /,' T-P-D grid & option switches: ',a20,/) IF (saverf) THEN WRITE(tabf,25) namerf ELSE WRITE(tabf,25) nosave END IF 25 FORMAT( ' USER-SPECIFIED RXN FILE containing ', 1 /,' chemical reactions: ',a20,/) WRITE(tabf,35) pfname 35 FORMAT( ' THERMODYNAMIC DATABASE: ',a20,/) WRITE(tabf,45) nametf 45 FORMAT( ' SUPCRT-GENERATED TAB FILE containing ', 1 /,' tabulated reaction properties ', 2 '(this file): ',a20) IF (xyplot .GT. 0) THEN WRITE(tabf,47) namepf(1) 47 FORMAT(/,' SUPCRT-GENERATED PLT FILES containing ', 1 /,' reaction properties for x-y plots: ' 2 ,a20,' etc.') END IF CALL wrtopt endif END ******************************************************************* *** wrtopt - Write various switch options to tabular output file. SUBROUTINE wrtopt IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXOdd = 3000, NPLOTF = 8) INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 2 univar, useLVS, epseqn, geqn, outflg DOUBLE PRECISION isomin, isomax, isoinc, Kmin, Kmax, Kinc, 1 oddv1(MAXODD), oddv2(MAXODD) CHARACTER*4 incvar(2,3) CHARACTER*10 isov(2,3), incv(2,3), var3(2,3), isosat(2) CHARACTER*12 isovar(2,3) CHARACTER*20 namecf, namerf, nametf, namepf(NPLOTF) COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /stvars/ isosat, isovar, incvar COMMON /headmp/ isov, incv, var3 COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /grid/ isomin, isomax, isoinc, v2min, v2max, v2inc, 2 oddv1, oddv2, Kmin, Kmax, Kinc, niso, nv2, nlogK COMMON /fnames/ namecf, namerf, nametf, namepf SAVE WRITE(tabf,75) 75 FORMAT(/,' ***** summary of option switches ') WRITE(tabf,85) isat,iopt,iplot,univar,noninc 85 FORMAT( ' isat, iopt, iplot, univar, noninc: ',4i3,i4) *** useLVS, epseqn, geqn not written to TAB for distribution copies *** * WRITE(tabf,105) useLVS,epseqn,geqn * 105 FORMAT( ' useLVS, epseqn, geqn: ',3i3) WRITE(tabf,115) 115 FORMAT(/,' ***** summary of state conditions ') IF (noninc .EQ. 0) THEN IF (isat .EQ. 0) THEN WRITE(tabf,125) isovar(iopt,iplot),isomin,isomax,isoinc 125 FORMAT(12x,'ISO',a12,': min, max, increment:', 1 3(2x,f10.4)) WRITE(tabf,135) incv(iopt,iplot),v2min, v2max, v2inc 135 FORMAT(12x,a10,' range: min, max, increment:', 1 3(2x,f10.4)) ELSE WRITE(tabf,145) isosat(iopt),v2min, v2max, v2inc 145 FORMAT(12x,'saturation ',a10,' range: min, max,', 1 ' increment:',3(2x,f10.4)) END IF ELSE IF (isat .EQ. 0) THEN WRITE(tabf,155) isov(iopt,iplot), incv(iopt,iplot), 1 noninc 155 FORMAT(12x,'nonincremental ',a10,', ',a10, 1 ' coordinates: ',i3,' pair') ELSE WRITE(tabf,165) isosat(iopt), noninc 165 FORMAT(12x,'nonincremental saturation ',a10,': ',i3, 1 ' points') END IF END IF END ********************************************************************* *** wrtop2 - Write various switch options to plot file k. SUBROUTINE wrtop2(k) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXOdd = 3000, NPLOTF = 8) INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 2 univar, useLVS, epseqn, geqn, outflg DOUBLE PRECISION isomin, isomax, isoinc, Kmin, Kmax, Kinc, 1 oddv1(MAXODD), oddv2(MAXODD) CHARACTER*4 incvar(2,3) CHARACTER*10 isov(2,3), incv(2,3), var3(2,3), isosat(2) CHARACTER*12 isovar(2,3) CHARACTER*20 namecf, namerf, nametf, namepf(NPLOTF) COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /stvars/ isosat, isovar, incvar COMMON /headmp/ isov, incv, var3 COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /grid/ isomin, isomax, isoinc, v2min, v2max, v2inc, 2 oddv1, oddv2, Kmin, Kmax, Kinc, niso, nv2, nlogK COMMON /fnames/ namecf, namerf, nametf, namepf SAVE WRITE(plotf(k),75) 75 FORMAT(/,' ***** summary of option switches ',/) WRITE(plotf(k),85) isat,iopt,iplot,univar,noninc 85 FORMAT( ' isat, iopt, iplot, univar, noninc: ',4i3,i4) *** useLVS, epseqn, geqn not written to PLOT for distribution copies *** * WRITE(plotf(k),105) useLVS,epseqn,geqn * 105 FORMAT( ' useLVS, epseqn, geqn: ',3i3) WRITE(plotf(k),115) 115 FORMAT(/,' ***** summary of state conditions ',/) IF (noninc .EQ. 0) THEN IF (isat .EQ. 0) THEN WRITE(plotf(k),125) isovar(iopt,iplot), 1 isomin,isomax,isoinc 125 FORMAT(12x,'ISO',a12,': min, max, increment:', 1 3(2x,f10.4)) WRITE(plotf(k),135) incv(iopt,iplot),v2min, v2max, v2inc 135 FORMAT(12x,a10,' range: min, max, increment:', 1 3(2x,f10.4)) ELSE WRITE(plotf(k),145) isosat(iopt),v2min, v2max, v2inc 145 FORMAT(12x,'saturation ',a10,' range: min, max,', 1 ' increment:',3(2x,f10.4)) END IF ELSE IF (isat .EQ. 0) THEN WRITE(plotf(k),155) isov(iopt,iplot), incv(iopt,iplot), 1 noninc 155 FORMAT(12x,'nonincremental ',a10,', ',a10, 1 ' coordinates: ',i3,' pair') ELSE WRITE(plotf(k),165) isosat(iopt), noninc 165 FORMAT(12x,'nonincremental saturation ',a10,': ',i3, 1 ' points') END IF END IF WRITE(plotf(k),175) 175 FORMAT(/,86('*')) END *************************************************************** *** wrtrxn - Write header information for the i[th] reaction to *** tabulated output file tabf and (if appropriate) to *** the plot files. SUBROUTINE wrtrxn(i) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MAXGAS = 10, MAXAQS = 10, 1 MXTRAN = 3, IABC = 4, MAXRXN = 800, NPLOTF = 8) CHARACTER*4 incvar(2,3) CHARACTER*10 isov(2,3), incv(2,3), var3(2,3), isosat(2) CHARACTER*12 isovar(2,3) CHARACTER*20 mname(MAXMIN), gname(MAXGAS), aname(MAXAQS) CHARACTER*30 mform(MAXMIN), gform(MAXGAS), aform(MAXAQS) CHARACTER*80 rtitle(MAXRXN) LOGICAL m2reac(MAXRXN), nullrx INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 univar, useLVS, epseqn, geqn, xyplot, end, outflg INTEGER nm(MAXRXN), na(MAXRXN), ng(MAXRXN), nw(MAXRXN), 1 rec1m(MAXRXN,MAXMIN), rec1a(MAXRXN,MAXAQS), 2 rec1g(MAXRXN,MAXGAS) INTEGER ntran(MAXMIN) DOUBLE PRECISION coefm(MAXRXN,MAXMIN), coefa(MAXRXN,MAXAQS), 1 coefg(MAXRXN,MAXGAS), coefw(MAXRXN) DOUBLE PRECISION Gfmin(MAXMIN), Hfmin(MAXMIN), 1 VPrTrm(MAXMIN), SPrTrm(MAXMIN), 3 MK1(IABC,MAXMIN), MK2(IABC,MAXMIN), 4 MK3(IABC,MAXMIN), MK4(IABC,MAXMIN), 5 Ttran(MXTRAN,MAXMIN), Htran(MXTRAN,MAXMIN), 6 Vtran(MXTRAN,MAXMIN), dPdTtr(MXTRAN,MAXMIN), 7 Tmaxm(MAXMIN) DOUBLE PRECISION Gfgas(MAXGAS), Hfgas(MAXGAS), VPrTrg(MAXGAS), 1 SPrTrg(MAXGAS), MKg(IABC,MAXGAS), Tmaxg(MAXGAS) DOUBLE PRECISION Gfaqs(MAXAQS), Hfaqs(MAXAQS), SPrTra(MAXAQS), 1 a(4,MAXAQS), c(2,MAXAQS), 2 wref(MAXAQS), chg(MAXAQS) COMMON /stvars/ isosat, isovar, incvar COMMON /headmp/ isov, incv, var3 COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /reac1/ rtitle COMMON /reac2/ coefm, coefa, coefg, coefw, nm, na, ng, nw, 1 rec1m, rec1a, rec1g, m2reac COMMON /mnames/ mname, mform COMMON /minref/ Gfmin, Hfmin, SPrTrm, VPrTrm, MK1, MK2, MK3, MK4, 1 Ttran, Htran, Vtran, dPdTtr, Tmaxm, ntran COMMON /gnames/ gname, gform COMMON /gasref/ Gfgas, Hfgas, SPrTrg, VPrTrg, MKg, Tmaxg COMMON /anames/ aname, aform COMMON /aqsref/ Gfaqs, Hfaqs, SPrTra, c, a, wref, chg COMMON /plottr/ xyplot, end, nplots SAVE ***** write header to TAB file ***** IF (outflg.ne.2) WRITE(tabf,5) i 5 FORMAT(/,36('*'),' REACTION ',i3,2x,36('*'),/) ***** write reaction title and stoichiometry to TAB file ***** IF (outflg.ne.2) WRITE(tabf,15) rtitle(i) 15 FORMAT(' REACTION TITLE: ',/,6x,a80) IF (outflg.eq.2) goto 41 WRITE(tabf,25) 25 FORMAT(/,' REACTION STOICHIOMETRY: ') WRITE(tabf,26) 26 FORMAT(8x,' COEFF.',3x,'NAME',16x,3x,'FORMULA',22x,/, 3 8x,7('-'),3x,20('-'),3x,20('-')) ***** write reactants ***** IF (nm(i) .GT. 0) THEN DO 10 j = 1,nm(i) IF (coefm(i,j) .LT. 0.0d0) THEN WRITE(tabf,35) coefm(i,j), mname(j), mform(j) 35 FORMAT(6x,f9.3,3x,a20,3x,a30) END IF 10 CONTINUE END IF IF (ng(i) .GT. 0) THEN DO 20 j = 1,ng(i) IF (coefg(i,j) .LT. 0.0d0) THEN WRITE(tabf,36) coefg(i,j), gform(j)(1:20), gname(j) 36 FORMAT(6x,f9.3,3x,a20,3x,a20) END IF 20 CONTINUE END IF IF (na(i) .GT. 0) THEN DO 30 j = 1,na(i) IF (coefa(i,j) .LT. 0.0d0) THEN WRITE(tabf,35) coefa(i,j), aname(j), aform(j) END IF 30 CONTINUE END IF IF ((nw(i) .GT. 0) .AND. (coefw(i) .LT. 0.0d0)) THEN WRITE(tabf,55) coefw(i) 55 FORMAT(6x,f9.3,3x,'H2O',17x,3x,'H2O') END IF ***** write products ***** IF (nm(i) .GT. 0) THEN DO 11 j = 1,nm(i) IF (coefm(i,j) .GT. 0.0d0) THEN WRITE(tabf,35) coefm(i,j), mname(j), mform(j) END IF 11 CONTINUE END IF IF (ng(i) .GT. 0) THEN DO 21 j = 1,ng(i) IF (coefg(i,j) .GT. 0.0d0) THEN WRITE(tabf,36) coefg(i,j), gform(j)(1:20), gname(j) END IF 21 CONTINUE END IF IF (na(i) .GT. 0) THEN DO 31 j = 1,na(i) IF (coefa(i,j) .GT. 0.0d0) THEN WRITE(tabf,35) coefa(i,j), aname(j), aform(j) END IF 31 CONTINUE END IF IF ((nw(i) .GT. 0) .AND. (coefw(i) .GT. 0.0d0)) THEN WRITE(tabf,55) coefw(i) END IF 41 Continue ***** write standard state properties, equation-of-state ***** parameters, and heat capacity coefficients CALL wrtssp(i) ***** write header for property tabulation ***** IF (outflg.ne.2) WRITE(tabf,65) 65 FORMAT(/,' STANDARD STATE PROPERTIES OF THE REACTION', 1 ' AT ELEVATED TEMPERATURES AND PRESSURES ') CALL zero(i,nullrx) IF (nullrx) THEN WRITE(tabf,888) 888 FORMAT(' CAUTION: INCOMPLETE DATA FOR ONE OR MORE SPECIES',//) END IF IF (outflg.ne.2) Then WRITE(tabf,75) isov(iopt,iplot), 1 incv(iopt,iplot), 1 var3(iopt,iplot) 75 FORMAT(50x,' DELTA G ',1x, 1 1x,' DELTA H ',1x, 1 1x,' DELTA S ',1x, 1 1x,' DELTA V ',1x, 1 ' DELTA Cp ',1x,/, 1 2x,a10,2x,a10,2x,a10, 1 2x,' LOG K ',1x, 2 1x,' (cal) ',1x, 3 1x,' (cal) ',1x, 4 1x,' (cal/K) ',1x, 5 1x,' (cc) ',1x, 6 1x,' (cal/K) ',1x,/, 7 3(2x,10('-')),1x,6(1x,10('-'),1x)) Endif IF (xyplot .GT. 0) CALL pltrxn(i) END ***************************************************************** ***** zero - Zero-out NULL values for reaction i to eliminate their ***** contribution to standard molal properties at elevated ***** temperatures and pressures; set nullrx to .TRUE. if Gf ***** missing for mineral species or a1..4 for aqueous species. SUBROUTINE zero(i,nullrx) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MAXGAS = 10, MAXAQS = 10, MXTRAN = 3, 1 IABC = 4, MAXRXN = 800) CHARACTER*20 mname(MAXMIN), aname(MAXAQS) CHARACTER*30 mform(MAXMIN), aform(MAXAQS) CHARACTER*80 rtitle(MAXRXN) LOGICAL m2reac(MAXRXN), nullrx INTEGER nm(MAXRXN), na(MAXRXN), ng(MAXRXN), nw(MAXRXN), 1 rec1m(MAXRXN,MAXMIN), rec1a(MAXRXN,MAXAQS), 2 rec1g(MAXRXN,MAXGAS) INTEGER ntran(MAXMIN) DOUBLE PRECISION coefm(MAXRXN,MAXMIN), coefa(MAXRXN,MAXAQS), 1 coefg(MAXRXN,MAXGAS), coefw(MAXRXN) DOUBLE PRECISION Gfmin(MAXMIN), Hfmin(MAXMIN), 1 VPrTrm(MAXMIN), SPrTrm(MAXMIN), 3 MK1(IABC,MAXMIN), MK2(IABC,MAXMIN), 4 MK3(IABC,MAXMIN), MK4(IABC,MAXMIN), 5 Ttran(MXTRAN,MAXMIN), Htran(MXTRAN,MAXMIN), 6 Vtran(MXTRAN,MAXMIN), dPdTtr(MXTRAN,MAXMIN), 7 Tmaxm(MAXMIN) DOUBLE PRECISION Gfaqs(MAXAQS), Hfaqs(MAXAQS), SPrTra(MAXAQS), 1 a(4,MAXAQS), c(2,MAXAQS), 2 wref(MAXAQS), chg(MAXAQS) COMMON /reac1/ rtitle COMMON /reac2/ coefm, coefa, coefg, coefw, nm, na, ng, nw, 1 rec1m, rec1a, rec1g, m2reac COMMON /mnames/ mname, mform COMMON /minref/ Gfmin, Hfmin, SPrTrm, VPrTrm, MK1, MK2, MK3, MK4, 1 Ttran, Htran, Vtran, dPdTtr, Tmaxm, ntran COMMON /anames/ aname, aform COMMON /aqsref/ Gfaqs, Hfaqs, SPrTra, c, a, wref, chg COMMON /null/ XNULLM, XNULLA SAVE nullrx = .FALSE. DO 10 j = 1,nm(i) IF (Gfmin(j) .EQ. XNULLM) THEN nullrx = .TRUE. Gfmin(j) = 0.0d0 Hfmin(j) = 0.0d0 END IF IF (ntran(j) .GT. 0) THEN DO 20 k = 1,ntran(j) IF (Htran(k,j) .EQ. XNULLM) THEN Htran(k,j) = 0.0d0 END IF IF (Vtran(k,j) .EQ. XNULLM) THEN Vtran(k,j) = 0.0d0 END IF IF (dPdTtr(k,j) .EQ. XNULLM) THEN dPdTtr(k,j) = 0.0d0 END IF 20 CONTINUE END IF 10 CONTINUE DO 30 j = 1,na(i) IF (a(3,j) .EQ. XNULLA) THEN nullrx = .TRUE. DO 40 k = 1,4 a(k,i) = 0.0d0 40 CONTINUE END IF 30 CONTINUE END ***************************************************************** *** wrtssp - Write, to tabf, standard molal thermodynamic *** properties at 25 C and 1 bar, equation-of-state *** parameters, and heat capacity coefficients for all *** species in the i[th] reaction. SUBROUTINE wrtssp(i) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MAXGAS = 10, MAXAQS = 10, MAXRXN = 800, 1 MXTRAN = 3, IABC = 4, MAXMK = 4, NPLOTF = 8, 2 ACON = 1.0d0, BCON = 1.0d3, CCON = 1.0d-5, 3 A1CON = 1.0d1, A2CON = 1.0d-2, 4 A3CON = 1.0d0, A4CON = 1.0d-4, 5 C1CON = 1.0d0, C2CON = 1.0d-4, 6 WCON = 1.0d-5) CHARACTER*4 incvar(2,3) CHARACTER*10 isov(2,3), incv(2,3), var3(2,3), isosat(2) CHARACTER*12 isovar(2,3) CHARACTER*20 mname(MAXMIN), gname(MAXGAS), aname(MAXAQS), 1 wname CHARACTER*30 mform(MAXMIN), gform(MAXGAS), aform(MAXAQS) CHARACTER*80 rtitle(MAXRXN) LOGICAL m2reac(MAXRXN), nullrx INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 univar, useLVS, epseqn, geqn, 2 mapiso(2,3), mapinc(2,3), mapv3(2,3), outflg INTEGER nm(MAXRXN), na(MAXRXN), ng(MAXRXN), nw(MAXRXN), 1 rec1m(MAXRXN,MAXMIN), rec1a(MAXRXN,MAXAQS), 2 rec1g(MAXRXN,MAXGAS), phaser(MAXMIN) INTEGER ntran(MAXMIN) DOUBLE PRECISION logKr, TPDref(4) DOUBLE PRECISION coefm(MAXRXN,MAXMIN), coefa(MAXRXN,MAXAQS), 1 coefg(MAXRXN,MAXGAS), coefw(MAXRXN) DOUBLE PRECISION Gfmin(MAXMIN), Hfmin(MAXMIN), 1 VPrTrm(MAXMIN), SPrTrm(MAXMIN), 3 MK1(IABC,MAXMIN), MK2(IABC,MAXMIN), 4 MK3(IABC,MAXMIN), MK4(IABC,MAXMIN), 5 Ttran(MXTRAN,MAXMIN), Htran(MXTRAN,MAXMIN), 6 Vtran(MXTRAN,MAXMIN), dPdTtr(MXTRAN,MAXMIN), 7 Tmaxm(MAXMIN) DOUBLE PRECISION Gfgas(MAXGAS), Hfgas(MAXGAS), VPrTrg(MAXGAS), 1 SPrTrg(MAXGAS), MKg(IABC,MAXGAS), Tmaxg(MAXGAS) DOUBLE PRECISION Gfaqs(MAXAQS), Hfaqs(MAXAQS), SPrTra(MAXAQS), 1 a(4,MAXAQS), c(2,MAXAQS), 2 wref(MAXAQS), chg(MAXAQS) DOUBLE PRECISION Vmin(MAXMIN), Smin(MAXMIN), Cpmin(MAXMIN), 2 Hmin(MAXMIN), Gmin(MAXMIN) DOUBLE PRECISION Vgas(MAXGAS), Sgas(MAXGAS), Cpgas(MAXGAS), 2 Hgas(MAXGAS), Ggas(MAXGAS) DOUBLE PRECISION Vaqs(MAXAQS), Saqs(MAXAQS), Cpaqs(MAXAQS), 2 Haqs(MAXAQS), Gaqs(MAXAQS), 3 VQterm(MAXAQS), SYterm(MAXAQS), CpXtrm(MAXAQS), 4 HYterm(MAXAQS), GZterm(MAXAQS) DOUBLE PRECISION mwH2O, Gftemp(MAXMIN), Hftemp(MAXMIN), 1 a3temp(MAXAQS) COMMON /stvars/ isosat, isovar, incvar COMMON /headmp/ isov, incv, var3 COMMON /TPDmap/ mapiso, mapinc, mapv3 COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr COMMON /reac1/ rtitle COMMON /reac2/ coefm, coefa, coefg, coefw, nm, na, ng, nw, 1 rec1m, rec1a, rec1g, m2reac COMMON /mnames/ mname, mform COMMON /minref/ Gfmin, Hfmin, SPrTrm, VPrTrm, MK1, MK2, MK3, MK4, 1 Ttran, Htran, Vtran, dPdTtr, Tmaxm, ntran COMMON /gnames/ gname, gform COMMON /gasref/ Gfgas, Hfgas, SPrTrg, VPrTrg, MKg, Tmaxg COMMON /anames/ aname, aform COMMON /aqsref/ Gfaqs, Hfaqs, SPrTra, c, a, wref, chg COMMON /H2Oss/ Dwss, Vwss, bewss, alwss, dalwss, Swss, 1 Cpwss, Hwss, Gwss, Zwss, Qwss, Ywss, Xwss COMMON /minsp/ Vmin, Smin, Cpmin, Hmin, Gmin, phaser COMMON /gassp/ Vgas, Sgas, Cpgas, Hgas, Ggas COMMON /aqsp/ Vaqs, Saqs, Cpaqs, Haqs, Gaqs COMMON /solvn/ VQterm, SYterm, CpXtrm, HYterm, GZterm COMMON /fmeq/ dVr, dSr, dCpr, dHr, dGr, logKr, dlogKT, dlogKP COMMON /null/ XNULLM, XNULLA SAVE DATA wname / 'H2O ' / ***** remove NULL contributions to standard state calculations nullrx = .FALSE. DO 456 iii = 1, nm(i) Gftemp(iii) = 0.0d0 IF (Gfmin(iii) .EQ. XNULLM) THEN nullrx = .TRUE. Gftemp(iii) = Gfmin(iii) Hftemp(iii) = Hfmin(iii) Gfmin(iii) = 0.0d0 Hfmin(iii) = 0.0d0 END IF 456 CONTINUE DO 556 iii = 1, na(i) a3temp(iii) = 0.0d0 IF (a(3,iii) .EQ. XNULLA) THEN nullrx = .TRUE. a3temp(iii) = a(3,iii) DO 557 jjj = 1,4 a(jjj,iii) = 0.0d0 557 CONTINUE END IF 556 CONTINUE ***** calculate all reaction species heat capacities and reactant ***** aqueous species standard partial molal volumes at ***** 25 degC, 1 bar CALL reac92(i,Pref,Tref-273.15d0,Dwss,Vwss,bewss,alwss,dalwss, 1 Swss,Cpwss,Hwss,Gwss,Zwss,Qwss,Ywss,Xwss,geqn) ***** return NULL contributions to faciltate blanking DO 457 iii = 1, nm(i) IF (Gftemp(iii) .EQ. XNULLM) THEN Gfmin(iii) = Gftemp(iii) Hfmin(iii) = Hftemp(iii) END IF 457 CONTINUE DO 656 iii = 1, na(i) IF (a3temp(iii) .EQ. XNULLA) a(3,iii) = a3temp(iii) 656 CONTINUE IF (outflg.eq.2) goto 989 WRITE(tabf,5) 5 FORMAT(/,' STANDARD STATE PROPERTIES OF THE SPECIES AT', 1 ' 25 DEG C AND 1 BAR') IF (nm(i) .GT. 0) THEN WRITE(tabf,6) 6 FORMAT(/,42x,' ...... MINERALS ...... ',/, 1 24x,' DELTA G ',1x, 1 1x,' DELTA H ',1x, 1 1x,' S ',1x, 1 1x,' V ',1x, 1 1x,' Cp ',1x,/, 1 7x,'NAME',12x, 1 1x,' (cal/mol) ',1x, 2 1x,' (cal/mol) ',1x, 3 1x,' (cal/mol/K) ',1x, 4 1x,' (cc/mol) ',1x, 5 1x,' (cal/mol/K) ',/, 6 2x,20('-'),2x,13('-'),2x,13('-'),2x,13('-'), 7 2x,13('-'),2x,13('-')) ***** write mineral G, H, S, V, Cp at 25 C, 1 bar ***** DO 10 j = 1,nm(i) IF (Gfmin(j) .EQ. XNULLM) THEN WRITE(tabf,14) mname(j), SPrTrm(j), 1 VPrTrm(j), Cpmin(j) 14 FORMAT(2x,a20,30x,5x,f8.3,3x,4x,f8.3,4x,4x,f6.1,6x) ELSE WRITE(tabf,15) mname(j), Gfmin(j), Hfmin(j), 1 SPrTrm(j), VPrTrm(j), Cpmin(j) 15 FORMAT(2x,a20,3x,f10.0,2x,3x,f10.0,2x,5x,f8.3,3x, 1 4x,f8.3,4x,4x,f6.1,6x) END IF 10 CONTINUE WRITE(tabf,7) 7 FORMAT(/,24x,' HEAT CAPACITY COEFFICIENTS ', 1 32x,'PHASE TRANSITION DATA',/, 1 7x,'NAME',11x, 1 1x,' a(10**0) ', 2 ' b(10**3) ', 3 ' c(10**-5) ', 3 1x,' d(10**0) ', 4 1x,' T limit (C)', 5 1x,' Htr (cal/mol)',1x, 6 1x,' Vtr (cc/mol) ',1x, 7 1x,'dPdTtr (bar/K)',1x,/, 8 2x,20('-'), 9 2x,10('-'),1x, 1 1x,10('-'),1x, 1 1x,10('-'),1x, 1 1x,12('-'),1x, 2 1x,11('-'),1x, 3 1x,13('-'),1x, 4 1x,14('-'),1x, 5 1x,14('-'),1x) DO 11 j = 1,nm(i) ***** write mineral heat capacity coefficients ***** a, b, c, d and phase transition T, H, V, dPdT IF (ntran(j) .EQ. 0) THEN WRITE(tabf,16) mname(j), MK1(1,j)*ACON, 1 MK1(2,j)*BCON, MK1(3,j)*CCON, 2 MK1(4,j)*ACON, 3 Tmaxm(j)-273.15d0 16 FORMAT(2x,a20,1x,f9.3,2x,1x,f9.3,2x,1x,f9.3, 1 2x,1x,f11.3,2x,3x,f7.2) ELSE *** following block IFs designed to eliminate *** printing of unknown (i.e., zero-valued) *** Htran, Vtran, dPdTtr. IF (Htran(1,j) .EQ. XNULLM) THEN WRITE(tabf,19) mname(j), MK1(1,j)*ACON, 1 MK1(2,j)*BCON, MK1(3,j)*CCON, 2 MK1(4,j)*ACON, 3 Ttran(1,j)-273.15d0 19 FORMAT(2x,a20,1x,f9.3,2x,1x,f9.3,2x,1x,f9.3, 1 2x,1x,f11.3,2x,3x,f7.2,3x) ELSE IF (Vtran(1,j) .EQ. XNULLM) THEN WRITE(tabf,119) mname(j), MK1(1,j)*ACON, 1 MK1(2,j)*BCON, MK1(3,j)*CCON, 2 MK1(4,j)*ACON, 2 Ttran(1,j)-273.15d0, Htran(1,j) 119 FORMAT(2x,a20,1x,f9.3,2x,1x,f9.3,2x,1x,f9.3, 1 2x,1x,f11.3, 1 2x,3x,f7.2,3x,5x,f6.0,5x) ELSE WRITE(tabf,219) mname(j), MK1(1,j)*ACON, 1 MK1(2,j)*BCON, MK1(3,j)*CCON, 2 MK1(4,j)*ACON, 2 Ttran(1,j)-273.15d0, Htran(1,j), 3 Vtran(1,j), dPdTtr(1,j) 219 FORMAT(2x,a20,1x,f9.3,2x,1x,f9.3,2x,1x,f9.3, 1 2x,1x,f11.3, 1 2x,3x,f7.2,3x,5x,f6.0,5x,4x,f7.3,5x, 2 4x,f7.3,5x) END IF END IF IF (ntran(j) .GE. 2) THEN IF (Htran(2,j) .EQ. XNULLM) THEN WRITE(tabf,25) 1, MK2(1,j)*ACON, 1 MK2(2,j)*BCON, MK2(3,j)*CCON, MK2(4,j)*acon, 2 Ttran(2,j)-273.15d0 25 FORMAT(4x,'post-transition ',i1,1x, 1 1x,f9.3,2x,1x,f9.3,2x,1x,f9.3,2x, 2 2x,1x,f9.3,3x,f7.2,3x) ELSE IF (Vtran(2,j) .EQ. XNULLM) THEN WRITE(tabf,125) 1, MK2(1,j)*ACON, 1 MK2(2,j)*BCON, MK2(3,j)*CCON, 2 MK2(4,j)*ACON, 2 Ttran(2,j)-273.15d0, Htran(2,j) 125 FORMAT(4x,'post-transition ',i1,1x, 1 1x,f9.3,2x,1x,f9.3,2x,1x,f9.3,2x, 2 2x,1x,f9.3,2x, 2 3x,f7.2,3x,5x,f6.0,5x) ELSE WRITE(tabf,225) 1, MK2(1,j)*ACON, 1 MK2(2,j)*BCON, MK2(3,j)*CCON, 2 MK2(4,j)*ACON, 2 Ttran(2,j)-273.15d0, Htran(2,j), 3 Vtran(2,j), dPdTtr(2,j) 225 FORMAT(4x,'post-transition ',i1,1x, 1 1x,f9.3,2x,1x,f9.3,2x,1x,f9.3,2x, 2 2x,1x,f9.3,2x, 2 3x,f7.2,3x,5x,f6.0,5x,4x,f7.3,5x, 3 4x,f7.3,5x) END IF END IF END IF IF (ntran(j) .GE. 3) THEN IF (Htran(3,j) .EQ. XNULLM) THEN WRITE(tabf,25) 2, MK3(1,j)*ACON, 1 MK3(2,j)*BCON, MK3(3,j)*CCON, 2 MK3(4,j)*ACON, 2 Ttran(3,j)-273.15d0 ELSE IF (Vtran(3,j) .EQ. XNULLM) THEN WRITE(tabf,125) 2, MK3(1,j)*ACON, 1 MK3(2,j)*BCON, MK3(3,j)*CCON, 2 MK3(4,j)*ACON, 2 Ttran(3,j)-273.15d0, Htran(3,j) ELSE WRITE(tabf,225) 2, MK3(1,j)*ACON, 1 MK3(2,j)*BCON, MK3(3,j)*CCON, 2 MK3(4,j)*ACON, 2 Ttran(3,j)-273.15d0, Htran(3,j), 3 Vtran(3,j), dPdTtr(3,j) END IF END IF END IF IF (ntran(j) .EQ. 1) THEN WRITE(tabf,39) ntran(j), MK2(1,j)*ACON, 1 MK2(2,j)*BCON,MK2(3,j)*CCON, 2 MK2(4,j)*ACON, Tmaxm(j)-273.15d0 39 FORMAT(4x,'post-transition ',i1,1x,1x,f9.3,2x, 1 1x,f9.3,2x,1x,f9.3,2x,3x,f9.3,2x,3x,f7.2) END IF IF (ntran(j) .EQ. 2) THEN WRITE(tabf,39) ntran(j), MK3(1,j)*ACON, 1 MK3(2,j)*BCON,MK3(3,j)*CCON, 2 MK3(4,j)*ACON,Tmaxm(j)-273.15d0 END IF IF (ntran(j) .EQ. 3) THEN WRITE(tabf,39) ntran(j), MK4(1,j)*ACON, 1 MK4(2,j)*BCON,MK4(3,j)*CCON, 2 MK4(4,j)*ACON,Tmaxm(j)-273.15d0 END IF END IF 11 CONTINUE END IF IF (ng(i) .GT. 0) THEN WRITE(tabf,8) 8 FORMAT(/,42x,' ...... GASES ...... ',/, 1 24x,' DELTA G ',1x, 1 1x,' DELTA H ',1x, 1 1x,' S ',1x, 1 1x,' V ',1x, 1 1x,' Cp ',1x,/, 1 7x,'NAME',12x, 1 1x,' (cal/mol) ',1x, 2 1x,' (cal/mol) ',1x, 3 1x,' (cal/mol/K) ',1x, 4 1x,' (cc/mol) ',1x, 5 1x,' (cal/mol/K) ',/, 6 2x,20('-'),2x,13('-'),2x,13('-'),2x,13('-'), 7 2x,13('-'),2x,13('-')) ***** write gas G, H, S, V, Cp at 25 C, 1 bar and Maier-Kelly ***** heat capacity coefficients a, b, c DO 30 j = 1,ng(i) WRITE(tabf,17) gname(j), Gfgas(j), Hfgas(j), 1 SPrTrg(j), VPrTrg(j), Cpgas(j) 17 FORMAT(2x,a20, 1 3x,f10.0,2x, 2 3x,f10.0,2x, 3 5x,f8.3,3x, 4 7x,f2.0,7x, 5 4x,f6.1,6x) 30 CONTINUE WRITE(tabf,9) 9 FORMAT(/,29x,'MAIER-KELLY COEFFICIENTS',/, 1 7x,'NAME',11x, 1 1x,' a(10**0) ', 2 ' b(10**3) ', 3 ' c(10**-5) ', 4 ' T limit (C)',/, 4 2x,20('-'), 5 2x,10('-'),1x, 6 1x,10('-'),1x, 6 1x,10('-'),1x, 7 1x,10('-')) DO 31 j = 1,ng(i) WRITE(tabf,16) gname(j), MKg(1,j)*ACON, 1 MKg(2,j)*BCON, MKg(3,j)*CCON, 2 MKg(4,j)*ACON, 2 Tmaxg(j)-273.15d0 31 CONTINUE END IF IF ((na(i) .GT. 0) .OR. (nw(i) .GT. 0)) THEN WRITE(tabf,46) 46 FORMAT(/,36x,' ...... AQUEOUS SPECIES ...... ',/, 1 24x,' DELTA G ',1x, 1 1x,' DELTA H ',1x, 1 1x,' S ',1x, 1 1x,' V ',1x, 1 1x,' Cp ',1x,/, 1 7x,'NAME',12x, 1 1x,' (cal/mol) ',1x, 2 1x,' (cal/mol) ',1x, 3 1x,' (cal/mol/K) ',1x, 4 1x,' (cc/mol) ',1x, 5 1x,' (cal/mol/K) ',/, 6 2x,20('-'),2x,13('-'),2x,13('-'),2x,13('-'), 7 2x,13('-'),2x,13('-')) ***** write aqueous species G, H, S, V, Cp at 25 C, 1 bar DO 40 j = 1,na(i) WRITE(tabf,79) aname(j), Gfaqs(j), Hfaqs(j), 1 SPrTra(j), Vaqs(j), Cpaqs(j) 79 FORMAT(2x,a20, 1 3x,f10.0,2x, 2 3x,f10.0,2x, 3 5x,f8.3,3x, 4 5x,f6.1,5x, 5 4x,f6.1,6x) 40 CONTINUE IF (nw(i) .GT. 0) THEN ***** write H2O G, H, S, V, Cp at 25 C, 1 bar ****** WRITE(tabf,79) wname, Gwss, Hwss, 1 Swss, Vwss, Cpwss END IF IF (na(i) .GT. 0) THEN WRITE(tabf,56) 56 FORMAT(/,50x,'EQUATION-OF-STATE COEFFICIENTS',/, 1 7x,'NAME',11x, 1 2x,' a1(10**1) ',1x, 1 1x,' a2(10**-2) ',1x, 1 1x,' a3(10**0) ',1x, 1 1x,' a4(10**-4) ',1x, 2 1x,' c1(10**0) ',1x, 3 1x,' c2(10**-4) ', 1 2x,'omega(10**-5)',/, 4 2x,20('-'), 5 2x,12('-'),1x, 6 1x,12('-'),1x, 6 1x,12('-'),1x, 6 1x,12('-'),1x, 6 1x,12('-'),1x, 6 1x,12('-'),1x, 6 1x,13('-')) ***** write aqueous species equation-of-state parameters ***** wref, c[1..4], a[1..2] DO 50 j = 1,na(i) IF (a(3,j) .EQ. XNULLA) THEN WRITE(tabf,64) aname(j), 2 c(1,j)*C1CON, c(2,j)*C2CON, wref(j)*WCON 64 FORMAT(2x,a20,1x,56x,3(3x,f8.4,3x)) ELSE WRITE(tabf,65) aname(j), 1 a(1,j)*A1CON, a(2,j)*A2CON, a(3,j)*A3CON, 2 a(4,j)*A4CON, c(1,j)*C1CON, c(2,j)*C2CON, 3 wref(j)*WCON 65 FORMAT(2x,a20,1x,7(3x,f8.4,3x)) END IF 50 CONTINUE END IF END IF ***** write reaction properties at 25 C, 1 bar WRITE(tabf,74) 74 FORMAT(/,' STANDARD STATE PROPERTIES OF THE REACTION AT', 1 ' 25 DEG C AND 1 BAR') IF (nullrx) THEN WRITE(tabf,888) 888 FORMAT(' CAUTION: INCOMPLETE DATA FOR ONE OR MORE SPECIES',/) END IF WRITE(tabf,75) isov(iopt,iplot), incv(iopt,iplot), 1 var3(iopt,iplot) 75 FORMAT(50x,' DELTA G ',1x, 1 1x,' DELTA H ',1x, 1 1x,' DELTA S ',1x, 1 1x,' DELTA V ',1x, 1 ' DELTA Cp ',1x,/, 1 2x,a10,2x,a10,2x,a10, 1 2x,' LOG K ',1x, 2 1x,' (cal) ',1x, 3 1x,' (cal) ',1x, 4 1x,' (cal/K) ',1x, 5 1x,' (cc) ',1x, 6 1x,' (cal/K) ',1x,/, 7 3(2x,10('-')),1x,6(1x,10('-'),1x)) TPDref(1) = Tref - 273.15d0 TPDref(2) = Pref TPDref(3) = Dwss TPDref(4) = Dwss WRITE(tabf,85) TPDref(mapiso(iopt,iplot)), 1 TPDref(mapinc(iopt,iplot)), 2 TPDref(mapv3(iopt,iplot)), 3 logKr, dGr, dHr, dSr, dVr, dCpr 85 FORMAT(3(2x,f9.3,1x), 1 1x,f10.3,1x, 2 1x,f10.0,1x, 3 1x,f10.0,1x, 4 1x,f9.1,2x, 5 1x,f9.1,2x, 6 1x,f9.1) 989 Continue END ****************************************************************** *** pltrxn - Write header information and reaction titles *** to plot files. SUBROUTINE pltrxn(ireac) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPLOTF = 8, MAXRXN = 800, MXRPLT = 10) CHARACTER*80 rtitle(MAXRXN) CHARACTER*20 namecf, namerf, nametf, namepf(NPLOTF) CHARACTER*3 rstamp(MXRPLT) INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 xyplot, end, rlen(2), outflg LOGICAL openf COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /fnames/ namecf, namerf, nametf, namepf COMMON /plottr/ xyplot, end, nplots COMMON /reac1/ rtitle SAVE DATA rlen / 80, 249 / DATA rstamp / 'R01', 'R02', 'R03', 'R04', 'R05', 1 'R06', 'R07', 'R08', 'R09', 'R10' / *** close files if necessary IF ((xyplot .EQ. 2) .AND. (ireac .GT. 1)) THEN DO 10 i = 1,nplots CLOSE(UNIT=plotf(i)) namepf(i)(end+1:end+3) = rstamp(ireac) 10 CONTINUE END IF *** if necessary, open files and write header IF ((xyplot .EQ. 2) .OR. (ireac .EQ. 1)) THEN DO 20 i = 1,nplots IF (openf(wterm,plotf(i),namepf(i),2,1,1, 1 rlen(xyplot))) THEN CALL plttop(i) ELSE WRITE(wterm,*) ' cannot open plot file ',i END IF 20 CONTINUE END IF *** write reaction number and title DO 30 i = 1,nplots WRITE(plotf(i),40) ireac, rtitle(ireac) 40 FORMAT(//,' REACTION ',i3, 1 /,' TITLE: ',a80) 30 CONTINUE END ********************************************************************** *** plttop - Write global banner to plot file i. SUBROUTINE plttop(i) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPLOTF = 8) CHARACTER*20 pfname, namecf, namerf, nametf, namepf(NPLOTF), 1 nosave LOGICAL savecf, saverf INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 xyplot, end, outflg COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /fnames/ namecf, namerf, nametf, namepf COMMON /saveif/ savecf, saverf COMMON /plottr/ xyplot, end, nplots COMMON /dapron/ pfname SAVE DATA nosave / 'file not saved ' / WRITE(plotf(i),20) 20 FORMAT(/,' ***** SUPCRT92: input/output specifications for', 1 ' this run',/) IF (savecf) THEN WRITE(plotf(i),30) namecf 30 FORMAT( ' USER-SPECIFIED CON FILE containing ', 1 /,' T-P-D grid & option switches: ',a20,/) ELSE WRITE(plotf(i),30) nosave END IF IF (saverf) THEN WRITE(plotf(i),40) namerf 40 FORMAT( ' USER-SPECIFIED RXN FILE containing ', 1 /,' chemical reactions: ',a20,/) ELSE WRITE(plotf(i),40) nosave END IF WRITE(plotf(i),50) pfname 50 FORMAT( ' THERMODYNAMIC DATABASE: ',a20,/) WRITE(plotf(i),60) nametf 60 FORMAT(' SUPCRT-GENERATED TAB FILE containing ', 1 /,' tabulated reaction properties: ',a20) CALL wrtop2(i) END ********************************************************************* *** report - Report computed reaction properties. SUBROUTINE report(ireac, iso, inc, TPD, TPDtrn, rptran, ptrans, 1 dVr, dSr, dCpr, dHr, dGr, logKr, 2 lvdome, H2Oerr, Kfound) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MAXAQS = 10, MAXGAS = 10, MAXRXN = 800, 1 MXTRAN = 3, IABC = 4, NPLOTF = 8, MAXOdd = 3000) CHARACTER*1 PT(2) CHARACTER*5 pprop(NPLOTF) CHARACTER*10 isov(2,3), incv(2,3), var3(2,3) CHARACTER*20 mname(MAXMIN) CHARACTER*30 mform(MAXMIN), mnform, aqform CHARACTER*80 rtitle(MAXRXN) LOGICAL m2reac(MAXRXN), xall, xHSVCp, xCp, 1 MKwarn, MKdone, Pwarn, Pdone, Kfound, Klost LOGICAL rptran, lvdome, H2Oerr, EQ3run INTEGER phaser(MAXMIN), ptrans(MAXMIN), ntran(MAXMIN), 1 xyplot, end INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 mapiso(2,3), mapinc(2,3), mapv3(2,3), 2 univar, useLVS, epseqn, geqn, outflg INTEGER nm(MAXRXN), na(MAXRXN), ng(MAXRXN), nw(MAXRXN), 1 rec1m(MAXRXN,MAXMIN), rec1a(MAXRXN,MAXAQS), 2 rec1g(MAXRXN,MAXGAS) DOUBLE PRECISION coefm(MAXRXN,MAXMIN), coefa(MAXRXN,MAXAQS), 1 coefg(MAXRXN,MAXGAS), coefw(MAXRXN) DOUBLE PRECISION TPD(3), TPDtrn(MAXMIN,MXTRAN,3), logKr DOUBLE PRECISION Vmin(MAXMIN), Smin(MAXMIN), Cpmin(MAXMIN), 2 Hmin(MAXMIN), Gmin(MAXMIN) DOUBLE PRECISION Gfmin(MAXMIN), Hfmin(MAXMIN), 1 VPrTrm(MAXMIN), SPrTrm(MAXMIN), 3 MK1(IABC,MAXMIN), MK2(IABC,MAXMIN), 4 MK3(IABC,MAXMIN), MK4(IABC,MAXMIN), 5 Ttran(MXTRAN,MAXMIN), Htran(MXTRAN,MAXMIN), 6 Vtran(MXTRAN,MAXMIN), dPdTtr(MXTRAN,MAXMIN), 7 Tmaxm(MAXMIN), mvolum DOUBLE PRECISION isomin, isomax, isoinc, Kmin, Kmax, Kinc, 1 oddv1(MAXODD), oddv2(MAXODD) COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /grid/ isomin, isomax, isoinc, v2min, v2max, v2inc, 1 oddv1, oddv2, Kmin, Kmax, Kinc, niso, nv2, nlogK COMMON /TPDmap/ mapiso, mapinc, mapv3 COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /reac1/ rtitle COMMON /reac2/ coefm, coefa, coefg, coefw, nm, na, ng, nw, 1 rec1m, rec1a, rec1g, m2reac COMMON /mnames/ mname, mform COMMON /minref/ Gfmin, Hfmin, SPrTrm, VPrTrm, MK1, MK2, MK3, MK4, 1 Ttran, Htran, Vtran, dPdTtr, Tmaxm, ntran COMMON /minsp/ Vmin, Smin, Cpmin, Hmin, Gmin, phaser COMMON /headmp/ isov, incv, var3 COMMON /EQ36/ EQ3run COMMON /plottr/ xyplot, end, nplots Common /solth1/ mvolum Common /solth2/ mnform, aqform SAVE DATA PT / 'P', 'T' / DATA MKdone, Pdone / 2*.FALSE. / DATA pprop / 'logK ', 'delG ', 'delH ', 'delS ', 1 'delCp', 'delV ', 'dvar1', 'dvar2' / IF ((inc .EQ. 1)) THEN MKdone = .FALSE. Pdone = .FALSE. * For generating Soltherm records, with one gas or mineral only. IF (outflg.eq.2.and.((ng(ireac).eq.1.and.nm(ireac).eq.0).or. 1 (ng(ireac).eq.0.and.nm(ireac).eq.1))) then write(tabf,5) rtitle(ireac), mnform, 1 'volume, cc/mol =', mvolum GOTO 777 END IF * For reactions with more than one mineral or gas in full P-T grid, * e.g. FMQ buffers, and still write rtitle(ireac). IF (outflg.eq.2.and.(ng(ireac).ge.1.or.nm(ireac).ge.1)) 1 write(tabf,5) rtitle(ireac) 5 FORMAT (A20,2x,A30,2x,A16,F8.3) * For generating Soltherm records, aqueous species. 777 IF (outflg.eq.2.and.ng(ireac).eq.0.and.nm(ireac).eq.0) 1 write(tabf,5) rtitle(ireac), aqform IF (xyplot .EQ. 1) THEN CALL pltln1(TPD) END IF END IF IF ((xyplot .EQ. 2) .AND. (iso .EQ. 1) .AND. (inc .EQ. 1)) THEN CALL pltln1(TPD) END IF IF (lvdome) THEN ***** T,DH2O location falls within liquid-vapor dome IF (outflg.eq.2) Then If (iplot.eq.1) then WRITE(tabf,11) rtitle(ireac), TPD(mapiso(iopt,iplot)), 1 TPD(mapinc(iopt,iplot)), 2 TPD(mapinc(iopt,iplot))+273.15d0 11 FORMAT(A20,3(2x,f9.3,1x),35x, 1 ' T-DH2O FALLS WITHIN LIQ-VAP T-DH2O DOME ') endif If (iplot.eq.2.or.iplot.eq.3) then WRITE(tabf,13) rtitle(ireac), TPD(mapiso(iopt,iplot)), 1 TPD(mapiso(iopt,iplot))+273.15d0, 2 TPD(mapinc(iopt,iplot)) 13 FORMAT(A20,3(2x,f9.3,1x),35x, 1 ' T-DH2O FALLS WITHIN LIQ-VAP T-DH2O DOME ') endif Else WRITE(tabf,15) TPD(mapiso(iopt,iplot)), 1 TPD(mapinc(iopt,iplot)) 15 FORMAT(2(2x,f9.3,1x),23x, 1 ' T-DH2O FALLS WITHIN LIQ-VAP T-DH2O DOME ') Endif END IF IF (H2Oerr) THEN ***** T-P-d beyond fluid H2O equation of state IF (outflg.eq.2) Then If (iplot.eq.1) then WRITE(tabf,516) rtitle(ireac), 1 TPD(mapiso(iopt,iplot)), 2 TPD(mapinc(iopt,iplot)), 3 TPD(mapinc(iopt,iplot))+273.15d0, 4 99999.999d0,9999999.9d0, 9999999.9d0 516 FORMAT(A20,3(2x,f9.3,1x),1x,F10.3,2x,f11.1,3x,f11.1,3x, 1 '*** BEYOND RANGE OF APPLICABILITY OF ', 2 'H2O EQUATION OF STATE **') endif If (iplot.eq.2.or.iplot.eq.3) then WRITE(tabf,517) rtitle(ireac), 1 TPD(mapiso(iopt,iplot)), 2 TPD(mapiso(iopt,iplot))+273.15d0, 3 TPD(mapinc(iopt,iplot)),99999.999d0, 4 9999999.9d0, 9999999.9d0 517 FORMAT(A20,3(2x,f9.3,1x),1x,F10.3,2x,f11.1,3x,f11.1,3x, 1 '*** BEYOND RANGE OF APPLICABILITY OF ', 2 'H2O EQUATION OF STATE **') endif Else WRITE(tabf,16) TPD(mapiso(iopt,iplot)), 1 TPD(mapinc(iopt,iplot)) 16 FORMAT(2(2x,f9.3,1x),14x,' *** BEYOND RANGE OF', 1 ' APPLICABILITY OF H2O EQUATION OF STATE **') Endif END IF Klost = (univar .EQ. 1) .AND. (.NOT. Kfound) IF (Klost) THEN WRITE(tabf,17) TPD(mapiso(iopt,iplot)), logKr, 1 v2min, PT(2/iplot), v2max 17 FORMAT(2x,f9.3,26x,f10.3,4x, 1 ' LOG K NOT FOUND: ',f10.3,' <= ',a1,' <= ',f10.3) END IF IF (rptran) THEN DO 20 imin = 1,nm(ireac) DO 25 itran = ptrans(imin),1,-1 IF ((iplot .EQ. 2) .AND. (isat .EQ. 0)) THEN *** isotherms(P,D): phase c -> b -> a iptnum = phaser(imin) ELSE *** iso[bars,chores](T): phase a -> b -> c iptnum = phaser(imin)-itran END IF IF (outflg.ne.2) then WRITE(tabf,30) 1 TPDtrn(imin,itran,mapiso(iopt,iplot)), 2 TPDtrn(imin,itran,mapinc(iopt,iplot)), 3 TPDtrn(imin,itran,mapv3(iopt,iplot)-isat), 4 iptnum, mname(imin) 30 FORMAT(3(2x,f9.3,1x),11x, 1 ' PHASE TRANSITION #',i1,' for ', 2 a20,/) endif 25 CONTINUE 20 CONTINUE END IF ******************************************************************* *** Assignment of "blank" variables below facilitates full *** reporting of reaction properties beyond certain limits *** of certain equations when the CALL to SUBR blank is *** commented-out for the development version. xall = .FALSE. xHSVCp = .FALSE. xCp = .FALSE. MKwarn = .FALSE. Pwarn = .FALSE. *** SUBR blanks to be called for distribution version; *** not called for development version IF (.NOT. (lvdome .OR. H2Oerr)) 1 CALL blanks(TPD(1),TPD(2),TPD(3),m2reac(ireac),nm(ireac), 2 ng(ireac),na(ireac),xall,xHSVCp,xCp,MKwarn,Pwarn) ***** write reaction properties to plot files IF (xyplot .GT. 0) 1 CALL pltrep(TPD,iso,inc,logKr,dGr,dHr,dSr,dCpr,dVr, 2 lvdome,H2Oerr,Klost,xall,xHSVCp,xCp) IF (lvdome .OR. H2Oerr .OR. Klost) RETURN ******************************************************************* ***** write reaction properties to tab file IF (xall) THEN ***** P-T beyond validity limits of ***** aqueous species equations IF (outflg.eq.2) Then If (iplot.eq.1) then WRITE(tabf,36) rtitle(ireac), 1 TPD(mapiso(iopt,iplot)), 2 TPD(mapinc(iopt,iplot)), 3 TPD(mapinc(iopt,iplot))+273.15d0, 4 99999.999d0,9999999.9d0, 9999999.9d0 36 FORMAT(A20,3(2x,f9.3,1x),1x,F10.3,2x,f11.1,3x,f11.1,3x, 1 'BEYOND RANGE OF APPLICABILITY OF ', 2 'AQUEOUS SPECIES EQNS') endif If (iplot.eq.2.or.iplot.eq.3) then WRITE(tabf,38) rtitle(ireac), 1 TPD(mapiso(iopt,iplot)), 2 TPD(mapiso(iopt,iplot))+273.15d0, 3 TPD(mapinc(iopt,iplot)),99999.999d0, 4 9999999.9d0, 9999999.9d0 38 FORMAT(A20,3(2x,f9.3,1x),1x,F10.3,2x,f11.1,3x,f11.1,3x, 1 'BEYOND RANGE OF APPLICABILITY OF ', 2 'AQUEOUS SPECIES EQNS') endif Else WRITE(tabf,40) TPD(mapiso(iopt,iplot)), 1 TPD(mapinc(iopt,iplot)), 2 TPD(mapv3(iopt,iplot)-isat) 40 FORMAT(3(2x,f9.3,1x),2x,' *** BEYOND RANGE OF', 1 ' APPLICABILITY OF AQUEOUS SPECIES EQNS ***') Endif RETURN END IF IF (xHSVCp) THEN ***** P-T within region where only Gibbs free energy can ***** be computed for charged aqueous species IF (outflg.eq.2) Then If (iplot.eq.1) then WRITE(tabf,41) rtitle(ireac), 1 TPD(mapiso(iopt,iplot)), 2 TPD(mapinc(iopt,iplot)), 3 TPD(mapinc(iopt,iplot))+273.15d0, 4 logKr, dGr, dHr 41 FORMAT(A20,3(2x,f9.3,1x), 1 1x,f10.3,1x, 2 1x,f11.1,3x,f11.1,3x, 3 '*** DELTA G ONLY (CHARGED AQUEOUS SPECIES) ***') endif If (iplot.eq.2.or.iplot.eq.3) then WRITE(tabf,43) rtitle(ireac), 1 TPD(mapiso(iopt,iplot)), 2 TPD(mapiso(iopt,iplot))+273.15d0, 3 TPD(mapinc(iopt,iplot)), 4 logKr, dGr, dHr 43 FORMAT(A20,3(2x,f9.3,1x), 1 1x,f10.3,1x, 2 1x,f11.1,3x,f11.1,3x, 3 '*** DELTA G ONLY (CHARGED AQUEOUS SPECIES) ***') endif else WRITE(tabf,45) TPD(mapiso(iopt,iplot)), 1 TPD(mapinc(iopt,iplot)), 2 TPD(mapv3(iopt,iplot)-isat), logKr, dGr 45 FORMAT(3(2x,f9.3,1x), 1 1x,f10.3,1x, 2 1x,f10.0,3x, 3 '*** DELTA G ONLY (CHARGED AQUEOUS SPECIES) ***') endif RETURN END IF IF (MKwarn .AND. (.NOT. MKdone)) THEN ***** beyond temperature limit of Maier-Kelly Cp coefficients; ***** issue warning to this effect. MKdone = .TRUE. * Supcrt wants to write error message here and delta G elsewhere on * separate lines in output, unlike block immediately above. * Comment out for now. * IF (outflg.eq.2) Then * If (iplot.eq.1) then * WRITE(tabf,46) rtitle(ireac), * 1 TPD(mapiso(iopt,iplot)), * 2 TPD(mapinc(iopt,iplot)), * 3 TPD(mapinc(iopt,iplot))+273.15d0,99999.999d0 * 46 FORMAT(A20,3(2x,f9.3,1x),1x,F10.3,15x, * 1 ' *** CAUTION: BEYOND P LIMIT OF', * 1 ' CP COEFFS FOR A MINERAL OR GAS') * endif * If (iplot.eq.2.or.iplot.eq.3) then * WRITE(tabf,47) rtitle(ireac), * 1 TPD(mapiso(iopt,iplot)), * 2 TPD(mapiso(iopt,iplot))+273.15d0, * 3 TPD(mapinc(iopt,iplot)),99999.999d0 * 47 FORMAT(A20,3(2x,f9.3,1x),1x,F10.3,15x, * 1 ' *** CAUTION: BEYOND P LIMIT OF', * 1 ' CP COEFFS FOR A MINERAL OR GAS') * endif * Else IF (outflg.ne.2) Then WRITE(tabf,48) TPD(mapiso(iopt,iplot)), 1 TPD(mapinc(iopt,iplot)), 2 TPD(mapv3(iopt,iplot)-isat) 48 FORMAT(3(2x,f9.3,1x),2x,' *** CAUTION: BEYOND T LIMIT', 1 ' OF CP COEFFS FOR A MINERAL OR GAS ***') Endif END IF IF (Pwarn .AND. (.NOT. Pdone)) THEN ***** beyond qualitative pressure limit of mineral/gas calculations; ***** issue warning to this effect. Pdone = .TRUE. IF (outflg.eq.2) Then If (iplot.eq.1) then WRITE(tabf,52) rtitle(ireac), 1 TPD(mapiso(iopt,iplot)), 2 TPD(mapinc(iopt,iplot)), 3 TPD(mapinc(iopt,iplot))+273.15d0, 4 99999.999d0,9999999.9d0, 9999999.9d0 52 FORMAT(A20,3(2x,f9.3,1x),1x,F10.3,2x,f11.1,3x,f11.1,3x, 1 ' *** CAUTION: BEYOND P LIMIT OF', 1 ' APPROXIMATIONS IN MINERAL/GAS EQNS ***') endif If (iplot.eq.2.or.iplot.eq.3) then WRITE(tabf,53) rtitle(ireac), 1 TPD(mapiso(iopt,iplot)), 2 TPD(mapiso(iopt,iplot))+273.15d0, 3 TPD(mapinc(iopt,iplot)),99999.999d0, 4 9999999.9d0, 9999999.9d0 53 FORMAT(A20,3(2x,f9.3,1x),1x,F10.3,2x,f11.1,3x,f11.1,3x, 1 ' *** CAUTION: BEYOND P LIMIT OF', 1 ' APPROXIMATIONS IN MINERAL/GAS EQNS ***') endif Else WRITE(tabf,55) TPD(mapiso(iopt,iplot)), 1 TPD(mapinc(iopt,iplot)), 2 TPD(mapv3(iopt,iplot)-isat) 55 FORMAT(3(2x,f9.3,1x),2x,' *** CAUTION: BEYOND P LIMIT', 1 ' OF APPROXIMATIONS IN MINERAL/GAS EQNS ***') Endif END IF IF (xCp) THEN ***** within +/- 25 degC of mineral phase transition; ***** report all property values except dCpr IF (outflg.eq.2) Then If (iplot.eq.1) then WRITE(tabf,57) rtitle(ireac), 1 TPD(mapiso(iopt,iplot)), 2 TPD(mapinc(iopt,iplot)), 3 TPD(mapinc(iopt,iplot))+273.15d0, 4 logKr, dGr, dHr 57 FORMAT(A20,3(2x,f9.3,1x), 1 1x,f10.3,1x, 2 1x,f11.1,3x,f11.1,3x, 3 ' PHASE TRANSITION') endif If (iplot.eq.2.or.iplot.eq.3) then WRITE(tabf,58) rtitle(ireac), 1 TPD(mapiso(iopt,iplot)), 2 TPD(mapiso(iopt,iplot))+273.15d0, 3 TPD(mapinc(iopt,iplot)), 4 logKr, dGr, dHr 58 FORMAT(A20,3(2x,f9.3,1x), 1 1x,f10.3,1x, 2 1x,f11.1,3x,f11.1,3x, 3 ' PHASE TRANSITION') endif Else WRITE(tabf,60) TPD(mapiso(iopt,iplot)), 1 TPD(mapinc(iopt,iplot)), 2 TPD(mapv3(iopt,iplot)-isat), 3 logKr, dGr, dHr, dSr, dVr 60 FORMAT(3(2x,f9.3,1x), 1 1x,f10.3,1x, 2 1x,f10.0,1x, 3 1x,f10.0,1x, 4 1x,f9.1,2x, 5 1x,f9.1,2x,' TRANSITION') Endif RETURN END IF ***** .NOT. (xall .OR. xHSVCp .OR. xCp); ***** report all property values IF (outflg.eq.2) Then If (iplot.eq.1) then WRITE(tabf,66) rtitle(ireac), 1 TPD(mapiso(iopt,iplot)), 2 TPD(mapinc(iopt,iplot)), 3 TPD(mapinc(iopt,iplot))+273.15d0, 4 logKr, dGr, dHr, dSr 66 FORMAT(A20,3(2x,f9.3,1x), 1 1x,f10.3,1x, 2 1x,3(f11.1,3x)) endif If (iplot.eq.2.or.iplot.eq.3) then WRITE(tabf,68) rtitle(ireac), 1 TPD(mapiso(iopt,iplot)), 2 TPD(mapiso(iopt,iplot))+273.15d0, 3 TPD(mapinc(iopt,iplot)), 4 logKr, dGr, dHr, dSr 68 FORMAT(A20,3(2x,f9.3,1x), 1 1x,f10.3,1x, 2 1x,3(f11.1,3x)) endif Else WRITE(tabf,70) TPD(mapiso(iopt,iplot)), 1 TPD(mapinc(iopt,iplot)), 2 TPD(mapv3(iopt,iplot)-isat), 3 logKr, dGr, dHr, dSr, dVr, dCpr 70 FORMAT(3(2x,f9.3,1x), 1 1x,f10.3,1x, 2 1x,f10.0,1x, 3 1x,f10.0,1x, 4 1x,f9.1,2x, 5 1x,f9.1,2x, 6 1x,f9.1) Endif RETURN END ******************************************************************* *** pltln1 - Write top line of next property block. SUBROUTINE pltln1(TPD) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPLOTF = 8, MXIPLT = 11, MAXOdd = 3000, MAXINC = 3000) DOUBLE PRECISION TPD(3), isomin, isomax, isoinc, Kmin, Kmax, Kinc, 1 oddv1(MAXODD), oddv2(MAXODD), 2 pbuff(MAXINC,MXIPLT,NPLOTF) INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 mapiso(2,3), mapinc(2,3), mapv3(2,3), 2 univar, useLVS, epseqn, geqn, xyplot, end, outflg LOGICAL EQ3run CHARACTER*7 isov2(2,3), incv2(2,3), var32(2,3) CHARACTER*10 isov(2,3), incv(2,3), var3(2,3) CHARACTER*13 pprop(NPLOTF) COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /grid/ isomin, isomax, isoinc, v2min, v2max, v2inc, 2 oddv1, oddv2, Kmin, Kmax, Kinc, niso, nv2, nlogK COMMON /headmp/ isov, incv, var3 COMMON /TPDmap/ mapiso, mapinc, mapv3 COMMON /EQ36/ EQ3run COMMON /plottr/ xyplot, end, nplots COMMON /pbuffr/ pbuff SAVE DATA pprop / 'logK ', 'delG (cal) ', 'delH (cal) ', 1 'delS (cal/K) ', 'delCp (cal/K)', 'delV (cc) ', 2 'dvar1 ', 'dvar2 ' / DATA isov2 / 'D(g/cc)', 'P(bars)', 3*'T(degC)', 'P(bars)' / DATA incv2 / 2*'T(degC)', 'D(g/cc)', 'P(bars)', 'P(bars)', 1 'T(degC)' / DATA var32 / 'P(bars)', 'D(g/cc)', 'P(bars)', 3*'D(g/cc)' / IF (xyplot .EQ. 1) THEN IF (univar .EQ. 1) THEN RETURN END IF DO 10 i = 1,nplots IF ((isat .EQ. 0) .AND. (.NOT. EQ3run)) THEN IF (i .EQ. 7) THEN WRITE(plotf(i),20) isov(iopt,iplot), 1 TPD(mapiso(iopt,iplot)), 2 incv(iopt,iplot), var3(iopt,iplot) 20 FORMAT(/,1x,a10,' = ',f10.4,' ; ', 1 a10,', ',a10,/) ELSE WRITE(plotf(i),25) isov(iopt,iplot), 1 TPD(mapiso(iopt,iplot)), 2 incv(iopt,iplot), pprop(i) 25 FORMAT(/,1x,a10,' = ',f10.4,' ; ', 1 a10,', ',a13,/) END IF ELSE IF (i .LT. 7) THEN WRITE(plotf(i),30) isov(iopt,iplot), pprop(i) 30 FORMAT(/,1x,a10,', ',a13,/) END IF IF (i .EQ. 7) THEN WRITE(plotf(i),35) isov(iopt,iplot), 1 incv(iopt,iplot) 35 FORMAT(/,1x,a10,', ',a10,/) END IF IF (i .EQ. 8) THEN WRITE(plotf(i),35) isov(iopt,iplot), 1 var3(iopt,iplot) END IF END IF 10 CONTINUE ELSE DO 40 i = 1,nplots IF ((isat .EQ. 1) .OR. EQ3run) THEN WRITE(plotf(i),50) isov2(iopt,iplot), 1 incv2(iopt,iplot), var32(iopt,iplot), 1 (pprop(j), j = 1,6) 50 FORMAT(/,3(a7,2x),6(a13,2x)) GO TO 40 END IF IF (univar .EQ. 0) THEN IF (i .LT. 7) THEN WRITE(plotf(i),60) isov2(iopt,iplot)(1:1), 1 incv2(iopt,iplot)(1:1), pprop(i) 60 FORMAT(/,1x,a1,'-',a1,' grid: ',a13) ELSE WRITE(plotf(i),65) isov2(iopt,iplot)(1:1), 1 incv2(iopt,iplot)(1:1), var32(iopt,iplot) 65 FORMAT(/,1x,a1,'-',a1,' grid: ',a7) END IF WRITE(plotf(i),70) incv2(iopt,iplot), 1 (isov2(iopt,iplot), isomin+(j-1)*isoinc, 2 j=1,MIN(niso,MXIPLT)) *** MXIPLT = 11 70 FORMAT(/,a7,11(2x,a7,' =',e11.4)) ELSE WRITE(plotf(i),80) isov2(iopt,iplot)(1:1), 1 incv2(iopt,iplot) 80 FORMAT(/,1x,a1,'-logK grid: ',a7) WRITE(plotf(i),90) isov2(iopt,iplot), 1 (incv2(iopt,iplot)(1:1), 2 Kmin+(k-1)*Kinc, k=1,MIN(nlogK,MXIPLT)) *** MXIPLT = 11 90 FORMAT(/,a7,11(2x,a1,'(logK =',e11.4,')')) END IF 40 CONTINUE *** initialize property buffer DO 100 k = 1,nplots DO 100 j = 1,MIN(niso,MXIPLT) DO 100 i = 1,nv2 pbuff(i,j,k) = 0.0d0 100 CONTINUE END IF END *********************************************************************** *** pltrep - Report calculated property values to plot files or buffers SUBROUTINE pltrep(TPD,iso,inc,logKr,dGr,dHr,dSr,dCpr,dVr, 1 lvdome,H2Oerr,Klost,xall,xHSVCp,xCp) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXINC = 3000, MAXOdd = 3000, MXIPLT = 11, NPLOTF = 8) LOGICAL lvdome, H2Oerr, Klost, xall, xHSVCp, xCp, EQ3run CHARACTER*10 isov(2,3), incv(2,3), var3(2,3) INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), 1 mapiso(2,3), mapinc(2,3), mapv3(2,3), univar, 2 useLVS, epseqn, geqn, xyplot, end, outflg DOUBLE PRECISION TPD(3), pbuff(MAXINC,MXIPLT,NPLOTF), 1 isomin, isomax, isoinc, Kmin, Kmax, Kinc, logKr, 2 oddv1(MAXODD), oddv2(MAXODD), satmin(2) COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg COMMON /TPDmap/ mapiso, mapinc, mapv3 COMMON /headmp/ isov, incv, var3 COMMON /icon/ isat, iopt, iplot, univar, noninc, 1 useLVS, epseqn, geqn COMMON /grid/ isomin, isomax, isoinc, v2min, v2max, v2inc, 2 oddv1, oddv2, Kmin, Kmax, Kinc, niso, nv2, nlogK COMMON /satend/ satmin COMMON /EQ36/ EQ3run COMMON /plottr/ xyplot, end, nplots COMMON /pbuffr/ pbuff SAVE *************************** xyplot = 1 ******************************* IF ((xyplot .EQ. 1) .AND. (lvdome .OR. H2Oerr .OR. xall)) RETURN IF ((xyplot .EQ. 1) .AND. (univar .EQ. 1)) THEN IF (Klost) THEN pbuff(inc,iso,1) = 0.0d0 ELSE pbuff(inc,iso,1) = TPD(mapinc(iopt,iplot)) END IF GO TO 20 END IF IF ((xyplot .EQ. 1) .AND. xHSVCp) THEN IF ((isat .EQ. 1) .OR. EQ3run) THEN WRITE(plotf(1),10) TPD(mapiso(iopt,iplot)), logKr WRITE(plotf(2),10) TPD(mapiso(iopt,iplot)), dGr WRITE(plotf(7),10) TPD(mapiso(iopt,iplot)), 1 TPD(mapinc(iopt,iplot)) WRITE(plotf(8),10) TPD(mapiso(iopt,iplot)), 1 TPD(mapv3(iopt,iplot)-isat) 10 FORMAT(2(1x,e14.7)) END IF IF (univar .EQ. 0) THEN WRITE(plotf(1),10) TPD(mapinc(iopt,iplot)), logKr WRITE(plotf(2),10) TPD(mapinc(iopt,iplot)), dGr WRITE(plotf(7),10) TPD(mapinc(iopt,iplot)), 1 TPD(mapv3(iopt,iplot)-isat) END IF RETURN END IF IF ((xyplot .EQ. 1) .AND. xCp) THEN IF ((isat .EQ. 1) .OR. EQ3run) THEN WRITE(plotf(1),10) TPD(mapiso(iopt,iplot)), logKr WRITE(plotf(2),10) TPD(mapiso(iopt,iplot)), dGr WRITE(plotf(3),10) TPD(mapiso(iopt,iplot)), dHr WRITE(plotf(4),10) TPD(mapiso(iopt,iplot)), dSr WRITE(plotf(6),10) TPD(mapiso(iopt,iplot)), dVr WRITE(plotf(7),10) TPD(mapiso(iopt,iplot)), 1 TPD(mapinc(iopt,iplot)) WRITE(plotf(8),10) TPD(mapiso(iopt,iplot)), 1 TPD(mapv3(iopt,iplot)-isat) RETURN END IF IF (univar .EQ. 0) THEN WRITE(plotf(1),10) TPD(mapinc(iopt,iplot)), logKr WRITE(plotf(2),10) TPD(mapinc(iopt,iplot)), dGr WRITE(plotf(3),10) TPD(mapinc(iopt,iplot)), dHr WRITE(plotf(4),10) TPD(mapinc(iopt,iplot)), dSr WRITE(plotf(6),10) TPD(mapinc(iopt,iplot)), dVr WRITE(plotf(7),10) TPD(mapinc(iopt,iplot)), 1 TPD(mapv3(iopt,iplot)-isat) END IF RETURN END IF IF (xyplot .EQ. 1) THEN *** .NOT. (xall .OR. xHSVCp .OR. xCp) IF ((isat .EQ. 1) .OR. EQ3run) THEN WRITE(plotf(1),10) TPD(mapiso(iopt,iplot)), logKr WRITE(plotf(2),10) TPD(mapiso(iopt,iplot)), dGr WRITE(plotf(3),10) TPD(mapiso(iopt,iplot)), dHr WRITE(plotf(4),10) TPD(mapiso(iopt,iplot)), dSr WRITE(plotf(5),10) TPD(mapiso(iopt,iplot)), dCpr WRITE(plotf(6),10) TPD(mapiso(iopt,iplot)), dVr WRITE(plotf(7),10) TPD(mapiso(iopt,iplot)), 1 TPD(mapinc(iopt,iplot)) WRITE(plotf(8),10) TPD(mapiso(iopt,iplot)), 1 TPD(mapv3(iopt,iplot)-isat) END IF IF ((isat .EQ. 0) .AND. (.NOT. EQ3run)) THEN WRITE(plotf(1),10) TPD(mapinc(iopt,iplot)), logKr WRITE(plotf(2),10) TPD(mapinc(iopt,iplot)), dGr WRITE(plotf(3),10) TPD(mapinc(iopt,iplot)), dHr WRITE(plotf(4),10) TPD(mapinc(iopt,iplot)), dSr WRITE(plotf(5),10) TPD(mapinc(iopt,iplot)), dCpr WRITE(plotf(6),10) TPD(mapinc(iopt,iplot)), dVr WRITE(plotf(7),10) TPD(mapinc(iopt,iplot)), 1 TPD(mapv3(iopt,iplot)-isat) END IF RETURN END IF *************************** xyplot = 2 ******************************* IF (lvdome .OR. H2Oerr .OR. Klost .OR. xall) GO TO 20 IF (univar .EQ. 1) THEN pbuff(inc,iso,1) = TPD(mapinc(iopt,iplot)) GO TO 20 END IF IF (xHSVCp) THEN pbuff(inc,iso,1) = logKr pbuff(inc,iso,2) = dGr pbuff(inc,iso,7) = TPD(mapv3(iopt,iplot)-isat) pbuff(inc,iso,8) = TPD(mapinc(iopt,iplot)) GO TO 20 END IF IF (xCp) THEN pbuff(inc,iso,1) = logKr pbuff(inc,iso,2) = dGr pbuff(inc,iso,3) = dHr pbuff(inc,iso,4) = dSr pbuff(inc,iso,6) = dVr pbuff(inc,iso,7) = TPD(mapv3(iopt,iplot)-isat) pbuff(inc,iso,8) = TPD(mapinc(iopt,iplot)) ELSE pbuff(inc,iso,1) = logKr pbuff(inc,iso,2) = dGr pbuff(inc,iso,3) = dHr pbuff(inc,iso,4) = dSr pbuff(inc,iso,5) = dCpr pbuff(inc,iso,6) = dVr pbuff(inc,iso,7) = TPD(mapv3(iopt,iplot)-isat) pbuff(inc,iso,8) = TPD(mapinc(iopt,iplot)) END IF 20 IF ((iso .LT. niso) .OR. (inc .LT. nv2) .OR. 1 (EQ3run .AND. (inc .LT. noninc))) RETURN *** flush buffers IF (xyplot .EQ. 1) THEN DO 25 i = 1,nlogk WRITE(plotf(1),22) Kmin + (i-1)*Kinc, 1 isov(iopt,iplot), incv(iopt,iplot) 22 FORMAT(/,' LOG K = ',e12.5,' ; ',a10,', ',a10,' = ',/) DO 25 j = 1,niso IF (pbuff(i,j,1) .NE. 0.0d0) THEN WRITE(plotf(1),10) isomin + (j-1)*isoinc, 1 pbuff(i,j,1) END IF 25 CONTINUE RETURN END IF IF (EQ3run) THEN DO 30 i = 1,noninc WRITE(plotf(1),40) oddv1(i), oddv2(i), 1 pbuff(i,1,7), (pbuff(i,1,k), k = 1,6) 40 FORMAT(9(e14.7,2x)) 30 CONTINUE RETURN END IF IF (isat .EQ. 1) THEN DO 50 i = 1,nv2 IF ((i .EQ. 1) .AND. (v2min .EQ. 0.0d0)) THEN WRITE(plotf(1),40) satmin(iopt), 1 pbuff(i,1,8), pbuff(i,1,7), 1 (pbuff(i,1,k), k = 1,6) ELSE WRITE(plotf(1),40) v2min+(i-1)*v2inc, 1 pbuff(i,1,8), pbuff(i,1,7), 1 (pbuff(i,1,k), k = 1,6) END IF 50 CONTINUE RETURN END IF IF (univar .EQ. 0) THEN DO 60 k = 1,nplots DO 60 i = 1,nv2 WRITE(plotf(k),70) v2min+(i-1)*v2inc, 1 (pbuff(i,j,k), j = 1,MIN(niso,MXIPLT)) 70 FORMAT(12(e14.7,2x)) 60 CONTINUE ELSE DO 80 j = 1,niso WRITE(plotf(1),90) isomin+(j-1)*isoinc, 1 (pbuff(i,j,1), i = 1,MIN(nlogK,MXIPLT)) 90 FORMAT(12(e14.7,2x)) 80 CONTINUE END IF END *********************************************************************** *** blanks - Set xall, xCp, and MKwarn per current state conditions. SUBROUTINE blanks(T,P,D,m2reac,nm,ng,na,xall,xHSVCp,xCp, 1 MKwarn,Pwarn) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MXTRAN = 3, IABC = 4, 1 MAXGAS = 10, MAXAQS = 10, 1 TCPM2 = 25.0d0, PMAXMG = 10000.0d0, 2 TMAXA = 1000.0d0, PMAXA = 5000.0d0, 3 TMAXX = 400.0d0, PMAXX1 = 500.0d0, 4 TMINX = 350.0d0, PMAXX2 = 1000.0d0, 5 DMINCA = 0.35d0, DMINNA = 0.05d0, TOL = 1.0d-5) CHARACTER*20 mname(MAXMIN), aname(MAXAQS), gname(MAXGAS) CHARACTER*30 mform(MAXMIN), aform(MAXAQS), gform(MAXGAS) LOGICAL m2reac, xall, xHSVCp, xCp, MKwarn, Pwarn, aqschg INTEGER ntran(MAXMIN), phaser(MAXMIN) DOUBLE PRECISION TtranP(MXTRAN,MAXMIN), 1 PtranT(MXTRAN,MAXMIN) DOUBLE PRECISION Vmin(MAXMIN), Smin(MAXMIN), Cpmin(MAXMIN), 2 Hmin(MAXMIN), Gmin(MAXMIN) DOUBLE PRECISION Gfaqs(MAXAQS), Hfaqs(MAXAQS), SPrTra(MAXAQS), 1 a(4,MAXAQS), c(2,MAXAQS), 2 wref(MAXAQS), chg(MAXAQS) DOUBLE PRECISION Gfmin(MAXMIN), Hfmin(MAXMIN), 1 VPrTrm(MAXMIN), SPrTrm(MAXMIN), 3 MK1(IABC,MAXMIN), MK2(IABC,MAXMIN), 4 MK3(IABC,MAXMIN), MK4(IABC,MAXMIN), 5 Ttran(MXTRAN,MAXMIN), Htran(MXTRAN,MAXMIN), 6 Vtran(MXTRAN,MAXMIN), dPdTtr(MXTRAN,MAXMIN), 7 Tmaxm(MAXMIN) DOUBLE PRECISION Gfgas(MAXGAS), Hfgas(MAXGAS), VPrTrg(MAXGAS), 1 SPrTrg(MAXGAS), MKg(IABC,MAXGAS), Tmaxg(MAXGAS) COMMON /PTtran/ TtranP, PtranT COMMON /minsp/ Vmin, Smin, Cpmin, Hmin, Gmin, phaser COMMON /anames/ aname, aform COMMON /aqsref/ Gfaqs, Hfaqs, SPrTra, c, a, wref, chg COMMON /mnames/ mname, mform COMMON /minref/ Gfmin, Hfmin, SPrTrm, VPrTrm, MK1, MK2, MK3, MK4, 1 Ttran, Htran, Vtran, dPdTtr, Tmaxm, ntran COMMON /gnames/ gname, gform COMMON /gasref/ Gfgas, Hfgas, SPrTrg, VPrTrg, MKg, Tmaxg SAVE xall = .FALSE. xHSVCp = .FALSE. xCp = .FALSE. MKwarn = .FALSE. Pwarn = .FALSE. aqschg = .FALSE. IF ((nm .GT. 0) .OR. (ng .GT. 0)) THEN ***** consider validity limitations of mineral/gas equations IF (P .GT. PMAXMG+TOL) THEN ***** P exceeds pressure limit; issue warning Pwarn = .TRUE. END IF TK = T + 273.15d0 DO 10 i = 1,ng IF (TK .GT. Tmaxg(i)) THEN ***** T beyond limit of Maier-Kelly coefficients; ***** issue appropriate warning in calling routine MKwarn = .TRUE. END IF 10 CONTINUE DO 11 i = 1,nm IF (TK .GT. Tmaxm(i)) THEN ***** T beyond limit of Maier-Kelly coefficients; ***** issue appropriate warning in calling routine MKwarn = .TRUE. END IF 11 CONTINUE IF (m2reac) THEN DO 20 i = 1,nm IF (ntran(i) .GT. 0) THEN ***** blank-out Cp if T within +/- 25 degC of ***** phase transition IF (phaser(i) .EQ. 1) THEN xCp = (DABS(TK - TtranP(phaser(i),i)) 1 .LE. TCPM2) ELSE xCp = (DABS(TK - TtranP(phaser(i)-1,i)) 1 .LE. TCPM2) 2 .OR. 3 (DABS(TK - TtranP(MIN(phaser(i),ntran(i)),i)) 4 .LE. TCPM2) END IF IF (xCp) THEN GO TO 25 END IF END IF 20 CONTINUE END IF END IF 25 IF (na .GT. 0) THEN ***** consider validity limitations of aqueous species equations IF ((P .GT. PMAXA+TOL) .OR. (T .GT. TMAXA+TOL)) THEN ***** P or T exceeds validity limits of equations xall = .TRUE. RETURN END IF DO 30 j = 1,na IF (chg(j) .NE. 0.0d0) THEN aqschg = .TRUE. END IF 30 CONTINUE IF (aqschg) THEN ***** check limits for charged aqueous species xall = ((D .LT. DMINCA) .OR. ((P. LT. PMAXX1) .AND. 1 (T .GT. TMINX) .AND. (T .LT. TMAXX))) xHSVCp = xall .OR. 1 ((P .LT. PMAXX2) .AND. (T .GT. TMINX)) ELSE ***** check limits for neutral aqueous species xall = (D .LT. DMINNA) END IF END IF END *** reac92 - Calculates the standard molal Gibbs free energy, enthalpy, *** entropy, heat capacity, and volume of the i[th] reaction *** (specified in common blocks /icon/ and /reac/) among *** <= MAXMIN minerals, <= MAXAQS aqueous species, <= MAXGAS *** gases, and H2O using equations and data given by Helgeson *** et al. (1978), Tanger and Helgeson (1988), Shock and *** Helgeson (1988, 1990), Shock et al. (1989, 1991), Johnson *** and Norton (1991), Johnson et al. (1991), and Sverjensky *** et al. (1991). *** *** Computed reaction properties are stored in COMMON blocks *** /minsp/, /gassp/, /aqsp/, /solvn/, and /fmeq/. *** ******************************************************************* *** *** Author: James W. Johnson *** Earth Sciences Department, L-219 *** Lawrence Livermore National Laboratory *** Livermore, CA 94550 *** johnson@s05.es.llnl.gov *** *** Abandoned: 8 November 1991 *** ******************************************************************* SUBROUTINE reac92(i,P,TC,Dw,Vw,betaw,alphaw,daldTw, 1 Sw,Cpw,Hw,Gw,Zw,Qw,Yw,Xw,geqn) ******************************************************************* *** argument units: (w suffixes denote H2O properties) *** *** P ............ bars *** TC ........... degC *** Dw ........... g/cm**3 *** Vw ........... cm**3/mol *** betaw, Qw .... bars**(-1) *** alphaw, Yw ... K**(-1) *** daldTw, Xw ... K**(-2) *** Sw, Cpw ...... cal/(mol*K) *** Hw, Gw ....... cal/mol *** Zw ........... dimensionless ********************************************* IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MAXGAS = 10, MAXAQS = 10, MAXRXN = 800) INTEGER geqn LOGICAL m2reac(MAXRXN) CHARACTER*80 rtitle(MAXRXN) INTEGER nm(MAXRXN), na(MAXRXN), ng(MAXRXN), nw(MAXRXN), 1 rec1m(MAXRXN,MAXMIN), rec1a(MAXRXN,MAXAQS), 2 rec1g(MAXRXN,MAXGAS) DOUBLE PRECISION coefm(MAXRXN,MAXMIN), coefa(MAXRXN,MAXAQS), 1 coefg(MAXRXN,MAXGAS), coefw(MAXRXN) COMMON /reac1/ rtitle COMMON /reac2/ coefm, coefa, coefg, coefw, nm, na, ng, nw, 1 rec1m, rec1a, rec1g, m2reac SAVE TK = TC + 273.15d0 CALL solids(nm(i),P,TK) CALL gases(ng(i),TK) CALL aqsps(na(i),P,TK,Dw,betaw,alphaw,daldTw,Zw,Qw,Yw,Xw,geqn) CALL reactn(i,TK,Vw,Sw,Cpw,Hw,Gw) END ******************************************************************** *** Solids - Computes the standard molal thermodynamic properties of * nmin minerals at P,T using equations given by * Helgeson et al. (1978). SUBROUTINE solids(nmin,P,T) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MXTRAN = 3, IABC = 4) CHARACTER*20 mname(MAXMIN) CHARACTER*30 mform(MAXMIN) INTEGER ntran(MAXMIN), phaser(MAXMIN), getphr, getCpr, Cpreg DOUBLE PRECISION mwH2O, TtranP(MXTRAN,MAXMIN), 1 PtranT(MXTRAN,MAXMIN) DOUBLE PRECISION Vmin(MAXMIN), Smin(MAXMIN), Cpmin(MAXMIN), 2 Hmin(MAXMIN), Gmin(MAXMIN) DOUBLE PRECISION Gfmin(MAXMIN), Hfmin(MAXMIN), SPrTrm(MAXMIN), 2 VPrTrm(MAXMIN), 3 MK1(IABC,MAXMIN), MK2(IABC,MAXMIN), 4 MK3(IABC,MAXMIN), MK4(IABC,MAXMIN), 5 Ttran(MXTRAN,MAXMIN), Htran(MXTRAN,MAXMIN), 6 Vtran(MXTRAN,MAXMIN), dPdTtr(MXTRAN,MAXMIN), 7 Tmaxm(MAXMIN) COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr COMMON /mnames/ mname, mform COMMON /minref/ Gfmin, Hfmin, SPrTrm, VPrTrm, MK1, MK2, MK3, MK4, 1 Ttran, Htran, Vtran, dPdTtr, Tmaxm, ntran COMMON /minsp/ Vmin, Smin, Cpmin, Hmin, Gmin, phaser COMMON /PTtran/ TtranP, PtranT SAVE DO 10 i = 1,nmin phaser(i) = getphr(i,P,T,TtranP) Cpreg = getCpr(i,T) CALL Vterms(i,P,T,phaser(i),Vmin(i),VdP,PtranT) CALL Cptrms('min',i,Cpreg,T,Cpmin(i),CprdT,CprdlT) CALL pttrms(i,phaser(i),T,Spttrm,Hpttrm,Gpttrm) Smin(i) = SPrTrm(i) + CprdlT + Spttrm Hmin(i) = Hfmin(i) + CprdT + VdP + Hpttrm Gmin(i) = Gfmin(i) - SPrTrm(i)*(T-Tref) + 1 CprdT - T*CprdlT + VdP + Gpttrm IF ((mname(i) .EQ. 'QUARTZ') .OR. 1 (mname(i) .EQ. 'COESITE')) THEN Hmin(i) = Hmin(i) - VdP Gmin(i) = Gmin(i) - VdP CALL quartz(mname(i),P,T,Ttran(1,i), 1 Vmin(i),Smin(i),Hmin(i),Gmin(i)) END IF 10 CONTINUE RETURN END ************************************************************************ *** getCpr - Returns the effective phase region for temperature *** integration of Cpr(T) for mineral imin (i.e., the *** phase region specified by T at 1 bar). INTEGER FUNCTION getCpr(imin,T) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MXTRAN = 3, IABC = 4) INTEGER ntran(MAXMIN) DOUBLE PRECISION Gfmin(MAXMIN), Hfmin(MAXMIN), SPrTrm(MAXMIN), 2 VPrTrm(MAXMIN), 3 MK1(IABC,MAXMIN), MK2(IABC,MAXMIN), 4 MK3(IABC,MAXMIN), MK4(IABC,MAXMIN), 5 Ttran(MXTRAN,MAXMIN), Htran(MXTRAN,MAXMIN), 6 Vtran(MXTRAN,MAXMIN), dPdTtr(MXTRAN,MAXMIN), 7 Tmaxm(MAXMIN) COMMON /minref/ Gfmin, Hfmin, SPrTrm, VPrTrm, MK1, MK2, MK3, MK4, 1 Ttran, Htran, Vtran, dPdTtr, Tmaxm, ntran SAVE getCpr = 1 DO 10 i = 1,ntran(imin) IF (T .GT. Ttran(i,imin)) getCpr = getCpr + 1 10 CONTINUE RETURN END *********************************************************************** *** quartz - Revises the standard molal Gibbs free energy (G), enthalpy *** (H), entropy (S), and volume (V) of quartz or coesite to *** account for V(T) > 0 using equations (109) through (115), *** Helgeson et al. (1978). SUBROUTINE quartz(mname,P,T,TtPr,V,S,H,G) IMPLICIT DOUBLE PRECISION (a-h,o-z) CHARACTER*20 mname INTEGER qphase DOUBLE PRECISION k, mwH2O COMMON /refval/ mwH2O, R, Pr, Tr, ZPrTr, YPrTr COMMON /qtzcon/ aa, ba, ca, VPtTta, VPrTtb, Stran SAVE *** VPrTra = VPrTr(a-quartz) *** Vdiff = VPrTr(a-quartz) - VPrTr(coesite) *** k = dPdTtr(a/b-quartz) DATA VPrTra, Vdiff, k / 22.688d0, 2.047d0, 38.5d0 / ***** set qphase = phase region of quartz IF ((T .LE. TtPr) .OR. (P .GE. (Pr + k*(T-TtPr)))) THEN qphase = 1 ELSE qphase = 2 END IF ***** set Pstar and Sstar ***** IF (T .LE. TtPr) THEN Pstar = Pr Sstar = 0.0d0 ELSE IF (qphase .EQ. 2) THEN Pstar = P Sstar = 0.0d0 ELSE Pstar = Pr + k*(T-TtPr) Sstar = Stran END IF END IF IF (qphase .EQ. 2) THEN ***** set volume to beta-quartz ***** V = VPrTtb ELSE ***** calculate volume of alpha-quartz per eqn (109) ***** V = VPrTra + ca*(P-Pr) + (VPtTta - VPrTra - ca*(P-Pr))*(T-Tr) / 1 (TtPr + (P-Pr)/k - Tr) END IF IF (mname .EQ. 'COESITE') V = V - Vdiff ***** leading constant for [G,S]Vterm below ***** is a coversion factor (cal/cm**3/bar) IF (mname .EQ. 'QUARTZ') THEN GVterm = 0.23901488d-1 * (VPrTra*(P-Pstar) + VPrTtb*(Pstar-Pr) - 1 0.5d0*ca*(2.0d0*Pr*(P-Pstar) - (P**2-Pstar**2)) - 2 ca*k*(T-Tr)*(P-Pstar) + 3 k*(ba + aa*ca*k)*(T-Tr)*DLOG((aa + P/k)/(aa + Pstar/k))) ELSE GVterm = 0.23901488d-1 * ((VPrTra-Vdiff)*(P-Pstar) + 1 (VPrTtb-Vdiff)*(Pstar-Pr) - 0.5d0*ca*(2.0d0*Pr*(P-Pstar) - 2 (P**2-Pstar**2)) - ca*k*(T-Tr)*(P-Pstar) + 3 k*(ba + aa*ca*k)*(T-Tr)*DLOG((aa + P/k)/(aa + Pstar/k))) END IF SVterm = 0.23901488d-1 * (-k*(ba + aa*ca*k)* 1 DLOG((aa + P/k)/(aa + Pstar/k)) + ca*k*(P-Pstar)) - 2 Sstar G = G + GVterm S = S + SVterm H = H + GVterm + T*SVterm END ************************************************************************ *** getphr - Returns phase region for mineral imin at P, T; and, as a *** side effect, TtranP(1..MXTRAN,imin) as f(P). *** *** getphr = 1 ... TtranP(1,imin) > T [or imin lacks transn] *** getphr = 2 ... TtranP(1,imin) < T [< TtranP(2,imin)] *** getphr = 3 ... TtranP(2,imin) < T [< TtranP(3,imin)] *** getphr = 4 ... TtranP(3,imin) < T INTEGER FUNCTION getphr(imin,P,T,TtranP) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MXTRAN = 3, IABC = 4) CHARACTER*20 mname(MAXMIN) CHARACTER*30 mform(MAXMIN) INTEGER ntran(MAXMIN) DOUBLE PRECISION TtranP(MXTRAN,MAXMIN), mwH2O DOUBLE PRECISION Gfmin(MAXMIN), Hfmin(MAXMIN), VPrTrm(MAXMIN), 2 SPrTrm(MAXMIN), 3 MK1(IABC,MAXMIN), MK2(IABC,MAXMIN), 4 MK3(IABC,MAXMIN), MK4(IABC,MAXMIN), 5 Ttran(MXTRAN,MAXMIN), Htran(MXTRAN,MAXMIN), 6 Vtran(MXTRAN,MAXMIN), dPdTtr(MXTRAN,MAXMIN), 7 Tmaxm(MAXMIN) COMMON /mnames/ mname, mform COMMON /minref/ Gfmin, Hfmin, SPrTrm, VPrTrm, MK1, MK2, MK3, MK4, 1 Ttran, Htran, Vtran, dPdTtr, Tmaxm, ntran COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr SAVE ****** phase region 1 ****** getphr = 1 IF (ntran(imin) .EQ. 0) RETURN IF (dPdTtr(1,imin) .EQ. 0.0d0) THEN TtranP(1,imin) = Ttran(1,imin) ELSE TtranP(1,imin) = Ttran(1,imin) + (P-Pref)/dPdTtr(1,imin) END IF IF (T .LE. TtranP(1,imin)) RETURN ****** phase region 2 ****** getphr = 2 IF (ntran(imin) .EQ. 1) RETURN IF (dPdTtr(2,imin) .EQ. 0.0d0) THEN TtranP(2,imin) = Ttran(2,imin) ELSE TtranP(2,imin) = Ttran(2,imin) + (P-Pref)/dPdTtr(2,imin) END IF IF (T .LE. TtranP(2,imin)) RETURN ****** phase region 3 ****** getphr = 3 IF (ntran(imin) .EQ. 2) RETURN IF (dPdTtr(3,imin) .EQ. 0.0d0) THEN TtranP(3,imin) = Ttran(3,imin) ELSE TtranP(3,imin) = Ttran(3,imin) + (P-Pref)/dPdTtr(3,imin) END IF IF (T .LE. TtranP(3,imin)) RETURN ****** phase region 4 ****** getphr = 4 RETURN END ************************************************************************ *** Vterms - Computes Vmin(P,T), Vmin*dP, and (if necesary) PtranT. SUBROUTINE Vterms(imin,P,T,phaser,Vmin,VdP,PtranT) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MXTRAN = 3, IABC = 4) CHARACTER*20 mname(MAXMIN) CHARACTER*30 mform(MAXMIN) INTEGER phaser, ntran(MAXMIN) DOUBLE PRECISION mwH2O, PtranT(MXTRAN,MAXMIN) DOUBLE PRECISION Gfmin(MAXMIN), Hfmin(MAXMIN), VPrTrm(MAXMIN), 2 SPrTrm(MAXMIN), 3 MK1(IABC,MAXMIN), MK2(IABC,MAXMIN), 4 MK3(IABC,MAXMIN), MK4(IABC,MAXMIN), 5 Ttran(MXTRAN,MAXMIN), Htran(MXTRAN,MAXMIN), 6 Vtran(MXTRAN,MAXMIN), dPdTtr(MXTRAN,MAXMIN), 7 Tmaxm(MAXMIN) COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr COMMON /mnames/ mname, mform COMMON /minref/ Gfmin, Hfmin, SPrTrm, VPrTrm, MK1, MK2, MK3, MK4, 1 Ttran, Htran, Vtran, dPdTtr, Tmaxm, ntran SAVE Vmin = VPrTrm(imin) DO 10 i = 1,phaser-1 10 Vmin = Vmin + Vtran(i,imin) VdP = Vmin*(P - Pref)*0.23901488d-1 ****** return if Pressure integration does not cross ****** phase transition boundaries IF (ntran(imin) .EQ. 0) RETURN IF (dPdTtr(1,imin) .EQ. 0.0d0) RETURN IF (T .LE. Ttran(1,imin)) RETURN IF ((ntran(imin) .EQ. 1) .AND. (phaser .EQ. 2)) RETURN IF ((ntran(imin) .EQ. 2) .AND. (phaser .EQ. 3)) RETURN IF ((ntran(imin) .EQ. 2) .AND. (phaser .EQ. 2) .AND. 1 (T .LT. Ttran(2,imin))) RETURN ****** take account of cross-boundary pressure integration IF ((ntran(imin) .EQ. 1) .OR. 1 ((phaser .EQ. 1) .AND.(T .LT. Ttran(2,imin)))) THEN PtranT(1,imin) = Pref + (T - Ttran(1,imin))*dPdTtr(1,imin) VdP = 0.23901488d-1 * ( 1 VPrTrm(imin)*(P - Pref) + 2 Vtran(1,imin)*(PtranT(1,imin) - Pref)) RETURN END IF ****** ntran(imin) = 2 and T .GE. Ttran(2,imin) ****** PtranT(2,imin) = Pref + (T - Ttran(2,imin))*dPdTtr(2,imin) IF (phaser .EQ. 2) THEN VdP = 0.23901488d-1 * ( 1 (VPrTrm(imin) + Vtran(1,imin))*(P - Pref) + 2 Vtran(2,imin)*(PtranT(2,imin) - Pref)) ELSE PtranT(1,imin) = Pref + (T - Ttran(1,imin))*dPdTtr(1,imin) VdP = 0.23901488d-1 * ( 1 VPrTrm(imin)*(P - Pref) + 1 Vtran(1,imin)*(PtranT(1,imin) - Pref) + 2 Vtran(2,imin)*(PtranT(2,imin) - Pref)) END IF RETURN END ************************************************************************ *** Cptrms - Computes the standard molal heat capacity and heat capacity *** temperature integrals, evaluated from Tref to T at 1 bar. SUBROUTINE Cptrms(phase,i,Cpreg,T,Cpr,CprdT,CprdlT) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXGAS = 10, MAXMIN = 10, MXTRAN = 3, IABC = 4) CHARACTER*3 phase CHARACTER*20 mname(MAXMIN), gname(MAXGAS) CHARACTER*30 mform(MAXMIN), gform(MAXGAS) INTEGER ntran(MAXMIN), Cpreg DOUBLE PRECISION mwH2O DOUBLE PRECISION Gfmin(MAXMIN), Hfmin(MAXMIN), VPrTrm(MAXMIN), 2 SPrTrm(MAXMIN), 3 MK1(IABC,MAXMIN), MK2(IABC,MAXMIN), 4 MK3(IABC,MAXMIN), MK4(IABC,MAXMIN), 5 Ttran(MXTRAN,MAXMIN), Htran(MXTRAN,MAXMIN), 6 Vtran(MXTRAN,MAXMIN), dPdTtr(MXTRAN,MAXMIN), 7 Tmaxm(MAXMIN) DOUBLE PRECISION Gfgas(MAXGAS), Hfgas(MAXGAS), VPrTrg(MAXGAS), 2 SPrTrg(MAXGAS), MKg(IABC,MAXGAS), Tmaxg(MAXGAS) COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr COMMON /mnames/ mname, mform COMMON /minref/ Gfmin, Hfmin, SPrTrm, VPrTrm, MK1, MK2, MK3, MK4, 1 Ttran, Htran, Vtran, dPdTtr, Tmaxm, ntran COMMON /gnames/ gname, gform COMMON /gasref/ Gfgas, Hfgas, SPrTrg, VPrTrg, MKg, Tmaxg SAVE IF (phase .EQ. 'gas') THEN **JP* Cpr = Cp(T,MKg(1,i),MKg(2,i),MKg(3,i)) **JP* CprdT = CpdT(Tref,T,MKg(1,i),MKg(2,i),MKg(3,i)) **JP* CprdlT = CpdlnT(Tref,T,MKg(1,i),MKg(2,i),MKg(3,i)) Cpr = Cp(T,MKg(1,i),MKg(2,i),MKg(3,i),MKg(4,i)) CprdT = CpdT(Tref,T,MKg(1,i),MKg(2,i),MKg(3,i),MKg(4,i)) CprdlT = CpdlnT(Tref,T,MKg(1,i),MKg(2,i),MKg(3,i),MKg(4,i)) RETURN END IF ***** phase = "min" ***** IF (Cpreg .EQ. 1) THEN **JP* Cpr = Cp(T,MK1(1,i),MK1(2,i),MK1(3,i)) **JP* CprdT = CpdT(Tref,T,MK1(1,i),MK1(2,i),MK1(3,i)) **JP* CprdlT = CpdlnT(Tref,T,MK1(1,i),MK1(2,i),MK1(3,i)) Cpr = Cp(T,MK1(1,i),MK1(2,i),MK1(3,i),MK1(4,i)) CprdT = CpdT(Tref,T,MK1(1,i),MK1(2,i),MK1(3,i),MK1(4,i)) CprdlT = CpdlnT(Tref,T,MK1(1,i),MK1(2,i),MK1(3,i),MK1(4,i)) RETURN END IF **JP* The following have been modified but not copied and **JP* commented out as above. IF (Cpreg .EQ. 2) THEN Cpr = Cp(T,MK2(1,i),MK2(2,i),MK2(3,i),MK2(4,i)) CprdT = CpdT(Tref,Ttran(1,i),MK1(1,i),MK1(2,i), 2 MK1(3,i),MK1(4,i)) + 3 CpdT(Ttran(1,i),T,MK2(1,i),MK2(2,i),MK2(3,i),MK2(4,i)) CprdlT = CpdlnT(Tref,Ttran(1,i),MK1(1,i),MK1(2,i), 2 MK1(3,i),MK1(4,I)) + 3 CpdlnT(Ttran(1,i),T,MK2(1,i),MK2(2,i),MK2(3,i),MK2(4,i)) RETURN END IF IF (Cpreg .EQ. 3) THEN Cpr = Cp(T,MK3(1,i),MK3(2,i),MK3(3,i),MK3(4,i)) CprdT = CpdT(Tref,Ttran(1,i),MK1(1,i),MK1(2,i), 2 MK1(3,i),MK1(4,i)) + 3 CpdT(Ttran(1,i),Ttran(2,i),MK2(1,i),MK2(2,i), 4 MK2(3,i),MK2(4,i)) + 5 CpdT(Ttran(2,i),T,MK3(1,i),MK3(2,i),MK3(3,i), 6 MK3(4,i)) CprdlT = CpdlnT(Tref,Ttran(1,i),MK1(1,i),MK1(2,i), 2 MK1(3,i),MK1(4,i))+ 3 CpdlnT(Ttran(1,i),Ttran(2,i),MK2(1,i),MK2(2,i), 4 MK2(3,i),MK2(4,i))+ 5 CpdlnT(Ttran(2,i),T,MK3(1,i),MK3(2,i),MK3(3,i),MK3(4,i)) RETURN END IF ***** Cpreg = 4 ***** Cpr = Cp(T,MK4(1,i),MK4(2,i),MK4(3,i),MK4(4,i)) CprdT = CpdT(Tref,Ttran(1,i),MK1(1,i),MK1(2,i), 2 MK1(3,i),MK1(4,i)) + 3 CpdT(Ttran(1,i),Ttran(2,i),MK2(1,i),MK2(2,i), 4 MK2(3,i),MK2(4,i)) + 5 CpdT(Ttran(2,i),Ttran(3,i),MK3(1,i),MK3(2,i), 5 MK3(3,i),MK3(4,i)) + 7 CpdT(Ttran(3,i),T,MK4(1,i),MK4(2,i),MK4(3,i),MK4(4,i)) CprdlT = CpdlnT(Tref,Ttran(1,i),MK1(1,i),MK1(2,i), 2 MK1(3,i),MK1(4,I)) + 3 CpdlnT(Ttran(1,i),Ttran(2,i),MK2(1,i), 4 MK2(2,i),MK2(3,i),MK2(4,i))+ 5 CpdlnT(Ttran(2,i),Ttran(3,i),MK3(1,i),MK3(2,i), 6 MK3(3,i),MK3(4,i))+ 7 CpdlnT(Ttran(3,i),T,MK4(1,i),MK4(2,i), 8 MK4(3,i),MK4(4,i)) RETURN END ********************************************************************* *** Cp - Returns the standard molal heat capacity at T. **JP* DOUBLE PRECISION FUNCTION Cp(T,a,b,c) DOUBLE PRECISION FUNCTION Cp(T,a,b,c,d) IMPLICIT DOUBLE PRECISION (a-h,o-z) SAVE **JP* Cp = a + b*T + c/T**2 Cp = a + b*T + c/T**2 + d/T**.5 RETURN END ********************************************************************* *** CpdT - Returns the integral CpdT evaluated from T1 to T2. **JP* DOUBLE PRECISION FUNCTION CpdT(T1,T2,a,b,c) DOUBLE PRECISION FUNCTION CpdT(T1,T2,a,b,c,d) IMPLICIT DOUBLE PRECISION (a-h,o-z) SAVE **JP* CpdT = a*(T2 - T1) + b/2.0d0*(T2**2 - T1**2) - **JP* 2 c*(1.0d0/T2 - 1.0d0/T1) CpdT = a*(T2 - T1) + b/2.0d0*(T2**2 - T1**2) - 2 c*(1.0d0/T2 - 1.0d0/T1) + 3 d/0.5d0*(T2**.5 - T1**.5) RETURN END ********************************************************************* *** CpdlnT - Returns the integral CpdlnT evaluated from T1 to T2. DOUBLE PRECISION FUNCTION CpdlnT(T1,T2,a,b,c,d) IMPLICIT DOUBLE PRECISION (a-h,o-z) SAVE **JP* CpdlnT = a*DLOG(T2/T1) + b*(T2 - T1) - **JP* 2 c/2.0d0*(1.0d0/T2**2 - 1.0d0/T1**2) - CpdlnT = a*DLOG(T2/T1) + b*(T2 - T1) - 2 c/2.0d0*(1.0d0/T2**2 - 1.0d0/T1**2) - 3 d/0.5d0*(1.0d0/T2**0.5-1.0d0/T1**0.5) RETURN END ********************************************************************* *** pttrms - Computes phase transition terms for Smin, Hmin, and Gmin. SUBROUTINE pttrms(imin,phaser,T,Spttrm,Hpttrm,Gpttrm) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MXTRAN = 3, IABC = 4) CHARACTER*20 mname(MAXMIN) CHARACTER*30 mform(MAXMIN) INTEGER ntran(MAXMIN), phtran, phaser DOUBLE PRECISION Gfmin(MAXMIN), Hfmin(MAXMIN), VPrTrm(MAXMIN), 2 SPrTrm(MAXMIN), 3 MK1(IABC,MAXMIN), MK2(IABC,MAXMIN), 4 MK3(IABC,MAXMIN), MK4(IABC,MAXMIN), 5 Ttran(MXTRAN,MAXMIN), Htran(MXTRAN,MAXMIN), 6 Vtran(MXTRAN,MAXMIN), dPdTtr(MXTRAN,MAXMIN), 7 Tmaxm(MAXMIN) COMMON /mnames/ mname, mform COMMON /minref/ Gfmin, Hfmin, SPrTrm, VPrTrm, MK1, MK2, MK3, MK4, 1 Ttran, Htran, Vtran, dPdTtr, Tmaxm, ntran SAVE Spttrm = 0.0d0 Hpttrm = 0.0d0 Gpttrm = 0.0d0 DO 10 phtran = 1,phaser-1 Spttrm = Spttrm + Htran(phtran,imin)/Ttran(phtran,imin) Hpttrm = Hpttrm + Htran(phtran,imin) Gpttrm = Gpttrm + 1 Htran(phtran,imin)*(1.0d0 - T/Ttran(phtran,imin)) 10 CONTINUE RETURN END ********************************************************************** *** gases - Computes the standard molal thermodynamic properties of * ngas gases at P,T using equations given by * Helgeson et al. (1978). SUBROUTINE gases(ngas,T) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXGAS = 10, IABC = 4, TS1BAR = 99.6324d0) LOGICAL error CHARACTER*20 gname(MAXGAS) CHARACTER*30 gform(MAXGAS) INTEGER specs(10) DOUBLE PRECISION mwH2O DOUBLE PRECISION Vgas(MAXGAS), Sgas(MAXGAS), Cpgas(MAXGAS), 2 Hgas(MAXGAS), Ggas(MAXGAS) DOUBLE PRECISION Gfgas(MAXGAS), Hfgas(MAXGAS), VPrTrg(MAXGAS), 2 SPrTrg(MAXGAS), MKg(IABC,MAXGAS), Tmaxg(MAXGAS) DOUBLE PRECISION states(4), props(46) COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr COMMON /gnames/ gname, gform COMMON /gasref/ Gfgas, Hfgas, SPrTrg, VPrTrg, MKg, Tmaxg COMMON /gassp/ Vgas, Sgas, Cpgas, Hgas, Ggas SAVE DATA specs / 2,2,2,5,1,0,2,0,4,0 / DATA states / 0.0d0, 1.0d0, 0.0d0, 0.0d0 / TC = T - 273.15d0 DO 10 i = 1,ngas IF ((gname(i) .EQ. 'H2O,g') .AND. (TC .GE. TS1BAR)) THEN *** use Haar et al. (1984) equation of state to *** compute H2O,g properties at 1 bar, T > Tsat(1 bar) = *** 99.6324 C. Note that for T < Tsat(1 bar), *** thermodynamic properties of metastable H2O,g are *** calculated using parameters estimated by J. W. Johnson *** (3/90) that facilitate smooth transition into the *** Haar et al. (1984) equation at Tsat. *** *** Beacuse (1) P = 1 bar, and (2) thermodynamic properties *** of steam are independent of dielectric properties, *** specs(8..9) can be safely hardwired, as above. states(1) = TC CALL H2O92(specs,states,props,error) Vgas(i) = VPrTrg(i) Sgas(i) = props(5) Hgas(i) = props(9) Ggas(i) = props(3) Cpgas(i) = props(13) ELSE Vgas(i) = VPrTrg(i) CALL Cptrms('gas',i,1,T,Cpgas(i),CprdT,CprdlT) Sgas(i) = SPrTrg(i) + CprdlT Hgas(i) = Hfgas(i) + CprdT Ggas(i) = Gfgas(i) - SPrTrg(i)*(T - Tref) + 1 CprdT - T*CprdlT END IF 10 CONTINUE RETURN END ************************************************************************ *** aqsps - Computes the standard partial molal thermodynamic properties *** of naqs aqueous species at P,T using equations given by *** Tanger and Helgeson (1988), Shock et al. (1991), and *** Johnson et al. (1991). SUBROUTINE aqsps(naqs,P,T,Dw,betaw,alphaw,daldTw,Z,Q,Y,X,geqn) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXAQS = 10) CHARACTER*20 aname(MAXAQS) CHARACTER*30 aform(MAXAQS) INTEGER geqn DOUBLE PRECISION mwH2O DOUBLE PRECISION Vaqs(MAXAQS), Saqs(MAXAQS), Cpaqs(MAXAQS), 2 Haqs(MAXAQS), Gaqs(MAXAQS), 7 VQterm(MAXAQS), SYterm(MAXAQS), CpXtrm(MAXAQS), 8 HYterm(MAXAQS), GZterm(MAXAQS) DOUBLE PRECISION Gfaqs(MAXAQS), Hfaqs(MAXAQS), SPrTra(MAXAQS), 2 a(4,MAXAQS), c(2,MAXAQS), wref(MAXAQS), 3 chg(MAXAQS) COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr COMMON /aqscon/ eta, theta, psi, anion, cation, gref COMMON /anames/ aname, aform COMMON /aqsref/ Gfaqs, Hfaqs, SPrTra, c, a, wref, chg COMMON /aqsp/ Vaqs, Saqs, Cpaqs, Haqs, Gaqs COMMON /solvn/ VQterm, SYterm, CpXtrm, HYterm, GZterm SAVE IF (naqs .EQ. 0) THEN RETURN ELSE CALL gfun92(T-273.15d0,P,Dw,betaw,alphaw,daldTw, 1 g,dgdP,dgdT,d2gdT2,geqn) END IF DO 10 j = 1,naqs ****** compute w, dwdP, dwdT, d2wdT2 ****** CALL omeg92(g,dgdP,dgdT,d2gdT2,wref(j),chg(j), 1 w,dwdP,dwdT,d2wdT2,aname(j)) VQterm(j) = 0.4184004d2 * (-w*Q + (-Z - 1.0d0)*dwdP) *** the leading constant converts cal/(mol*bar) -> cm3/mol Vaqs(j) = 0.4184004d2 * (a(1,j) + 1 a(2,j)/(psi+P) + 2 a(3,j)/(T-theta) + 3 a(4,j)/(psi+P)/(T-theta)) + 4 VQterm(j) SYterm(j) = w*Y - (-Z - 1.0d0)*dwdT - wref(j)*YPrTr Saqs(j) = SPrTra(j) + c(1,j)*DLOG(T/Tref) - 2 c(2,j)/theta* (1.0d0/(T-theta) - 3 1.0d0/(Tref-theta) + 4 (1.0d0/theta)* 5 DLOG(Tref*(T-theta)/T/(Tref-theta))) + 6 (a(3,j)*(P-Pref) + 7 a(4,j)*DLOG((psi+P)/(psi+Pref))) * 8 (1.0d0/(T-theta))**2 + 9 SYterm(j) CpXtrm(j) = w*T*X + 2.0d0*T*Y*dwdT + T*(Z + 1.0d0)*d2wdT2 Cpaqs(j) = c(1,j) + c(2,j)/(T-theta)**2 - 1 (2.0d0*T/(T-theta)**3) * (a(3,j)*(P-Pref) + 2 a(4,j)*DLOG((psi+P)/(psi+Pref))) + 3 CpXtrm(j) HYterm(j) = w*(-Z - 1.0d0) + w*T*Y - T*(-Z - 1.0d0)*dwdT - 1 wref(j)*(-ZPrTr - 1.0d0) - 2 wref(j)*Tref*YPrTr Haqs(j) = Hfaqs(j) + c(1,j)*(T-Tref) - 1 c(2,j)*(1.0d0/(T-theta) - 1.0d0/(Tref-theta)) + 2 a(1,j)*(P-Pref) + a(2,j)*DLOG((psi+P)/(psi+Pref)) + 3 (a(3,j)*(P-Pref) + a(4,j)*DLOG((psi+P)/(psi+Pref))) * 4 ((2.0d0*T - theta)/(T - theta)**2) + 5 HYterm(j) GZterm(j) = w*(-Z - 1.0d0) - wref(j)*(-ZPrTr - 1.0d0) + 1 wref(j)*YPrTr*(T-Tref) Gaqs(j) = Gfaqs(j) - SPrTra(j)*(T-Tref) - 1 c(1,j)*(T*DLOG(T/Tref)-T+Tref) + 2 a(1,j)*(P-Pref) + a(2,j)*DLOG((psi+P)/(psi+Pref)) - 3 c(2,j)* ( (1.0d0/(T-theta) - 1.0d0/(Tref-theta)) * 4 ((theta-T)/theta) - T/theta**2 * 5 DLOG((Tref*(T-theta))/(T*(Tref-theta))) ) + 6 (1.0d0/(T-theta)) * (a(3,j)*(P-Pref) + 7 a(4,j)*DLOG((psi+P)/(psi+Pref))) + 8 GZterm(j) GZterm(j) = w*(-Z - 1.0d0) 10 CONTINUE RETURN END ************************************************************************ *** omeg92 - Computes the conventinal Born coefficient (w) of the *** current aqueous species, dwdP, dwdP, and dw2dT2 as a *** function of g, dgdP, dgdT, d2gdT2, wref, and Z using *** equations given by Johnson et al. (1991). SUBROUTINE omeg92(g,dgdP,dgdT,d2gdT2,wref,Z, 1 w,dwdP,dwdT,d2wdT2,aname) IMPLICIT DOUBLE PRECISION (a-h,o-z) CHARACTER*20 aname COMMON /aqscon/ eta, theta, psi, anion, cation, gref SAVE IF ((Z .EQ. 0.0d0) .OR. (aname .EQ. 'H+')) THEN *** neutral aqueous species or H+ w = wref dwdP = 0.0d0 dwdT = 0.0d0 d2wdT2 = 0.0d0 RETURN ELSE *** charged aqueous species other than H+ reref = Z**2 / (wref/eta + Z/(3.082d0 + gref)) re = reref + DABS(Z) * g w = eta * (Z**2/re - Z/(3.082d0 + g)) Z3 = DABS(Z**3)/re**2 - Z/(3.082d0 + g)**2 Z4 = DABS(Z**4)/re**3 - Z/(3.082d0 + g)**3 dwdP = -eta * Z3 * dgdP dwdT = -eta * Z3 * dgdT d2wdT2 = 2.0d0 * eta * Z4 * dgdT**2 - eta * Z3 * d2gdT2 END IF END ************************************************************************ *** reactn - Computes the standard molal thermodynamic properties *** of the i[th] reaction. SUBROUTINE reactn(i,T,Vw,Sw,Cpw,Hw,Gw) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (MAXMIN = 10, MAXAQS = 10, MAXGAS = 10, MAXRXN = 800) CHARACTER*80 rtitle(MAXRXN) LOGICAL m2reac(MAXRXN) INTEGER nm(MAXRXN), na(MAXRXN), ng(MAXRXN), nw(MAXRXN), 1 rec1m(MAXRXN,MAXMIN), rec1a(MAXRXN,MAXAQS), 2 rec1g(MAXRXN,MAXGAS), phaser(MAXMIN) DOUBLE PRECISION mwH2O DOUBLE PRECISION coefm(MAXRXN,MAXMIN), coefa(MAXRXN,MAXAQS), 1 coefg(MAXRXN,MAXGAS), coefw(MAXRXN) DOUBLE PRECISION Vmin(MAXMIN), Smin(MAXMIN), Cpmin(MAXMIN), 2 Hmin(MAXMIN), Gmin(MAXMIN), 3 Vgas(MAXGAS), Sgas(MAXGAS), Cpgas(MAXGAS), 4 Hgas(MAXGAS), Ggas(MAXGAS), 5 Vaqs(MAXAQS), Saqs(MAXAQS), Cpaqs(MAXAQS), 6 Haqs(MAXAQS), Gaqs(MAXAQS) DOUBLE PRECISION VQterm(MAXAQS), SYterm(MAXAQS), CpXtrm(MAXAQS), 1 HYterm(MAXAQS), GZterm(MAXAQS), logKr COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr COMMON /reac1/ rtitle COMMON /reac2/ coefm, coefa, coefg, coefw, nm, na, ng, nw, 1 rec1m, rec1a, rec1g, m2reac COMMON /minsp/ Vmin, Smin, Cpmin, Hmin, Gmin, phaser COMMON /gassp/ Vgas, Sgas, Cpgas, Hgas, Ggas COMMON /aqsp/ Vaqs, Saqs, Cpaqs, Haqs, Gaqs COMMON /fmeq/ dVr, dSr, dCpr, dHr, dGr, 2 logKr, dlogKT, dlogKP COMMON /solvn/ VQterm, SYterm, CpXtrm, HYterm, GZterm SAVE ***** sum mineral contributions ***** dVrm = 0.0d0 dCprm = 0.0d0 dSrm = 0.0d0 dHrm = 0.0d0 dGrm = 0.0d0 DO 10 j = 1,nm(i) dVrm = dVrm + coefm(i,j)*Vmin(j) dCprm = dCprm + coefm(i,j)*Cpmin(j) dSrm = dSrm + coefm(i,j)*Smin(j) dHrm = dHrm + coefm(i,j)*Hmin(j) dGrm = dGrm + coefm(i,j)*Gmin(j) 10 CONTINUE ***** sum gas contributions ***** dVrg = 0.0d0 dCprg = 0.0d0 dSrg = 0.0d0 dHrg = 0.0d0 dGrg = 0.0d0 DO 20 j = 1,ng(i) dVrg = dVrg + coefg(i,j)*Vgas(j) dCprg = dCprg + coefg(i,j)*Cpgas(j) dSrg = dSrg + coefg(i,j)*Sgas(j) dHrg = dHrg + coefg(i,j)*Hgas(j) dGrg = dGrg + coefg(i,j)*Ggas(j) 20 CONTINUE ***** sum aqueous species contributions ***** dVra = 0.0d0 dCpra = 0.0d0 dSra = 0.0d0 dHra = 0.0d0 dGra = 0.0d0 DO 30 j = 1,na(i) dVra = dVra + coefa(i,j)*Vaqs(j) dCpra = dCpra + coefa(i,j)*Cpaqs(j) dSra = dSra + coefa(i,j)*Saqs(j) dHra = dHra + coefa(i,j)*Haqs(j) dGra = dGra + coefa(i,j)*Gaqs(j) 30 CONTINUE ***** calculate H2O contributions ***** dVrw = coefw(i) * Vw dSrw = coefw(i) * Sw dCprw = coefw(i) * Cpw dHrw = coefw(i) * Hw dGrw = coefw(i) * Gw ***** calculate reaction properties ***** dVr = dVrm + dVrg + dVra + dVrw dSr = dSrm + dSrg + dSra + dSrw dCpr = dCprm + dCprg + dCpra + dCprw dHr = dHrm + dHrg + dHra + dHrw dGr = dGrm + dGrg + dGra + dGrw logKr = -dGr / (2.302585d0 * R * T) dlogKT = dHr / (2.302585d0 * R * T**2) dlogKP = -0.23901488d-1 * dVr / (2.302585d0 * R * T) RETURN END ****************************************************************** *** gfun92 - Computes the g function (Tanger and Helgeson, 1988; *** Shock et al., 1991) and its partial derivatives *** (dgdP, dgdT, d2gdT2) at TdegC, Pbars using the *** computational algorithm specified by geqn. *** *** geqn = 1 ...... use Tanger-Helgeson (1988) equations *** geqn = 2 ...... use Shock et al. (1991) equations *** without the f(P,T) difference function *** geqn = 3 ...... use Shock et al. (1991) equations *** with the f(P,T) difference function SUBROUTINE gfun92(TdegC,Pbars,Dgcm3,betab,alphaK,daldT, 1 g,dgdP,dgdT,d2gdT2,geqn) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (TMAX = 1000.0d0, PMAX = 5000.0d0, TOL=1.0d-4) INTEGER geqn SAVE ****** initialize g and derivatives to zero g = 0.0d0 dgdP = 0.0d0 dgdT = 0.0d0 d2gdT2 = 0.0d0 IF ((TdegC .GT. TMAX+TOL) .OR. (Pbars .GT. PMAX+TOL)) RETURN * IF (geqn .EQ. 1) THEN ****** use Tanger-Helgeson (1988) equations * CALL gTangr(Pbars,TdegC+273.15d0,Dgcm3,betab,alphaK,daldT, * 2 g,dgdP,dgdT,d2gdT2) * RETURN * END IF * IF (geqn .EQ. 2) THEN ****** use Shock et al. (1991) equations ****** without f(P,T) difference function * CALL gShok1(TdegC,Pbars,Dgcm3,betab,alphaK,daldT, * 2 g,dgdP,dgdT,d2gdT2) * RETURN * END IF IF (geqn .EQ. 3) THEN ****** use Shock et al. (1991) equations ****** with f(P,T) difference function CALL gShok2(TdegC,Pbars,Dgcm3,betab,alphaK,daldT, 2 g,dgdP,dgdT,d2gdT2) RETURN END IF END ***************************************************************** *** gShok2- Computes g, dgdP, dgdT, and d2gdT2 using equations given *** by Shock et al. (1991) *** *** units: T ................. C *** D ................. g/cm**3 *** beta, dgdP ........ bars**(-1) *** alpha, dgdT ....... K**(-1) *** daldT, d2gdT2 ..... K**(-2) SUBROUTINE gShok2(T,P,D,beta,alpha,daldT,g,dgdP,dgdT,d2gdT2) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION c(6), cc(3) SAVE DATA c / -0.2037662D+01, 0.5747000D-02, -0.6557892D-05, 1 0.6107361D+01, -0.1074377D-01, 0.1268348D-04 / DATA cc / 0.3666666D+02, -0.1504956D-9, 0.5017997D-13 / IF (D .GE. 1.0d0) RETURN a = c(1) + c(2)*T + c(3)*T**2 b = c(4) + c(5)*T + c(6)*T**2 g = a*(1.0d0 - D)**b dgdD = - a * b * (1.0d0 - D)**(b - 1.0d0) dgdD2 = a * b * (b - 1.0d0) * (1.0d0 - D)**(b - 2.0d0) dadT = c(2) + 2.0d0*c(3)*T dadTT = 2.0d0 * c(3) dbdT = c(5) + 2.0d0*c(6)*T dbdTT = 2.0d0 * c(6) dDdT = - D * alpha dDdP = D * beta dDdTT = - D * (daldT - alpha**2) Db = (1.0d0 - D) ** b dDbdT = -b * (1.0d0 - D)**(b-1.0d0) * dDdT + 1 DLOG(1.0d0 - D) * Db * dbdT dDbdTT = -(b * (1.0d0 - D)**(b-1.0d0) * dDdTT + 1 (1.0d0 - D)**(b-1.0d0) * dDdT * dbdT + b * dDdT * 2 (-(b-1.0d0) * (1.0d0 - D)**(b-2.0d0) * dDdT + 3 DLOG(1.0d0 - D) * (1.0d0 - D)**(b-1.0d0) * dbdT)) + 4 DLOG(1.0d0 - D) * (1.0d0 - D)**b * dbdTT - 5 (1.0d0 - D)**b * dbdT * dDdT / (1.0d0 - D) + 6 DLOG(1.0d0 - D) * dbdT * dDbdT dgdP = dgdD * dDdP dgdT = a*dDbdT + Db*dadT d2gdT2 = a*dDbdTT + 2.0d0*dDbdT*dadT + Db*dadTT IF ((T .LT. 155.0d0) .OR. (P .GT. 1000.0d0) .OR. 1 (T .GT. 355.0d0)) RETURN ft = ((T - 155.0d0)/300.0d0)**4.8 + 1 cc(1)*((T - 155.0d0)/300.0d0)**16 dftdT = 4.8d0/300.0d0*((T - 155.0d0)/300.0d0)**3.8 + 1 16.0d0/300.0d0*cc(1)*((T - 155.0d0)/300.0d0)**15 dftdTT = 3.8d0*4.8d0/300.0d0**2*((T - 155.0d0)/300.0d0)**2.8 + 1 15.0d0*16.0d0/300.0d0**2*cc(1)*((T - 155.0d0)/300.0d0)**14 fp = cc(2)*(1000.0d0 - P)**3 + cc(3)*(1000.0d0 - P)**4 dfpdP = -3.0d0*cc(2)*(1000.0d0 - P)**2 - 1 4.0d0*cc(3)*(1000.0d0 - P)**3 f = ft * fp dfdP = ft * dfpdP dfdT = fp * dftdT d2fdT2 = fp * dftdTT g = g - f dgdP = dgdP - dfdP dgdT = dgdT - dfdT d2gdT2 = d2gdT2 - d2fdT2 RETURN END *___________________________________________________ *** H2O92 - Computes state, thermodynamic, transport, and electroststic *** properties of fluid H2O at T,[P,D] using equations and data *** given by Haar et al. (1984), Levelt Sengers et al. (1983), *** Johnson and Norton (1991), Watson et al. (1980), Sengers and *** Kamgar-Parsi (1984), Sengers et al. (1984), Helgeson and Kirkham *** (1974), Uematsu and Franck (1980), and Pitzer (1983). *** *********************************************************************** *** *** Author: James W. Johnson *** Earth Sciences Dept., L-219 *** Lawrence Livermore National Laboratory *** Livermore, CA 94550 *** johnson@s05.es.llnl.gov *** *** Abandoned: 8 November 1991 *** *********************************************************************** * * specs - Input unit, triple point, saturation, and option specs: * ***** it, id, ip, ih, itripl, isat, iopt, useLVS, epseqn, icrit; * * note that the returned value of isat may differ from * its input value and that icrit need not be specified * prior to invocation. * * * states - State variables: * ***** temp, pres, dens(1), dens(2); * * note that the first three of these must be specified prior * to invocation and that, in the case of saturation, vapor * density is returned in dens(1), liquid in dens(2). * * * props - Thermodynamic, transport, electrostatic, and combined * property values: * ***** A, G, S, U, H, Cv, Cp, Speed, alpha, beta, diel, visc, ***** tcond, surten, tdiff, Prndtl, visck, albe, ***** ZBorn, YBorn, QBorn, daldT, XBorn * * * error - LOGICAL argument that indicates success ("FALSE") or * failure ("TRUE") of the call, the latter value in * response to out-of-bounds specs or states variables. * *********************************************************************** SUBROUTINE H2O92(specs,states,props,error) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPROP = 23, NPROP2 = 46) INTEGER specs(10) DOUBLE PRECISION states(4), props(NPROP2), Dens(2), 1 wpliq(NPROP), wprops(NPROP) LOGICAL crtreg, valid, error, useLVS COMMON /units/ ft, fd, fvd, fvk, fs, fp, fh, fst, fc COMMON /wpvals/ wprops, wpliq SAVE CALL unit(specs(1),specs(2),specs(3),specs(4),specs(5)) IF (.NOT. (valid(specs(1),specs(2),specs(3),specs(4),specs(5), 1 specs(6),specs(7),specs(8),specs(9), 2 states(1),states(2),states(3)))) THEN error = .TRUE. RETURN ELSE error = .FALSE. END IF IF (crtreg(specs(6),specs(7),specs(1), 1 states(1),states(2),states(3))) THEN specs(10) = 1 useLVS = (specs(8) .EQ. 1) ELSE specs(10) = 0 useLVS = .FALSE. END IF IF (useLVS) THEN Dens(1) = states(3) CALL LVSeqn(specs(6),specs(7),specs(5), 1 states(1),states(2),Dens,specs(9)) Dens(1) = Dens(1) / 1.0d3 IF (specs(6) .EQ. 1) THEN Dens(2) = Dens(2) / 1.0d3 END IF ELSE Dens(1) = states(3) / 1.0d3 CALL HGKeqn(specs(6),specs(7),specs(5), 1 states(1),states(2),Dens,specs(9)) END IF CALL load(1,wprops,props) IF (specs(6) .EQ. 1) THEN tempy = Dens(1) Dens(1) = Dens(2) Dens(2) = tempy CALL load(2,wpliq,props) END IF states(1) = TdegUS(specs(1),states(1)) states(2) = states(2) * fp states(3) = Dens(1) / fd IF (specs(6) .EQ. 1) THEN states(4) = Dens(2) / fd END IF RETURN END ************************************************************************ *** valid - Returns "TRUE" if unit and equation specifications * are valid and input state conditions fall within * the HGK equation's region of validity; * returns "FALSE" otherwise. LOGICAL FUNCTION valid(it,id,ip,ih,itripl,isat,iopt, 1 useLVS,epseqn,Temp,Pres,Dens) IMPLICIT DOUBLE PRECISION (a-h,o-z) INTEGER useLVS, epseqn LOGICAL valspc, valTD, valTP COMMON /tolers/ TTOL, PTOL, DTOL, XTOL, EXPTOL, FPTOL COMMON /units/ ft, fd, fvd, fvk, fs, fp, fh, fst, fc COMMON /crits/ Tc, rhoC, Pc, Pcon, Ucon, Scon, dPcon COMMON /tpoint/ Utr, Str, Htr, Atr, Gtr, 1 Ttr, Ptripl, Dltrip, Dvtrip COMMON /HGKbnd/ Ttop, Tbtm, Ptop, Pbtm, Dtop, Dbtm COMMON /liqice/ sDli1, sPli1, sDli37, sPli37, sDIB30, 1 Tli13, Pli13, Dli13, TnIB30, DnIB30 SAVE *** ensure validity of input specifications IF (.NOT. valspc(it,id,ip,ih,itripl,isat,iopt, 1 useLVS,epseqn)) THEN valid = .FALSE. RETURN END IF *** convert to degC, bars, g/cm3 *** T = TdegK(it,Temp) - 273.15d0 D = Dens * fd P = Pres / fp * 1.0d1 Ttripl = Ttr - 273.15d0 Tcrit = Tc - 273.15d0 Pcrit = Pc * 1.0d1 IF (isat .EQ. 0) THEN IF (iopt .EQ. 1) THEN valid = valTD(T,D,isat,epseqn) ELSE valid = valTP(T,P) END IF ELSE IF (iopt .EQ. 1) THEN valid = ((T+FPTOL .GE. Ttripl) .AND. 1 (T-FPTOL .LE. Tcrit)) ELSE valid = ((P+FPTOL .GE. Ptripl) .AND. 1 (P-FPTOL .LE. Pcrit)) END IF END IF RETURN END ***************************************************************** *** valspc - Returns "TRUE" if it, id, ip, ih, itripl, isat, iopt, * useLVS, and epseqn values all define valid input; * returns "FALSE" otherwise. LOGICAL FUNCTION valspc(it,id,ip,ih,itripl,isat,iopt, 1 useLVS,epseqn) INTEGER useLVS, epseqn SAVE valspc = (1 .LE. it) .AND. (it .LE. 4) .AND. 1 (1 .LE. id) .AND. (id .LE. 4) .AND. 2 (1 .LE. ip) .AND. (ip .LE. 5) .AND. 3 (1 .LE. ih) .AND. (ih .LE. 6) .AND. 4 (0 .LE. itripl) .AND. (itripl .LE. 1) .AND. 5 (0 .LE. isat) .AND. (isat .LE. 1) .AND. 6 (1 .LE. iopt) .AND. (iopt .LE. 2) .AND. 7 (0 .LE. useLVS) .AND. (useLVS .LE. 1) .AND. 8 (1 .LE. epseqn) .AND. (epseqn .LE. 5) RETURN END ***************************************************************** *** valTD - Returns "TRUE" if T-D defines liquid or vapor H2O * within validity limits of the HGK equation of state; * returns "FALSE" otherwise. LOGICAL FUNCTION valTD(T,D,isat,epseqn) IMPLICIT DOUBLE PRECISION (a-h,o-z) INTEGER epseqn COMMON /tolers/ TTOL, PTOL, DTOL, XTOL, EXPTOL, FPTOL COMMON /aconst/ wm, gascon, tz, aa, zb, dzb, yb, uref, sref COMMON /RTcurr/ rt COMMON /crits/ Tc, rhoC, Pc, Pcon, Ucon, Scon, dPcon COMMON /tpoint/ Utr, Str, Htr, Atr, Gtr, 1 Ttr, Ptripl, Dltrip, Dvtrip COMMON /HGKbnd/ Ttop, Tbtm, Ptop, Pbtm, Dtop, Dbtm COMMON /liqice/ sDli1, sPli1, sDli37, sPli37, sDIB30, 1 Tli13, Pli13, Dli13, TnIB30, DnIB30 COMMON /coefs/ a(20), q(20), x(11) COMMON /satur/ Dliq, Dvap, DH2O, iphase SAVE EQUIVALENCE (TmnLVS, x(1)) IF ((T-FPTOL .GT. Ttop) .OR. (T+FPTOL .LT. Tbtm) .OR. 1 (D-FPTOL .GT. Dtop) .OR. (D+FPTOL .LT. Dbtm)) THEN valTD = .FALSE. RETURN END IF Tcrit = Tc - 273.15d0 Ttripl = Ttr - 273.15d0 IF ((T+FPTOL .GE. Tcrit) .OR. 1 ((T .GE. TnIB30) .AND. (D .GE. Dltrip))) THEN Dlimit = sDIB30 * (T-TnIB30) + Dtop valTD = (D-FPTOL .LE. Dlimit) ELSE IF (D-FPTOL .LE. Dltrip) THEN IF (T .GE. Ttripl) THEN valTD = .TRUE. Tk = T + 273.15d0 IF (Tk .LT. TmnLVS) THEN rt = gascon * Tk CALL pcorr(0,Tk,Ps,Dl,Dv,epseqn) ELSE istemp = 1 DH2O = 0.0d0 P = Pfind(istemp,Tk,DH2O) CALL denLVS(istemp,Tk,P) Dv = Dvap / 1.0d3 Dl = Dliq / 1.0d3 END IF IF ((D .GE. Dv) .AND. (D. LE. Dl)) THEN isat = 1 END IF ELSE P = Psublm(T) PMPa = P / 1.0d1 Tk = T + 273.15d0 Dguess = PMPa / Tk / 0.4d0 rt = gascon * Tk CALL bb(Tk) CALL denHGK(Dsublm,PMPa,Dguess,Tk,dPdD) valTD = (D-FPTOL .LE. Dsublm) END IF ELSE IF (D .LE. Dli13) THEN Dlimit = sDli1 * (T-Tli13) + Dli13 valTD = (D+FPTOL .GE. Dlimit) ELSE Dlimit = sDli37 * (T-Tli13) + Dli13 valTD = (D-FPTOL .LE. Dlimit) END IF END IF END IF RETURN END ***************************************************************** *** valTP - Returns "TRUE" if T-P defines liquid or vapor H2O * within validity limits of the HGK equation of state; * returns "FALSE" otherwise. LOGICAL FUNCTION valTP(T,P) IMPLICIT DOUBLE PRECISION (a-h,o-z) COMMON /tolers/ TTOL, PTOL, DTOL, XTOL, EXPTOL, FPTOL COMMON /crits/ Tcrit, rhoC, Pc, Pcon, Ucon, Scon, dPcon COMMON /tpoint/ Utr, Str, Htr, Atr, Gtr, 1 Ttr, Ptripl, Dltrip, Dvtrip COMMON /HGKbnd/ Ttop, Tbtm, Ptop, Pbtm, Dtop, Dbtm COMMON /liqice/ sDli1, sPli1, sDli37, sPli37, sDIB30, 1 Tli13, Pli13, Dli13, TnIB30, DnIB30 SAVE IF ((T-FPTOL .GT. Ttop) .OR. (T+FPTOL .LT. Tbtm) .OR. 1 (P-FPTOL .GT. Ptop) .OR. (P+FPTOL .LT. Pbtm)) THEN valTP = .FALSE. RETURN ELSE valTP = .TRUE. END IF IF (P .GE. Pli13) THEN Plimit = sPli37 * (T-Tli13) + Pli13 valTP = (P-FPTOL .LE. Plimit) ELSE IF (P .GE. Ptripl) THEN Plimit = sPli1 * (T-Tli13) + Pli13 valTP = (P+FPTOL .GE. Plimit) ELSE Psubl = Psublm(T) valTP = (P-FPTOL .LE. Psubl) END IF END IF RETURN END ***************************************************************** *** Psublm - Returns Psublimation(T) computed from the * equation given by Washburn (1924): Monthly * Weather Rev., v.52, pp.488-490. DOUBLE PRECISION FUNCTION Psublm(Temp) IMPLICIT DOUBLE PRECISION (a-h,o-z) SAVE T = Temp + 2.731d2 PmmHg = power(1.0d1, (-2.4455646d3/T + 8.2312d0*DLOG10(T) - 1 1.677006d-2*T + 1.20514d-5*T*T - 6.757169d0)) *** convert mmHg to bars *** Psublm = PmmHg * 1.33322d-3 RETURN END ************************************************************************ *** HGKcon - Constant parameters for the H2O equation of state * given by Haar, Gallagher, & Kell (1984): * bp, bq = b(j), B(j) from Table A.1, p.272 * g1, g2, gf = alpha, beta, gamma from eq (A.2), p.272 * g, ii, jj = g(i), k(i), l(i) from eq (A.5), p.272. * Note that tz < tcHGK. * Tolerence limits required in various real & inexact * comparisons are set and stored in COMMON /tolers/. BLOCK DATA HGKcon IMPLICIT DOUBLE PRECISION (a-h,o-z) COMMON /aconst/ wm, gascon, tz, aa, zb, dzb, yb, uref, sref COMMON /nconst/ g(40), ii(40), jj(40), nc COMMON /ellcon/ g1, g2, gf, b1, b2, b1t, b2t, b1tt, b2tt COMMON /bconst/ bp(10), bq(10) COMMON /addcon/ atz(4), adz(4), aat(4), aad(4) COMMON /HGKcrt/ tcHGK, dcHGK, pcHGK COMMON /tolers/ TTOL, PTOL, DTOL, XTOL, EXPTOL, FPTOL COMMON /HGKbnd/ Ttop, Tbtm, Ptop, Pbtm, Dtop, Dbtm COMMON /liqice/ sDli1, sPli1, sDli37, sPli37, sDIB30, 1 Tli13, Pli13, Dli13, TnIB30, DnIB30 COMMON /tpoint/ Utripl, Stripl, Htripl, Atripl, Gtripl, 1 Ttripl, Ptripl, Dltrip, Dvtrip SAVE DATA Ttripl, Ptripl, Dltrip, Dvtrip 1 / 2.7316d2, 2 0.611731677193563186622762580414d-2, 3 0.999778211030936587977889295063d0, 4 0.485467583448287303988319166423d-5 / DATA Ttop, Tbtm, Ptop, Pbtm, Dtop, Dbtm 1 / 2.25d3, -2.0d1, 3.0d4, 1.0d-3, 2 0.138074666423686955066817336896d1, 3 0.858745555396173972667420987465d-7 / DATA sDli1, sPli1, sDli37, sPli37, sDIB30, 1 Tli13, Pli13, Dli13, TnIB30, DnIB30 2 / -0.584797401732178547634910059828d-2, 3 -0.138180804975562958027981345769d3, 4 0.183244000000000000000000000007d-2, 5 0.174536874999999999999999999995d3, 6 -0.168375439429928741092636579574d-3, 7 -0.15d2, 8 0.20741d4, 9 0.108755631570602617113573577945d1, 1 0.145d3, 1 0.102631640581853166397515716306d1 / DATA TTOL, PTOL, DTOL, XTOL, EXPTOL, FPTOL 1 / 1.0d-6, 1.0d-6, 1.0d-9, 1.0d-5, -673.5d0, 1.0d-7 / DATA tcHGK, dcHGK, pcHGK / .647126d3, .322d3, .22055d2 / DATA atz /.64d3, .64d3, .6416d3, .27d3/ DATA adz /.319d0, .319d0, .319d0, .155d1/ DATA aat /.2d5, .2d5, .4d5, .25d2/ DATA aad /.34d2, .4d2, .3d2, .105d4/ DATA wm, gascon, tz, aa, uref, sref 1 / .1801520000d2, .46152200d0, .647073d3, .1d1, 2 -.4328455039d4, .76180802d1 / DATA g1, g2, gf /.11d2, .44333333333333d2, .35d1/ DATA bp / .7478629d0, -.3540782d0, 2*.0d0, .7159876d-2, 1 .0d0, -.3528426d-2, 3*.0d0/ DATA bq / .11278334d1, .0d0, -.5944001d0, -.5010996d1, .0d0, 1 .63684256d0, 4*.0d0/ DATA nc / 36 / DATA g /-.53062968529023d3, .22744901424408d4, .78779333020687d3 1, -.69830527374994d2, .17863832875422d5, -.39514731563338d5 2, .33803884280753d5, -.13855050202703d5, -.25637436613260d6 3, .48212575981415d6, -.34183016969660d6, .12223156417448d6 4, .11797433655832d7, -.21734810110373d7, .10829952168620d7 5, -.25441998064049d6, -.31377774947767d7, .52911910757704d7 6, -.13802577177877d7, -.25109914369001d6, .46561826115608d7 7, -.72752773275387d7, .41774246148294d6, .14016358244614d7 8, -.31555231392127d7, .47929666384584d7, .40912664781209d6 9, -.13626369388386d7, .69625220862664d6, -.10834900096447d7 a, -.22722827401688d6, .38365486000660d6, .68833257944332d4 b, .21757245522644d5, -.26627944829770d4, -.70730418082074d5 c, -.22500000000000d0, -.16800000000000d1 d, .5500000000000d-1, -.93000000000000d2/ DATA ii / 4*0, 4*1, 4*2, 4*3, 4*4, 4*5, 4*6, 4*8, 2*2, 0, 4, 1 3*2, 4/ DATA jj / 2, 3, 5, 7, 2, 3, 5, 7, 2, 3, 5, 7, 2, 3, 5, 7, 1 2, 3, 5, 7, 2, 3, 5, 7, 2, 3, 5, 7, 2, 3, 5, 7, 2 1, 4, 4, 4, 0, 2, 0, 0/ END ********************************************************************* *** LVScon - Constant parameters for the H2O critical region equation * of state given by Levelt Sengers, Kamgar-Parsi, Balfour, * & Sengers (1983). BLOCK DATA LVScon IMPLICIT DOUBLE PRECISION (a-h,o-z) COMMON /crits/ Tc, rhoC, Pc, Pcon, Ucon, Scon, dPcon COMMON /coefs/ a(20), q(20), x(11) SAVE DATA Tc, rhoC, Pc, Pcon, Ucon, Scon, dPcon 1 / 647.067d0, 322.778d0, 22.046d0, 2 0.034070660379837018423130834983d0, 22046.0d0, 3 0.034070660379837018423130834983d3, 4 0.000000327018783663660700780197d0 / DATA a / -0.017762d0, 5.238000d0, 0.000000d0, -2.549150d1, 1 6.844500d0, 0.325000d0, 1.440300d0, 0.000000d0, 2 1.375700d0, 2.366660d1, 4.820000d0, 0.294200d0, 3 -1.123260d1, -2.265470d1, -1.788760d1, -4.933200d0, 4 1.109430391161019373812391218008d0, 5 -1.981395981400671095301629432211d0, 6 0.246912528778663959151808173743d0, 7 -0.843411332867484343974055795059d0 / DATA q / -0.006000d0, -0.003000d0, 0.000000d0, 6.470670d2, 1 3.227780d2, 2.204600d1, 0.267000d0, -1.600000d0, 2 0.491775937675717720291497417773d0, 0.108500d0, 3 0.586534703230779473334597524774d0, 4 -1.026243389120214352553706598564d0, 5 0.612903225806451612903225804745d0, 0.500000d0, 6 -0.391500d0, 0.825000d0, 0.741500d0, 7 0.103245882826119154987166286332d0, 8 0.160322434159191991394857495360d0, 9 -0.169859514687100893997445721324d0 / DATA x / 6.430000d2, 6.453000d2, 6.950000d2, 1 1.997750d2, 4.200400d2, 2 2.09945691135940719075293945960d1, 3 2.15814057875264119875397458907d1, 4 3.0135d1, 4.0484d1, 5 .175777517046267847932127026995d0, 6 .380293646126229135059562456934d0 / * EQUIVALENCE (cc, a(1) ), (pointA, q(1) ), (Tmin1, x(1)), * 1 (p3, a(2) ), (pointB, q(2) ), (Tmin2, x(2)), * 2 (delroc, a(3) ), (delpc, q(3) ), (Tmax, x(3)), * 3 (p2, a(4) ), (Tc, q(4) ), (Dmin, x(4)), * 4 (p1, a(5) ), (rhoc, q(5) ), (Dmax, x(5)), * 5 (beta, a(6) ), (Pc, q(6) ), (Pmin1, x(6)), * 6 (xko, a(7) ), (dPcdTc, q(7) ), (Pmin2, x(7)), * 7 (delTc, a(8) ), (slopdi, q(8) ), (Pmax1, x(8)), * 8 (besq, a(9) ), (p11, q(9) ), (Pmax2, x(9)), * 9 (aa, a(10)), (alpha, q(10)), (sl1, x(10)), * 0 (delta, a(11)), (p00, q(11)), (sl2, x(11)), * 1 (k1, a(12)), (p20, q(12)), * 2 (muc, a(13)), (p40, q(13)), * 3 (mu1, a(14)), (deli, q(14)), * 4 (mu2, a(15)), (alh1, q(15)), * 5 (mu3, a(16)), (beti, q(16)), * 6 (s00, a(17)), (gami, q(17)), * 7 (s20, a(18)), (p01, q(18)), * 8 (s01, a(19)), (p21, q(19)), * 9 (s21, a(20)), (p41, q(20)) END ******************************************************************* *** unit - Sets internal parameters according to user-specified * choice of units. Internal program units are degK(T), * and gm/cm**3(D); all other properties are computed in * dimensionless form and dimensioned at output time. * NOTE: conversion factors for j/g ---> cal/(g,mole) * (ffh (4 & 5)) are consistent with those given in * Table 1, Helgeson & Kirkham (1974a) for thermal calories, * and differ slightly with those given by Haar et al (1984) * for international calories. SUBROUTINE unit(it,id,ip,ih,itripl) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION fft(4), ffd(4), ffvd(4), ffvk(4), 1 ffs(4), ffp(5), ffh(6), 2 ffst(4), ffcd(4), ffch(6) COMMON /units/ ft, fd, fvd, fvk, fs, fp, fh, fst, fc SAVE DATA fft /1.0d0, 1.0d0, 0.555555556d0, 0.555555556d0 / DATA ffd /1.0d-3, 1.0d0, 1.80152d-2, 1.6018d-2/ DATA ffvd /1.0d0, 1.0d1, 0.555086816d0, 0.671968969d0 / DATA ffvk /1.0d0, 1.0d4, 1.0d4, 1.076391042d1 / DATA ffs /1.0d0, 1.0d2, 1.0d2, 3.280833d0 / DATA ffp /1.0d0, 1.0d1, 9.869232667d0, 1.45038d2, 1.01971d1/ DATA ffh /1.0d0, 1.0d0, 1.80152d1, 2.3901d-1, 1 4.305816d0, 4.299226d-1/ DATA ffst /1.0d0, 1.0d3, 0.555086816d2, 0.2205061d1 / DATA ffcd /1.0d0, 1.0d-2, 1.0d-2, 0.3048d0 / DATA ffch /1.0d-3, 1.0d0, 1.0d0, 0.23901d0, 1 0.23901d0, 0.947244d-3 / ft = fft(it) fd = ffd(id) fvd = ffvd(id) fvk = ffvk(id) fs = ffs(id) fp = ffp(ip) fh = ffh(ih) fst = ffst(id) fc = ffcd(id) * ffch(ih) IF (itripl .EQ. 1) CALL tpset RETURN END *********************************************************************** *** crtreg - Returns "TRUE" if input state conditions fall within * the critical region of H2O; otherwise returns "FALSE". * T, P, D, input in user-specified units, are returned in * degK, MPa, kg/m3. LOGICAL FUNCTION crtreg(isat,iopt,it,T,P,D) IMPLICIT DOUBLE PRECISION (a-h,o-z) LOGICAL llim, ulim COMMON /crits/ Tc, rhoc, Pc, Pcon, Ucon, Scon, dPcon COMMON /coefs/ a(20), q(20), x(11) COMMON /units/ ft, fd, fvd, fvk, fs, fp, fh, fst, fc SAVE EQUIVALENCE (Tmin1, x(1)), (Tmin2, x(2)), (Tmax, x(3)), 1 (Dmin, x(4)), (Dmax, x(5)), 2 (Pbase1, x(6)), (Pbase2,x(7)), 3 (PTmins, x(10)), (PTmaxs,x(11)) T = TdegK(it,T) IF (isat .EQ. 0) THEN IF (iopt .EQ. 1) THEN D = D * fd * 1.0d3 crtreg = ((T .GE. Tmin1) .AND. (T .LE. Tmax) .AND. 1 (D .GE. Dmin) .AND. (D .LE. Dmax)) ELSE P = P / fp IF ((T .LT. Tmin1) .OR. (T .GT. Tmax)) THEN crtreg = .FALSE. ELSE Pmin = Pbase1 + PTmins * (T - Tmin1) Pmax = Pbase2 + PTmaxs * (T - Tmin2) llim = (P .GE. Pmin) ulim = (P .LE. Pmax) IF (llim .AND. ulim) THEN crtreg = .TRUE. ELSE IF (llim .AND. (T .LE. Tmin2)) THEN isat1 = 1 ddummy = 0.0d0 Pstest = Pfind(isat1,T,ddummy) crtreg = (P .LE. Pstest) ELSE crtreg = .FALSE. END IF END IF END IF END IF ELSE IF (iopt .EQ. 1) THEN crtreg = (T .GE. Tmin1) ELSE P = P / fp crtreg = (P .GE. Pbase1) END IF END IF RETURN END ********************************************************************* *** HGKeqn - Computes thermodynamic and transport properties of * of H2O from the equation of state given by * Haar, Gallagher, & Kell (1984). SUBROUTINE HGKeqn(isat,iopt,itripl,Temp,Pres,Dens,epseqn) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPROP = 23) INTEGER epseqn DOUBLE PRECISION Dens(2), wprops(NPROP), wpliq(NPROP) COMMON /aconst/ wm, gascon, tz, aa, zb, dzb, yb, uref, sref COMMON /wpvals/ wprops, wpliq COMMON /RTcurr/ rt SAVE rt = gascon * Temp CALL HGKsat(isat,iopt,itripl,Temp,Pres,Dens,epseqn) IF (isat .EQ. 0) THEN CALL bb(Temp) CALL calcv3(iopt,itripl,Temp,Pres,Dens(1),epseqn) CALL thmHGK(Dens(1),Temp) CALL dimHGK(isat,itripl,Temp,Pres,Dens(1),epseqn) ELSE DO 10 i=1,NPROP 10 wpliq(i) = wprops(i) CALL dimHGK(2,itripl,Temp,Pres,Dens(2),epseqn) END IF RETURN END ***************************************************************** *** HGKsat - If isat=1, computes Psat(T) or Tsat(P) (iopt=1,2), * liquid and vapor densities, and associated * thermodynamic and transport properties. * If isat=0, checks whether T-D or T-P (iopt=1,2) * falls on or within TOL of the liquid-vapor * surface; if so, sets isat <- 1 and computes * properties. SUBROUTINE HGKsat(isat,iopt,itripl,Temp,Pres,Dens,epseqn) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION Dens(2) INTEGER epseqn COMMON /tolers/ TTOL, PTOL, DTOL, XTOL, EXPTOL, FPTOL COMMON /HGKcrt/ tcHGK, dcHGK, pcHGK COMMON /aconst/ wm, gascon, tz, aa, zb, dzb, yb, uref, sref COMMON /units/ ft, fd, fvd, fvk, fs, fp, fh, fst, fc COMMON /tpoint/ Utr, Str, Htr, Atr, Gtr, 1 Ttripl, Ptripl, Dltrip, Dvtrip COMMON /crits/ Tc, rhoC, Pc, Pcon, Ucon, Scon, dPcon SAVE IF (isat .EQ. 1) THEN IF (iopt .EQ. 1) THEN CALL pcorr(itripl,Temp,Pres,Dens(1),Dens(2),epseqn) ELSE CALL tcorr(itripl,Temp,Pres,Dens(1),Dens(2),epseqn) END IF ELSE IF ((Temp .GT. Tc) .OR. (Temp .LT. Ttripl) .OR. 1 ((iopt .EQ. 2) .AND. (Pres .GT. Pc))) THEN RETURN ELSE CALL pcorr(itripl,Temp,Ptemp,dltemp,dvtemp,epseqn) IF (((iopt .EQ. 2) .AND. 1 (DABS(Pres-Ptemp) .LE. PTOL)) .OR. 2 ((iopt .EQ. 1) .AND. 3 ((DABS(Dens(1)-dltemp) .LE. DTOL) .OR. 4 (DABS(Dens(1)-dvtemp) .LE. DTOL)))) THEN isat = 1 Pres = Ptemp Dens(1) = dltemp Dens(2) = dvtemp END IF END IF END IF RETURN END ************************************************************************ *** calcv3 - Compute the dependent state variable. SUBROUTINE calcv3(iopt,itripl,Temp,Pres,Dens,epseqn) IMPLICIT DOUBLE PRECISION (a-h,o-z) INTEGER epseqn COMMON /units/ ft, fd, fvd, fvk, fs, fp, fh, fst, fc COMMON /qqqq/ q0, q5 COMMON /aconst/ wm, gascon, tz, aa, z, dz, y, uref, sref COMMON /fcts/ ad, gd, sd, ud, hd, cvd, cpd, dpdt, dvdt, dpdd, 1 cjtt, cjth COMMON /RTcurr/ rt SAVE IF (iopt .EQ. 1) THEN CALL resid(Temp,Dens) CALL base(Dens,Temp) CALL ideal(Temp) Pres = rt * Dens * z + q0 ELSE IF (Temp .LT. tz) THEN CALL pcorr(itripl,Temp,ps,dll,dvv,epseqn) ELSE ps = 2.0d4 dll = 0.0d0 END IF IF (Pres .GT. ps) THEN dguess = dll ELSE dguess = Pres / Temp / 0.4d0 END IF CALL denHGK(Dens,Pres,dguess,Temp,dpdd) CALL ideal(Temp) END IF RETURN END ****************************************************************************** *** thmHGK - Computes thermodynamic functions in dimensionless * units from the HGK equation of state: Helmholtz, Gibbs, * internal energy, and enthalpy functions (ad, gd, ud, hd) are * per RT; entropy and heat capacities (sd, cvd, cpd) are per R. SUBROUTINE thmHGK(d,t) IMPLICIT DOUBLE PRECISION (a-h,o-z) COMMON /aconst/ wm, gascon, tz, aa, zb, dzb, y, uref, sref COMMON /qqqq/ qp, qdp COMMON /basef/ ab, gb, sb, ub, hb, cvb, pb, dpdtb COMMON /resf/ ar, gr, sr, ur, hr, cvr, dpdtr COMMON /idf/ ai, gi, si, ui, hi, cvi, cpi COMMON /fcts/ ad, gd, sd, ud, hd, cvd, cpd, dpdt, dvdt, dpdd, 1 cjtt, cjth COMMON /RTcurr/ rt SAVE z = zb + qp/rt/d dpdd = rt * (zb + y * dzb) + qdp ad = ab + ar + ai - uref/t + sref gd = ad + z ud = ub + ur + ui - uref/t dpdt = rt * d * dpdtb + dpdtr cvd = cvb + cvr + cvi cpd = cvd + t*dpdt*dpdt/(d*d*dpdd*gascon) hd = ud + z sd = sb + sr + si - sref dvdt = dpdt / dpdd / d / d cjtt = 1.0d0 / d - t * dvdt cjth = -cjtt / cpd / gascon RETURN END ************************************************************************* *** bb - Computes molecular parameters b, the "excluded volume" * (eq A.3), and B, the second virial coefficient (eq A.4), * in cm3/g (b1,b2) and their first and second derivatives * with respect to temperature (b1t,b1tt,b2t,b2tt). SUBROUTINE bb(t) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION v(10) COMMON /ellcon/ g1, g2, gf, b1, b2, b1t, b2t, b1tt, b2tt COMMON /aconst/ wm, gascon, tz, aa, z, dz, y, uref, sref COMMON /bconst/ bp(10), bq(10) SAVE v(1) = 1.0d0 DO 2 i=2,10 2 v(i) = v(i-1) * tz / t b1 = bp(1) + bp(2) * DLOG(1.0 / v(2)) b2 = bq(1) b1t = bp(2) * v(2) / tz b2t = 0.0d0 b1tt = 0.0d0 b2tt = 0.0d0 DO 4 i=3,10 b1 = b1 + bp(i) * v(i-1) b2 = b2 + bq(i) * v(i-1) b1t = b1t - (i-2) * bp(i) * v(i-1) / t b2t = b2t - (i-2) * bq(i) * v(i-1) / t b1tt = b1tt + bp(i) * (i-2)*(i-2) * v(i-1) / t / t 4 b2tt = b2tt + bq(i) * (i-2)*(i-2) * v(i-1) / t / t b1tt = b1tt - b1t / t b2tt = b2tt - b2t / t RETURN END *********************************************************************** *** base - Computes Abase, Gbase, Sbase, Ubase, Hbase, Cvbase * -- all per RT (dimensionless) -- as well as Pbase & dP/dT * -- both per (DRT) -- for the base function (ab, gb, sb, ub, * hb, cvb, pb, dpdtb). See Haar, Gallagher & Kell (1979), eq(1). SUBROUTINE base(d,t) IMPLICIT DOUBLE PRECISION (a-h,o-z) COMMON /ellcon/ g1, g2, gf, b1, b2, b1t, b2t, b1tt, b2tt COMMON /basef/ ab, gb, sb, ub, hb, cvb, pb, dpdtb COMMON /aconst/ wm, gascon, tz, a, z, dz, y, uref, sref SAVE y = .25d0 * b1 * d x = 1.0d0 - y z0 = (1.0d0 + g1*y + g2*y*y) / (x*x*x) z = z0 + 4.0d0*y*(b2/b1 - gf) dz0 = (g1 + 2.0d0*g2*y)/(x*x*x) + 1 3.0d0*(1.0d0 + g1*y + g2*y*y)/(x*x*x*x) dz = dz0 + 4.0d0*(b2/b1 - gf) pb = z ab = -DLOG(x) - (g2 - 1.0d0)/x + 28.16666667d0/x/x + 1 4.0d0*y*(b2/b1 - gf) + 15.166666667d0 + 2 DLOG(d*t*gascon/.101325d0) gb = ab + z ub = -t*b1t*(z - 1.0d0 - d*b2)/b1 - d*t*b2t sb = ub - ab hb = z + ub bb2tt = t * t * b2tt cvb = 2.0d0*ub + (z0 - 1.0d0)*(((t*b1t/b1)*(t*b1t/b1)) - 1 t*t*b1tt/b1) - d*(bb2tt - gf*b1tt*t*t) - 2 (t*b1t/b1)*(t*b1t/b1)*y*dz0 dpdtb = pb/t + d*(dz*b1t/4.0d0 + b2t - b2/b1*b1t) RETURN END *********************************************************************** *** resid - Computes residual contributions to pressure (q), the * Helmloltz function (ar) , dP/dD (q5), the Gibbs function * (gr), entropy (sr), internal energy (ur), enthalpy (hr), * isochoric heat capacity (cvr), and dP/dT. The first 36 * terms of the residual function represent a global * least-squares fit to experimental data outside the * critical region, terms 37-39 affect only the immediate * vicinity of the critical point, and the last term (40) * contributes only in the high pressure, low temperature * region. SUBROUTINE resid(t,d) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION qr(11), qt(10), qzr(9), qzt(9) COMMON /resf/ ar, gr, sr, ur, hr, cvr, dpdtr COMMON /qqqq/ q, q5 COMMON /nconst/ g(40), ii(40), jj(40), n COMMON /aconst/ wm, gascon, tz, aa, z, dz, y, uref, sref COMMON /addcon/ atz(4), adz(4), aat(4), aad(4) COMMON /RTcurr/ rt COMMON /tolers/ TTOL, PTOL, DTOL, XTOL, EXPTOL, FPTOL SAVE EQUIVALENCE (qr(3), qzr(1)), (qt(2), qzt(1)) qr(1) = 0.0d0 q5 = 0.0d0 q = 0.0d0 ar = 0.0d0 dadt = 0.0d0 cvr = 0.0d0 dpdtr = 0.0d0 e = DEXP(-aa * d) q10 = d * d * e q20 = 1.0d0 - e qr(2) = q10 v = tz / t qt(1) = t / tz DO 4 i=2,10 qr(i+1) = qr(i) * q20 4 qt(i) = qt(i-1) * v DO 10 i=1,n k = ii(i) + 1 l = jj(i) zz = k IF (k .EQ. 1) THEN qp = g(i) * aa * qr(2) * qzt(l) ELSE qp = g(i) * aa * qzr(k-1) * qzt(l) END IF q = q + qp q5 = q5 + aa*(2.0/d - aa*(1.0 - e*(k-1)/q20))*qp ar = ar + g(i)*qzr(k)*qzt(l)/q10/zz/rt dfdt = power(q20,DBLE(k))*(1-l)*qzt(l+1)/tz/k d2f = l * dfdt dpt = dfdt*q10*aa*k/q20 dadt = dadt + g(i)*dfdt dpdtr = dpdtr + g(i)*dpt 10 cvr = cvr + g(i)*d2f/gascon qp = 0.0d0 q2a = 0.0d0 DO 20 j=37,40 IF (g(j) .EQ. 0.0d0) GO TO 20 k = ii(j) km = jj(j) ddz = adz(j-36) del = d/ddz - 1.0d0 IF (DABS(del) .LT. 1.0d-10) del = 1.0d-10 ex1 = -aad(j-36) * power(del,DBLE(k)) IF (ex1 .LT. EXPTOL) THEN dex = 0.0d0 ELSE dex = DEXP(ex1) * power(del,DBLE(km)) END IF att = aat(j-36) tx = atz(j-36) tau = t/tx - 1.0d0 ex2 = -att * tau * tau IF (ex2 .LE. EXPTOL) THEN tex = 0.0d0 ELSE tex = DEXP(ex2) END IF q10 = dex * tex qm = km/del - k*aad(j-36)*power(del,DBLE(k-1)) fct = qm * d*d * q10 / ddz q5t = fct*(2.0d0/d + qm/ddz) - (d/ddz)*(d/ddz)*q10 * 1 (km/del/del + k*(k-1)*aad(j-36) * 2 power(del,DBLE(k-2))) q5 = q5 + q5t*g(j) qp = qp + g(j)*fct dadt = dadt - 2.0d0*g(j)*att*tau* q10 /tx dpdtr = dpdtr - 2.0d0*g(j)*att*tau* fct /tx q2a = q2a + t*g(j)*(4.0d0*att*ex2 + 2.0d0*att)*q10/tx/tx ar = ar + q10*g(j)/rt 20 CONTINUE sr = -dadt / gascon ur = ar + sr cvr = cvr + q2a/gascon q = q + qp RETURN END ************************************************************************ *** ideal - Computes thermodynamic properties for H2O in the * ideal gas state using equations given by Woolley (1979). SUBROUTINE ideal(t) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION c(18) COMMON /idf/ ai, gi, si, ui, hi, cvi, cpi SAVE DATA c / .19730271018d2, .209662681977d2, -.483429455355d0, 1 .605743189245d1, .2256023885d2, -.987532442d1, 2 -.43135538513d1, .458155781d0, -.47754901883d-1, 3 .41238460633d-2, -.27929052852d-3, .14481695261d-4, 4 -.56473658748d-6, .16200446d-7, -.3303822796d-9, 5 .451916067368d-11, -.370734122708d-13, 6 .137546068238d-15/ tt = t / 1.0d2 tl = DLOG(tt) gi = -(c(1)/tt + c(2)) * tl hi = (c(2) + c(1)*(1.0d0 - tl)/tt) cpi = c(2) - c(1)/tt DO 8 i=3,18 emult = power(tt,DBLE(i-6)) gi = gi - c(i) * emult hi = hi + c(i) * (i-6) * emult 8 cpi = cpi + c(i) * (i-6) * (i-5) * emult ai = gi - 1.0d0 ui = hi - 1.0d0 cvi = cpi - 1.0d0 si = ui - ai RETURN END ****************************************************************************** *** dalHGK - Computes/returns (d(alpha)/dt)p(d,t,alpha) * for the Haar et al. (1983) equation of state. DOUBLE PRECISION FUNCTION dalHGK(d,t,alpha) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION tempi(4), densi(4), betai(4), alphai(4), 1 g(40), k, l, km, lm, kp, lp INTEGER ll(40), kk(40) COMMON /aconst/ wm, gascon, tz, a, z, dz, y, uref, sref COMMON /ellcon/ g1, g2, gf, b1, b2, b1t, b2t, b1tt, b2tt COMMON /basef/ ab, gb, sb, ub, hb, cvb, pb, dpdtb COMMON /resf/ ar, gr, sr, ur, hr, cvr, dpdtr COMMON /qqqq/ q, q5 COMMON /nconst/ g, kk, ll, n COMMON /addcon/ tempi, densi, betai, alphai COMMON /tolers/ TTOL, PTOL, DTOL, XTOL, EXPTOL, FPTOL SAVE *** evaluate derivatives for the base function y = .25d0 * b1 * d x = 1.0d0 - y dydtp = (d/4.0d0)*(b1t - b1*alpha) dbdd = gascon*t * ((b1/4.0d0/x) * (1.0d0 - (g2-1.0d0)/x + 1 (g1+g2+1.0d0)/x/x) + b2 - b1*gf + 1.0d0/d) db2dd = gascon*t* ((b1*b1/16.0d0/x/x) * (1.0d0 - 1 2.0d0*(g2-1.0d0)/x + 3.0d0*(g1+g2+1.0d0)/x/x) - 2 1.0d0/d/d) db2ddt = gascon*t * ((b1t/4.0d0/x/x) * 1 (1.0d0 - (g2-1.0d0)*(1.0d0+y)/x + 2 (g1+g2+1.0d0)*(1.0d0+2.0d0*y)/x/x) + 3 b2t - gf*b1t) + dbdd/t db2dtp = dbdd/t + gascon*t* ( (b1*dydtp/4.0d0/x/x/x) * 1 (1.0d0 - g2 + 2.0d0*(g1+g2+1.0d0)/x) + 2 ((x*b1t + b1*dydtp)/4.0d0/x/x) * 3 (1.0d0 - (g2-1.0d0)/x + (g1+g2+1.0d0)/x/x) + 4 b2t - gf*b1t + alpha/d ) db3ddt = db2dd/t + gascon*t * ( (b1*b1*dydtp/8.0d0/x/x/x/x) * 1 (1.0d0 - g2 + 3.0d0*(g1+g2+1.0d0)/x) + 2 (b1*(x*b1t + b1*dydtp)/8.0d0/x/x/x) * 3 (1.0d0 - 2.0d0*(g2-1.0d0)/x + 3.0d0*(g1+g2+1.0d0)/x/x) 4 - 2.0d0*alpha/d/d ) db3dtt = (db2ddt - dbdd/t)/t + gascon*t* ( 1 (b1t*dydtp/2.0d0/x/x/x/x) * (1.0d0 - g2 + 2 (g1+g2+1.0d0)*(2.0d0+y)/x) + 3 ((x*b1tt + 2.0d0*b1t*dydtp)/4.0d0/x/x/x) * (1.0d0 - 4 (g2-1.0d0)*(1+y)/x + (g1+g2+1.0d0)*(1.0d0+2.0d0*y)/x/x) 5 + b2tt - gf*b1tt ) + (t*db2dtp - dbdd)/t/t *********************************************************** *** evaluate derivatives for the residual function * drdd = q/d/d * dr2dd = (q5 - 2.0d0/d*q)/d/d * dr2ddt = dpdtr/d/d e1 = DEXP(-a * d) e2 = 1.0d0 - e1 tzt = tz / t drdd = 0.0d0 dr2dd = 0.0d0 dr2ddt = 0.0d0 dr2dtp = 0.0d0 dr3ddt = 0.0d0 dr3dtt = 0.0d0 *** evaluate terms 1-36 DO 10 i=1,n k = DBLE(kk(i)) + 1.0d0 l = DBLE(ll(i)) - 1.0d0 km = k - 1.0d0 lm = l - 1.0d0 kp = k + 1.0d0 lp = l + 1.0d0 xtzt = power(tzt,l) drdd = drdd + g(i) * xtzt*power(e2,km)*e1 dr2dd = dr2dd + g(i) * e1*xtzt*power(e2,km) * 1 (km*e1/e2 - 1.0d0) dr2ddt = dr2ddt - g(i)*e1*l*power(e2,km)*power(tzt,lp)/tz dr2dtp = dr2dtp + g(i)*e1*power(e2,km)*xtzt * 1 ( d*alpha - l/t - km*e1*d*alpha/e2 ) dr3ddt = dr3ddt + g(i)*( km*d*alpha*e1*e1*xtzt* 1 power(e2,k-3.0d0) + e1*xtzt*power(e2,km)* 2 (km*e1/e2 - 1.0d0) * (d*alpha - l/t - 3 km*d*alpha*e1/e2) ) dr3dtt = dr3dtt + g(i)*l*e1*power(e2,km)*power(tzt,lp)/tz 1 * ( lp/t + d*alpha*km*e1/e2 - d*alpha ) 10 CONTINUE *** evaluate terms 37-40 DO 20 i=37,40 k = DBLE(kk(i)) l = DBLE(ll(i)) km = k - 1.0d0 lm = l - 1.0d0 kp = k + 1.0d0 lp = l + 1.0d0 ai = alphai(i-36) bi = betai(i-36) di = densi(i-36) ti = tempi(i-36) tau = t/ti - 1.0d0 del = d/di - 1.0d0 IF (DABS(del) .LT. 1.0d-10) del = 1.0d-10 ex1 = -ai * power(del,k) IF (ex1 .LT. EXPTOL) THEN dex = 0.0d0 ELSE dex = DEXP(ex1) END IF ex2 = -bi * tau * tau IF (ex2 .LE. EXPTOL) THEN tex = 0.0d0 ELSE tex = DEXP(ex2) END IF ex12 = dex * tex qm = l/del - k*ai*power(del,km) xdell = power(del,l) xdelk = power(del,k) drdd = drdd + g(i)*xdell*ex12/di*qm dr2dd = dr2dd + g(i)*xdell*ex12/di/di * (qm*qm - 1 l/di/di - ai*k*km*power(del,k-2.0d0)) dr2ddt = dr2ddt - g(i)*2.0d0*bi*tau*ex12*xdell/ti/di*qm dr2dtp = dr2dtp + g(i)/di*( d*alpha*xdell*ex12/di/del/del * 1 (l + ai*k*km*xdelk) + qm * ( ex12 * 2 ( xdell* (k*ai*d*alpha*power(del,km)/di - 3 2.0d0*bi*tau/ti) - l*d*alpha*power(del,lm)/di) ) ) dr3ddt = dr3ddt + g(i)/di/di*( xdell*ex12* (2.0d0*qm* 1 (l*d*alpha/di/del/del + ai*k*km*d*alpha* 2 power(del,k-2.0d0)/di) - 2.0d0*l*d*alpha/di/del 3 /del/del + ai*k*km*(k-2.0d0)*power(del,k-3.0d0)* 4 d*alpha/di) + (qm*qm - l/del/del - ai*k*km* 5 power(del,k-2.0d0)) *(ex12*xdell*( ai*k* 6 power(del,k-1.0d0)*d*alpha/di - 2.0d0*bi*tau/ti ) - 7 ex12*l*power(del,l-1.0d0)*d*alpha/di) ) dr3dtt = dr3dtt - 2.0d0*g(i)*bi/ti/di * ( tau*xdell*ex12*d* 1 alpha/del/del/di * (l + ai*k*km*power(del,k)) + 2 qm*( xdell*ex12*( ai*k*d*alpha*tau*power(del,km)/di 3 + (1.0d0 - 2.0d0*bi*tau*tau)/ti - 4 tau*l*d*alpha/di/del ) ) ) 20 CONTINUE *** compute (d(alpha)/dT)P dalHGK = ((db3dtt + dr3dtt)*(2.0d0*(dbdd + drdd) + 1 d*(db2dd + dr2dd)) - 2 (db2ddt + dr2ddt)*(2.0d0*(db2dtp + dr2dtp) + 3 d*(db3ddt + dr3ddt) - d*alpha*(db2dd + dr2dd))) / 4 (2.0d0*(dbdd + drdd) + d*(db2dd + dr2dd)) / 5 (2.0d0*(dbdd + drdd) + d*(db2dd + dr2dd)) RETURN END ****************************************************************************** *** denHGK - Computes density (d in g/cm3) and dP/dD (dPdd) as * f(p(MPa),t(degK)) from an initial density guess (dguess). SUBROUTINE denHGK(d,p,dguess,t,dpdd) IMPLICIT DOUBLE PRECISION (a-h,o-z) COMMON /qqqq/ q0, q5 COMMON /aconst/ wm, gascon, tz, aa, z, dz, y, uref, sref COMMON /basef/ ab, gb, sb, ub, hb, cvb, pb, dpdtb COMMON /RTcurr/ rt SAVE i = 0 d = dguess 10 i = i + 1 IF (d .LE. 0.0d0) d = 1.0d-8 IF (d .GT. 1.9d0) d = 1.9d0 CALL resid(t,d) CALL base(d,t) pp = rt * d * pb + q0 dpdd = rt * (z + y * dz) + q5 *** if dpdd < 0 assume d in 2-phase region and adjust accordingly *** IF (dpdd .GT. 0.0d0) GO TO 20 IF (dguess .GE. 0.2967d0) d = d * 1.02d0 IF (dguess .LT. 0.2967d0) d = d * 0.98d0 IF (i .LE. 10) GO TO 10 20 dpdx = dpdd * 1.1d0 IF (dpdx .LT. 0.1d0) dpdx = 0.1d0 dp = DABS(1.0d0 - pp/p) IF ((dp .LT. 1.0d-8) .OR. 1 ((dguess .GT. 0.3d0) .AND. (dp .LT. 1.0d-7)) .OR. 2 ((dguess .GT. 0.7d0) .AND. (dp .LT. 1.0d-6))) RETURN x = (p - pp) / dpdx IF (DABS(x) .GT. 0.1d0) x = x * 0.1d0 / DABS(x) d = d + x IF (d .LE. 0.0d0) d = 1.0d-8 IF (i .LE. 30) GO TO 10 RETURN END *********************************************************************** *** PsHGK - Returns an approximation to Psaturation(T) that agrees * to within 0.02% of that predicted by the HGK surface * for temperatures up to within roughly a degree of * the critical point. DOUBLE PRECISION FUNCTION PsHGK(t) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION a(8) SAVE DATA a /-.78889166d1, .25514255d1, -.6716169d1, .33239495d2, 1 -.10538479d3, .17435319d3, -.14839348d3, .48631602d2/ IF (T .LE. 314.0d0) THEN pl = 6.3573118d0 - 8858.843d0/t + 1 607.56335d0 * power(t,-0.6d0) PsHGK = 0.1d0 * DEXP(pl) ELSE v = t / 647.25d0 w = DABS(1.0d0 - v) b = 0.0d0 DO 4 i=1,8 z = i b = b + a(i)*power(w,(z + 1.0d0)/2.0d0) 4 CONTINUE q = b / v PsHGK = 22.093d0 * DEXP(q) END IF RETURN END *********************************************************************** *** TsHGK - Returns Tsaturation(P). DOUBLE PRECISION FUNCTION TsHGK(p) IMPLICIT DOUBLE PRECISION (a-h,o-z) SAVE TsHGK = 0.0d0 IF (p .GT. 22.05d0) RETURN k = 0 pl = 2.302585d0 + DLOG(p) tg = 372.83d0 + 1 pl*(27.7589d0 + pl*(2.3819d0 + pl*(0.24834d0 + 2 pl*0.0193855d0))) 1 IF (tg .LT. 273.15d0) tg = 273.15d0 IF (tg .GT. 647.00d0) tg = 647.00d0 IF (k .GE. 8) THEN TsHGK = tg ELSE k = k + 1 pp = PsHGK(tg) dp = TdPsdT(tg) IF (ABS(1.0d0 - pp/p) .LT. 1.0d-5) THEN TsHGK = tg ELSE tg = tg * (1.0d0 + (p - pp)/dp) GO TO 1 END IF END IF RETURN END *********************************************************************** *** TdPsdT - Returns T*(dPsat/dT). DOUBLE PRECISION FUNCTION TdPsdT(t) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION a(8) SAVE DATA a /-.78889166d1, .25514255d1, -.6716169d1, .33239495d2, 1 -.10538479d3, .17435319d3, -.14839348d3, .48631602d2/ v = t / 647.25d0 w = 1.0 - v b = 0.0d0 c = 0.0d0 DO 4 i=1,8 z = i y = a(i) * power(w,(z + 1.0d0)/2.0d0) c = c + y/w*(0.5d0 - 0.5d0*z - 1.0d0/v) 4 b = b + y q = b / v TdPsdT = 22.093d0 * DEXP(q) * c RETURN END *********************************************************************** *** corr - Computes liquid and vapor densities (dliq & dvap) * and (Gl-Gv)/RT (delg) for T-P conditions on or * near the saturation surface. SUBROUTINE corr(itripl,t,p,dl,dv,delg,epseqn) IMPLICIT DOUBLE PRECISION (a-h,o-z) INTEGER epseqn COMMON /qqqq/ q00, q11 COMMON /aconst/ wm, gascon, tz, aa, zb, dzb, yb, uref, sref COMMON /fcts/ ad, gd, sd, ud, hd, cvd, cpd, dpdt, dvdt, dpdd, 1 cjtt, cjth COMMON /basef/ ab, gb, sb, ub, hb, cvb, pb, dpdtb COMMON /RTcurr/ rt COMMON /units/ ft, fd, fvd, fvk, fs, fp, fh, fst, fc COMMON /HGKcrt/ tcHGK, dcHGK, pcHGK SAVE CALL bb(t) dguess = dl IF (dl .LE. 0.0d0) dguess = 1.11d0 - 0.0004d0*t CALL denHGK(dl,p,dguess,t,dpdd) CALL ideal(t) CALL thmHGK(dl,t) *** save liquid properties CALL dimHGK(1,itripl,t,p,dl,epseqn) gl = gd dguess = dv IF (dv .LE. 0.0d0) dguess = p / rt CALL denHGK(dv,p,dguess,t,dpdd) IF (dv .LT. 5.0d-7) dv = 5.0d-7 CALL ideal(t) CALL thmHGK(dv,t) *** vapor properties will be available *** in COMMON /fcts/ (dimensionless) after *** pcorr's final call of corr (delg < 10d-4) gv = gd delg = gl - gv RETURN END *********************************************************************** *** pcorr - Computes Psaturation(T) (p) and liquid and vapor * densities (dl & dv) from refinement of an initial * approximation (PsHGK(t)) in accord with Gl = Gv. SUBROUTINE pcorr(itripl,t,p,dl,dv,epseqn) IMPLICIT DOUBLE PRECISION (a-h,o-z) INTEGER epseqn COMMON /aconst/ wm, gascon, tz, aa, zb, dzb, yb, uref, sref SAVE p = PsHGK(t) dl = 0.0d0 dv = 0.0d0 2 CALL corr(itripl,t,p,dl,dv,delg,epseqn) dp = delg * gascon * T / (1.0d0/dv - 1.0d0/dl) p = p + dp IF (DABS(delg) .GT. 1.0d-4) GO TO 2 RETURN END ************************************************************ *** tcorr - Computes Tsaturation(P) (t) and liquid and vapor * densities (dl & dv) from refinement of an initial * approximation (TsHGK(p)) in accord with Gl = Gv. SUBROUTINE tcorr(itripl,t,p,dl,dv,epseqn) IMPLICIT DOUBLE PRECISION (a-h,o-z) INTEGER epseqn COMMON /aconst/ wm, gascon, tz, aa, zb, dzb, yb, uref, sref COMMON /RTcurr/ rt SAVE t = TsHGK(p) IF (t .EQ. 0.0d0) RETURN dl = 0.0d0 dv = 0.0d0 1 rt = t * gascon CALL corr(itripl,t,p,dl,dv,delg,epseqn) dp = delg * gascon * t / (1.0d0/dv - 1.0d0/dl) t = t * (1.0d0 - dp/TdPsdT(t)) IF (DABS(delg) .GT. 1.0d-4) GO TO 1 RETURN END *************************************************************** *** LVSeqn - Computes thermodynamic and transport properties of * critical region H2O (369.85-419.85 degC, * 0.20-0.42 gm/cm3) from the fundamental equation given * by Levelt Sengers, et al (1983): J.Phys.Chem.Ref.Data, * V.12, No.1, pp.1-28. SUBROUTINE LVSeqn(isat,iopt,itripl,T,P,Dens,epseqn) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPROP = 23) DOUBLE PRECISION wprops(NPROP), wpliq(NPROP), Dens(2) LOGICAL cpoint INTEGER epseqn COMMON /coefs/ a(20), q(20), x(11) COMMON /crits/ Tc, rhoc, Pc, Pcon, Ucon, Scon, dPcon COMMON /therm/ AE, GE, U, H, Entrop, Cp, Cv, betaw, alphw, 1 heat, Speed COMMON /satur/ Dliq, Dvap, DH2O, iphase COMMON /param/ r1, th1 COMMON /units/ ft, fd, fvd, fvk, fs, fp, fh, fst, fc COMMON /wpvals/ wprops, wpliq SAVE cpoint = .FALSE. DH2O = Dens(1) 10 CALL LVSsat(iopt,isat,T,P,DH2O) IF ((isat .NE. 0) .OR. (iopt .NE. 1)) CALL denLVS(isat,T,P) IF (isat .EQ. 0) THEN Dens(1) = DH2O ELSE Dens(1) = Dliq Dens(2) = Dvap END IF IF (isat .EQ. 0) THEN CALL thmLVS(isat,T,r1,th1) CALL dimLVS(isat,itripl,th1,T,P*1.0d1,dl,dv,wprops,epseqn) IF (cpoint) THEN CALL cpswap Dens(1) = cdens Dens(2) = cdens isat = 1 iopt = ioptsv END IF ELSE th1 = -1.0d0 CALL thmLVS(isat,T,r1,th1) CALL dimLVS(isat,itripl,th1,T,P*1.0d1,dl,dv,wprops,epseqn) th1 = 1.0d0 CALL thmLVS(isat,T,r1,th1) CALL dimLVS(isat,itripl,th1,T,P*1.0d1,dl,dv,wpliq,epseqn) IF (dl .EQ. dv) THEN cpoint = .TRUE. cdens = dl T = 647.0670000003d0 P = 22.0460000008d0 ioptsv = iopt iopt = 2 isat = 0 GO TO 10 END IF END IF END ********************************************************************* *** cpswap - Load critical point A, G, U, H, S, Vs, Di, ZB, * albe values from wpliq into wprops and * approximations to critical Cv, Cp, alpha, beta, * visc, tcond, Prndtl, tdiff, visck, YB, QB, XB, * daldT, st values from wprops into wpliq. SUBROUTINE cpswap IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPROP = 23) INTEGER aw, gw, sw, uw, hw, cvw, cpw, vsw, alw, bew, 1 diw, viw, tcw, stw, tdw, Prw, vikw, albew, 2 ZBw, YBw, QBw, dalwdT, XBw DOUBLE PRECISION wprops(NPROP), wpliq(NPROP) COMMON /wpvals/ wprops, wpliq COMMON /units/ ft, fd, fvd, fvk, fs, fp, fh, fst, fc SAVE DATA aw, gw, sw, uw, hw, cvw, cpw, vsw, alw, bew, diw, viw, 1 tcw, stw, tdw, Prw, vikw, albew, ZBw, YBw, QBw, 2 dalwdT, XBw 2 / 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 3 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 / wprops(aw) = wpliq(aw) wprops(gw) = wpliq(gw) wprops(sw) = wpliq(sw) wprops(uw) = wpliq(uw) wprops(hw) = wpliq(hw) wprops(diw) = wpliq(diw) wprops(ZBw) = wpliq(ZBw) wprops(stw) = wpliq(stw) wpliq(cvw) = wprops(cvw) wpliq(cpw) = wprops(cpw) wpliq(alw) = wprops(alw) wpliq(bew) = wprops(bew) wpliq(YBw) = wprops(YBw) wpliq(QBw) = wprops(QBw) wpliq(XBw) = wprops(XBw) wpliq(tcw) = wprops(tcw) wpliq(tdw) = wprops(tdw) wpliq(Prw) = wprops(Prw) wpliq(dalwdT) = wprops(dalwdT) wpliq(albew) = wprops(albew) wprops(vsw) = 0.429352766443498d2 * fs wprops(viw) = 1.0d6 wprops(vikw) = 1.0d6 wpliq(vsw) = wprops(vsw) wpliq(viw) = wprops(viw) wpliq(vikw) = wprops(vikw) END ********************************************************************* *** LVSsat - If isat=1, computes Psat(T) or Tsat(P) (iopt=1,2). * If isat=0, checks whether T-D or T-P (iopt=1,2) * falls on or within TOL of the liq-vap surface; if so, * isat <- 1 and T <- Tsat. SUBROUTINE LVSsat(iopt,isat,T,P,D) IMPLICIT DOUBLE PRECISION (a-h,o-z) COMMON /tolers/ TTOL, PTOL, DTOL, XTOL, EXPTOL, FPTOL COMMON /crits/ Tc, rhoc, Pc, Pcon, Ucon, Scon, dPcon SAVE DATA ERRTOL, TCTOL / 1.0d-12, 1.0d-2 / IF (isat .EQ. 1) THEN IF (iopt .EQ. 1) THEN P = Pfind(isat,T,D) END IF T = TsLVS(isat,P) ELSE IF (iopt .EQ. 1) THEN P = Pfind(isat,T,D) END IF IF (P-ERRTOL .GT. Pc) THEN RETURN ELSE CALL backup Tsat = TsLVS(isat,P) IF (DABS(Tsat-T) .LT. TCTOL) THEN T = Tsat isat = 1 ELSE CALL restor END IF END IF END IF RETURN END ********************************************************************* *** denLVS - Calculates DH2O(T,P) or Dvap,Dliq(T,P) from the * Levelt Sengers, et al (1983) critical region * equation of state. SUBROUTINE denLVS(isat,T,P) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION s(2), sd(2) COMMON /coefs/ a(20), q(20), x(11) COMMON /crits/ Tc, rhoc, Pc, Pcon, Ucon, Scon, dPcon COMMON /satur/ Dliq, Dvap, DH2O, iphase COMMON /therm/ AE, GE, U, H, Entrop, Cp, Cv, betaw, alphw, 1 heat, Speed COMMON /param/ r1, th1 COMMON /deri2/ dPdD, dPdT SAVE EQUIVALENCE (Dmin, x(4)), (Dmax, x(5)), (pw11, q(9)), 1 (xk0, a(7)), (xk1, a(12)) IF (isat .EQ. 0) THEN DH2O = rhoc DO 10 i=1,20 Pnext = Pfind(isat,T,DH2O) Pdif = Pnext - P IF (iphase .EQ. 2) THEN IF (DABS(Pdif) .LE. 0.0d0) THEN RETURN ELSE END IF IF (Pdif .LT. 0.0d0) THEN DH2O = Dmax ELSE DH2O = Dmin END IF ELSE delD = -Pdif/dPdD DH2O = DH2O + delD IF (DH2O .LT. Dmin) DH2O = Dmin IF (DH2O .GT. Dmax) DH2O = Dmax IF (DABS(delD/DH2O) .LT. 1.0d-6) RETURN END IF 10 CONTINUE ELSE Tw = -Tc/T dTw = 1.0d0 + Tw CALL ss(r1,th1,s,sd) rho1 = 1.0d0+pw11*dTw+a(1)*(s(1)+s(2)) rho2 = xk0*power(r1,a(6)) + xk1*power(r1,q(16)) Dvap = rhoc * (rho1 - rho2) Dliq = rhoc * (rho1 + rho2) RETURN END IF RETURN END ********************************************************************* *** TsLVS - Returns saturation T(P) DOUBLE PRECISION FUNCTION TsLVS(isat,P) IMPLICIT DOUBLE PRECISION (a-h,o-z) COMMON /therm/ AE, GE, U, H, Entrop, Cp, Cv, betaw, alphw, 1 heat, Speed COMMON /satur/ Dliq, Dvap, DH2O, iphase COMMON /crits/ Tc, rhoc, Pc, Pcon, Ucon, Scon, dPcon COMMON /deri2/ dPdD, dPdT SAVE TsLVS2 = Tc - 1.0d0 D = rhoc DO 10 i=1,20 Pnext = Pfind(isat,TsLVS2,D) dT = (Pnext - P)/dPdT TsLVS2 = TsLVS2 - dT IF (TsLVS2 .GT. Tc) THEN TsLVS2 = Tc ELSE IF (DABS(dT/TsLVS2) .LT. 1.0d-8) THEN GO TO 20 ELSE END IF END IF 10 CONTINUE 20 TsLVS = TsLVS2 RETURN END ********************************************************************* *** Pfind - Returns P(T,D). Computes (dP/dD)T when invoked by SUB * Dfind (isat=0) and (dP/dT)D when invoked by SUB TsLVS * (isat=1). Also computes 1st & 2nd partial derivatives * the singular part of the potential (Delta P tilde) that * are used in SUB thmLVS. DOUBLE PRECISION FUNCTION Pfind(isat,T,D) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION s(2), xk(2), sd(2) COMMON /coefs/ a(20), q(20), x(11) COMMON /crits/ Tc, rhoc, Pc, Pcon, Ucon, Scon, dPcon COMMON /satur/ Dliq, Dvap, DH2O, iphase COMMON /therm/ AE, GE, U, H, Entrop, Cp, Cv, betaw, alphw, 1 heat, Speed COMMON /param/ r1, th1 COMMON /tolers/ TTOL, PTOL, DTOL, XTOL, EXPTOL, FPTOL COMMON /deriv/ amu, s, Pw, Tw, dTw, dM0dT, dP0dT, 1 d2PdM2, d2PdMT, d2PdT2, p0th, p1th, xk COMMON /deri2/ dPdD, dPdT *************************************** COMMON /abc2/ r, th *************************************** SAVE EQUIVALENCE (Pw1, a(5)), (Pw2, a(4)), (Pw3, a(2)), 1 (amc, a(13)), (am1, a(14)), (am2, a(15)), 2 (am3, a(16)), (p00, q(11)), (p20, q(12)), 3 (p40, q(13)), (p01, q(18)), (p21, q(19)), 4 (p41, q(20)), (aa, a(10)), (xk0, a(7)), 5 (xk1, a(12)), (pw11,q(9)), (alpha,q(10)), 6 (alhi,q(15)), (besq,a(9)) xk(1) = xk0 xk(2) = xk1 IF (DABS(T-Tc) .LT. FPTOL) T = Tc Tee = (T-Tc)/Tc Tw = -Tc/T dTw = 1.0d0 + Tw IF (isat .EQ. 0) THEN rho = D / rhoc CALL conver(rho,Tee,amu,th1,r1,rho1,s,rhodi,err) ELSE th1 = -1.0d0 th = th1 r1 = dTw/(1.0d0-besq) r = r1 CALL ss(r1,th1,s,sd) rho = th1 * (xk0*power(r1,a(6)) + 1 xk1*power(r1,q(16))) + 2 a(1)*(s(1)+s(2)) rho = 1.0d0+pw11*dTw+rho amu = 0.0d0 D = rho * rhoc END IF tt1 = th1*th1 tt2 = tt1*tt1 Pw0 = 1.0d0+dTw*(Pw1+dTw*(Pw2+dTw*Pw3)) IF (isat .EQ. 0) THEN Pwmu = amu*rhodi ELSE Pwmu = 0.0d0 END IF p0th = p00+p20*tt1+p40*tt2 p1th = p01+p21*tt1+p41*tt2 dPw0 = xk0*p0th*power(r1,2.0d0-alpha) dPw1 = xk1*p1th*power(r1,2.0d0-alhi) dPw = aa*(dPw0+dPw1) Pw = Pw0 + Pwmu + dPw Pfind = Pw * Pcon * T IF (DABS(th1) .LT. 1.0d0) THEN iphase = 1 ELSE iphase = 2 dP0dT = Pw1+dTw*(2.0d0*Pw2+3.0d0*Pw3*dTw) dM0dT = am1+dTw*(2.0d0*am2+3.0d0*am3*dTw) Uw = dP0dT-rho*dM0dT+pw11*amu+s(1)+s(2) dPdTcd = Uw + rho*dM0dT dPwdTw = Pw - Tw*dPdTcd dPdT = Pcon * dPwdTw END IF CALL aux(r1,th1,d2PdT2,d2PdMT,d2PdM2,aa,xk,sd,Cvcoex) IF (iphase .EQ. 1) dPdD = dPcon * D * T / d2PdM2 RETURN END *************************************************************** *** aux - Calculates some second derivatives of the * anomalous part of the equation of state. SUBROUTINE aux(r1,th1,d2PdT2,d2PdMT,d2PdM2,aa,xk,sd,Cvcoex) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION xk(2), s(2), sd(2), w(2), y(2), z(2), coex(2) COMMON /coefs/ a(20), q(20), x(11) SAVE EQUIVALENCE (cc, a(1)), (beta, a(6)), (besq,a(9)), 1 (delta,a(11)), (alpha,q(10)), (s00, a(17)), 2 (s20, a(18)), (s01, a(19)), (s21, a(20)) deli = 0.0d0 s(1) = s00+s20*th1*th1 s(2) = s01+s21*th1*th1 sd(1) = 2.0*th1*s20 sd(2) = 2.0*th1*s21 ww = 0.0d0 yy = 0.0d0 zz = 0.0d0 gamma = beta*(delta-1.0d0) tt1 = th1*th1 ter = 2.0d0*beta*delta-1.0d0 g = (1.0+(besq*ter-3.0)*tt1 - besq*(ter-2.0)*tt1*tt1) Cvcoex = 0.0d0 DO 30 i=1,2 alhi = alpha - deli beti = beta + deli gami = gamma - deli IF (r1 .NE. 0.0d0) THEN w(i) = (1.0-alhi)*(1.0-3.0*tt1)*s(i) - 1 beta*delta*(1.0-tt1)*th1*sd(i) w(i) = (w(i)*power(r1,-alhi))/g w(i) = w(i) * xk(i) ww = ww + w(i) y(i) = beti*(1.0d0-3.0d0*tt1)*th1 - 1 beta*delta*(1.0d0-tt1)*th1 y(i) = (y(i)*power(r1,beti-1.0d0)) * xk(i) / g yy = yy + y(i) z(i) = 1.0d0-besq*(1.0d0-(2.0d0*beti))*tt1 z(i) = (z(i)*power(r1,-gami)) * xk(i) / g zz = zz + z(i) a1 = (beta*(delta-3.0d0)-3.0d0*deli-besq*alhi*gami) / 1 (2.0d0*besq*besq*(2.0d0-alhi)*(1.0d0-alhi)*alhi) a2 = 1+((beta*(delta-3.0d0)-3.0d0*deli-besq*alhi*ter) / 1 (2.0d0*besq*(1.0d0-alhi)*alhi)) a2 = -a2 a4 = 1.0d0+((ter-2.0d0)/(2.0d0*alhi)) f1 = a1 + a2 + a4 coex(i) = ((2.0d0-alhi)*(1.0d0-alhi)*power(r1,-alhi) * 1 f1*xk(i)) Cvcoex = Cvcoex + coex(i) END IF deli = 0.5d0 30 CONTINUE d2PdT2 = aa * ww d2PdMT = yy + aa*cc*ww d2PdM2 = zz/aa + 2.0d0*cc*yy + cc*cc*aa*ww RETURN END *************************************************************** *** conver - Transforms T,D to parametric variables r,theta * according to the revised and scaled equations. SUBROUTINE conver(rho,Tee,amu,th1,r1,rho1s,s1,rhodi,error1) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION s1(2), sd(2) COMMON /coefs/ a(20), q(20), x(11) COMMON /crits/ Tc, rhoc, Pc, Pcon, Ucon, Scon, dPcon ************************************************************** COMMON /abc2/ r, th ************************************************************** SAVE EQUIVALENCE (beta,a(6)), (delta,a(11)), (xk1, a(12)), 1 (cc, a(1)), (alhi, q(15)), (alpha,q(10)), 2 (besq,a(9)), (p11, q(9)), (deli, q(14)), 3 (p1w, q(18)), (p2w, q(19)), (p4w, q(20)), 4 (aa, a(10)), (xk0, a(7)), (s00, a(17)), 5 (s20, a(18)), (betai,q(16)) Tstar = Tee + 1.0d0 dtstin = 1.0d0 - (1.0d0 / Tstar) r1 = dtstin IF (dtstin .LE. 0.0d0) THEN r1 = dtstin/(1.0d0-besq) th1 = 1.0d0 ELSE th1 = 0.0d0 END IF CALL ss(r1,th1,s1,sd) rhodi = 1.0d0 + p11*dtstin rhodit = rhodi + cc*s1(1) + cc*s1(2) drho = rho - rhodit amu = 0.0d0 IF (dtstin .LE. 0.0d0) THEN rho1co = xk0*power(r1,beta) + xk1*power(r1,betai) twofaz = rho1co IF (DABS(drho) .LE. twofaz) THEN rho1s = DSIGN(rho1co,drho) + cc*s1(1) th1 = DSIGN(1.00d0,drho) error1 = 1.0d0 r = r1 th = th1 RETURN END IF END IF IF (drho .EQ. 0.0d0) THEN th1 = 0.0d0 r1 = dtstin rho1s = cc*s1(1) END IF *** rule for first pass *** y1 = dtstin den1 = rho - rhodit CALL rtheta(r1,th1,den1,y1) tt = th1*th1 amu = aa*power(r1,beta*delta)*th1*(1.0d0-tt) y1 = dtstin + cc*amu CALL ss(r1,th1,s1,sd) rhoweg = xk1*power(r1,betai)*th1 + cc*s1(2) rho1s = den1 + cc*s1(1) + rhoweg error1 = rho - rhodi - rho1s r = r1 th = th1 IF (DABS(error1) .LT. 1.0d-5) THEN RETURN END IF *** rule for second pass *** den12 = rho - rhodi - cc*s1(1) + rhoweg IF (den12 .EQ. den1) den12 = den1 - 1.0d-6 CALL rtheta(r1,th1,den12,y1) tt = th1*th1 amu = aa*power(r1,beta*delta)*th1*(1.0d0-tt) y1 = dtstin + cc*amu CALL ss(r1,th1,s1,sd) rhoweg = xk1*power(r1,betai)*th1 + cc*s1(2) rho1s2 = den12 + cc*s1(1) + rhoweg error2 = rho - rhodi - rho1s2 IF (DABS(error2) .LE. 1.0d-5) THEN r = r1 th = th1 error1 = error2 rho1s = rho1s2 RETURN END IF *** rule for nth pass *** den2 = den12 DO 44 isig=1,10 slope = (error2-error1)/(den2-den1) hold = den2 den2 = den1 - (error1/slope) CALL rtheta(r1,th1,den2,y1) tt = th1*th1 amu = aa*power(r1,beta*delta)*th1*(1.0d0-tt) y1 = dtstin + cc*amu CALL ss(r1,th1,s1,sd) rhoweg = xk1*power(r1,betai)*th1 + cc*s1(2) rho1s = den2 + cc*s1(1) + rhoweg error1 = error2 error2 = rho - rhodi - rho1s r = r1 th = th1 IF (DABS(error2) .LT. 1.0d-6) RETURN den1 = hold 44 CONTINUE RETURN END ********************************************************************* *** rtheta - Fits data for 1.0 < theta < 1.000001. * Solves: * rho = em*theta*(r**beta) * Tee = r*(1.0d0-besq*theta*theta) * * Routine given by Moldover (1978): Jour. Res. NBS, v. 84, n. 4, * p. 329 - 334. SUBROUTINE rtheta(r,theta,rho,Tee) IMPLICIT DOUBLE PRECISION (a-h,o-z) COMMON /coefs/ a(20), q(20), x(11) SAVE EQUIVALENCE (beta,a(6)), (em,a(7)), (besq,a(9)) IF (em .LE. 0.0d0 .OR. besq .LE. 1.0d0) GO TO 600 absrho = DABS(rho) IF (absrho .LT. 1.0d-12) GO TO 600 bee = DSQRT(besq) IF (DABS(Tee) .LT. 1.0d-12) GO TO 495 IF (Tee .LT. 0.0d0) THEN z = 1.0d0-(1.0d0-bee)*Tee/(1.0d0-besq) * 1 power(em/absrho,1.0d0/beta) ELSE z = power(1.0d0+Tee*power(em/bee/absrho,1.0d0/beta), 1 -beta) END IF IF (z .GT. 1.00234d0*bee) GO TO 496 c = -rho*bee/em/power(DABS(Tee),beta) z = DSIGN(z,rho) DO 500 n=1,16 z2 = z*z z3 = 1.0d0 - z2 dz = z3*(z+c*power(DABS(z3),beta))/(z3+2.0d0*beta*z2) z = z - dz IF (DABS(dz/z) .LT. 1.0d-12) GO TO 498 500 CONTINUE 601 IF (DABS(theta) .GT. 1.0001d0) theta = theta/DABS(theta) RETURN 498 theta = z/bee r = Tee/(1.0d0-z*z) r = DABS(r) RETURN 495 theta = DSIGN(1.0d0,rho)/bee r = power(rho/(em*theta),1.0d0/beta) RETURN 496 theta = DSIGN(1.0d0,rho) r = Tee/(1.0d0-besq) r = DABS(r) RETURN 600 IF (DABS(Tee) .LT. 1.0d-12) GO TO 601 IF (Tee .LT. 0.0d0) GO TO 496 theta = 1.0d-12 r = Tee RETURN END ********************************************************************* *** ss - Computes terms of the summation that defines dPotl/dT * and the 1st derivative of the theta (s) square polynomial. SUBROUTINE ss(r,th,s,sd) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION s(2), sd(2), sx(2) COMMON /coefs/ a(20), q(20), x(11) *************************************************************** COMMON /abc1/ dPdM *************************************************************** SAVE EQUIVALENCE (alpha,q(10)), (beta,a(6)), (besq,a(9)), 1 (delta,a(11)), (deli,q(14)), (alhi,q(15)), 2 (beti, q(16)), (gami,q(17)), (p00, q(11)), 3 (p01, q(18)), (s00, a(17)), (s20, a(18)), 4 (s01, a(19)), (s21, a(20)) tt = th*th sx(1) = s00 + s20*tt sd(1) = 2.0d0*s20*th sx(2) = s01 + s21*tt sd(2) = 2.0d0*s21*th s(1) = sx(1)*a(10)*a(7)*power(r,1.0d0-alpha) s(2) = sx(2)*a(10)*a(12)*power(r,1.0d0-alhi) dPdM = power(r,beta)*a(7)*th + a(1)*power(r,1.0d0-alpha)* 1 a(10)*a(7)*sx(1) + 2 power(r,beti)*a(12)*th + a(1)*power(r,1.0d0-alhi)* 3 a(10)*a(12)*sx(2) RETURN END ***************************************************************** *** thmLVS - Calculates thermodynamic and transport properties * of critical region H2O using the Levelt Sengers, et al * (1983) equation of state. SUBROUTINE thmLVS(isat,T,r1,th1) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION s(2), xk(2), sd(2) COMMON /coefs/ a(20), q(20), x(11) COMMON /crits/ Tc, rhoc, Pc, Pcon, Ucon, Scon, dPcon COMMON /therm/ AE, GE, U, H, Entrop, Cp, Cv, betaw, alphw, 1 heat, Speed COMMON /satur/ Dliq, Dvap, DH2O, iphase COMMON /deriv/ amu, s, Pw, Tw, dTw, dM0dT, dP0dT, 1 d2PdM2, d2PdMT, d2PdT2, p0th, p1th, xk COMMON /deri2/ dPdD, dPdT ************************************************************* COMMON /abc1/ dPdM COMMON /abc3/ dPdTcd ************************************************************* SAVE EQUIVALENCE (pw2, a(4)), (pw3, a(2)), (besq, a(9)), 1 (amc, a(13)), (am1, a(14)), (am2, a(15)), 2 (aa, a(10)), (xk0, a(7)), (am3, a(16)), 3 (xk1, a(12)), (pw11,q(9)), (alpha, q(10)), 4 (alhi,q(15)), (pw1, a(5)) d2P0dT = 2.0d0*pw2 + 6.0d0*pw3*dTw d2M0dT = 2.0d0*am2 + 6.0d0*am3*dTw dP0dT = pw1+dTw*(2.0d0*pw2+3.0d0*pw3*dTw) dM0dT = am1+dTw*(2.0d0*am2+3.0d0*am3*dTw) IF (isat .EQ. 0) THEN rho = DH2O / rhoc Uw = dP0dT-rho*dM0dT+pw11*amu+s(1)+s(2) ELSE rho = th1 * (xk0*power(r1,a(6)) + xk1*power(r1,q(16))) 1 + a(1)*(s(1)+s(2)) rho = 1.0d0+pw11*dTw+rho Uw = dP0dT-rho*dM0dT+pw11*amu+s(1)+s(2) DH2O = rho * rhoc dPdT2 = Pw - Tw*(Uw+rho*dM0dT) heat = 1.0d3*T*(Pcon*dPdT2)*(1.0d0/Dvap-1.0d0/Dliq) CALL ss(r1,th1,s,sd) CALL aux(r1,th1,d2PdT2,d2PdMT,d2PdM2,aa,xk,sd,Cvcoex) IF (r1 .NE. 0.0d0) THEN dPdD = dPcon * DH2O * T / d2PdM2 END IF END IF IF (r1 .NE. 0.0d0) THEN dPdTcd = dP0dT+pw11*(amu-rho/d2PdM2)+s(1)+s(2) - 1 d2PdMT*rho/d2PdM2 dPwdTw = Pw - Tw*dPdTcd dPdTal = Pcon * dPwdTw CviTw2 = d2P0dT - rho*d2M0dT + d2PdT2 - 1 (pw11+d2PdMT)*(pw11+d2PdMT)/d2PdM2 Cvw = CviTw2 * Tw*Tw Cpw = Cvw + d2PdM2*dPwdTw*dPwdTw / (rho*rho) betaw = 1.0d0 / (DH2O*dPdD) alphw = betaw * dPdTal Speed = 1.0d3 * DSQRT(Cpw/Cvw*dPdD) ELSE Cvw = 1.0d0 Cpw = 1.0d0 betaw = 1.0d0 alphw = 1.0d0 Speed = 0.0d0 END IF Hw = Pw - Tw*Uw Sw = Hw - rho*(amu+amc+dTw*(am1+dTw*(am2+dTw*am3))) Scond = Scon/DH2O U = Uw * Ucon/DH2O H = Hw * Scond * T entrop = Sw * Scond AE = U - T * entrop GE = H - T * entrop Cv = Cvw * Scond Cp = Cpw * Scond RETURN END ******************************************************** *** dalLVS - Computes/returns (d(alpha)/dt)p(D,T,alpha) * for the Levelt Sengers et al. (1983) * equation of state. Note that D (kg/m**3), * T (degK), P (MPa), alpha (degK**-1). DOUBLE PRECISION FUNCTION dalLVS(D,T,P,alpha) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION sss(2), xk(2), s(2), dsdT(2), sp(2), dspdT(2), 1 k(2), calpha(2), cbeta(2), cgamma(2), 2 u(2), v(2), w(2), dudT(2), dvdT(2), dwdT(2) COMMON /coefs/ aa(20), qq(20), xx(11) COMMON /crits/ Tc, Dc, Pc, Pcon, Ucon, Scon, dPcon COMMON /deriv/ amu, sss, Pw, Tw, dTw, dM0dT, dP0dT, 1 d2PdM2, d2PdMT, d2PdT2, p0th, p1th, xk COMMON /deri2/ dPdD, dPdT ************************************************************* COMMON /abc1/ dPdM COMMON /abc2/ r,th COMMON /abc3/ dPdTcd ************************************************************* SAVE EQUIVALENCE (a, aa(10)), (c, aa(1)), (delta, aa(11)), 1 (bsq, aa(9)), (P11, qq(9)), (Delta1, qq(14)), 2 (P1, aa(5)), (P2, aa(4)), (P3, aa(2)), 3 (s00, aa(17)), (s01, aa(19)), (s20, aa(18)), 4 (s21, aa(20)) IF (r .EQ. 0.0d0) THEN dalLVS = 1.0d6 RETURN END IF k(1) = aa(7) k(2) = aa(12) calpha(1) = qq(10) calpha(2) = qq(15) cbeta(1) = aa(6) cbeta(2) = qq(16) cgamma(1) = cbeta(1)*(delta - 1.0d0) cgamma(2) = cgamma(1) - Delta1 delT = (T - Tc) / T s(1) = s00 + s20*th**2 s(2) = s01 + s21*th**2 sp(1) = 2.0d0*s20*th sp(2) = 2.0d0*s21*th ********************************************************************* *** *** Compute drdT and d0dT from solution of the linear system *** *** ax = b *** *** d(dPdM)/dT = -D/Dc*alpha - P11*Tc/T**2 = ar1*drdT + a01*d0dT = b1 *** d(delT)/dT = Tc/T**2 = ar2*drdT + a02*d0dT = b2 *** b1 = -D/Dc*alpha - P11*Tc/T/T b2 = Tc/T**2 ar1 = 0.0d0 a01 = 0.0d0 DO 10 i = 1,2 ar1 = ar1 + k(i) * (cbeta(i)*th*power(r,cbeta(i)-1.0d0) + 1 a*c*(1.0d0 - calpha(i))*power(r,-calpha(i))*s(i)) a01 = a01 + k(i) * (power(r,cbeta(i)) + a*c*sp(i)* 1 power(r,1.0d0-calpha(i))) 10 CONTINUE ar2 = 1.0d0 - bsq*th**2 - a*c*cbeta(1)*delta* 1 (1.0d0 - th**2)*th*power(r,(cbeta(1)*delta - 1.0d0)) a02 = 3.0d0*a*c*th**2*power(r,cbeta(1)*delta) - 1 2.0d0*bsq*r*th - a*c*power(r,cbeta(1)*delta) ********************************************************************* *** solve the linear system with simplistic GE w/ partial pivoting ********************************************************************* IF (DABS(ar1) .GT. DABS(ar2)) THEN amult = -ar2 / ar1 d0dT = (b2 + amult*b1) / (a02 + amult*a01) drdT = (b1 - a01*d0dT) / ar1 ELSE amult = -ar1 / ar2 d0dT = (b1 + amult*b2) / (a01 + amult*a02) drdT = (b2 - a02*d0dT) / ar2 END IF ********************************************************************* *** *** Compute theta polynomials and their tempertaure derivatives *** dsdT(1) = 2.0d0*s20*th*d0dT dsdT(2) = 2.0d0*s21*th*d0dT dspdT(1) = 2.0d0*s20*d0dT dspdT(2) = 2.0d0*s21*d0dT q = 1.0d0 + (bsq*(2.0d0*cbeta(1)*delta - 1.0d0) - 3.0d0)* 1 th**2 - bsq*(2.0d0*cbeta(1)*delta - 3.0d0)*th**4 dqdT = 2.0d0*(bsq*(2.0d0*cbeta(1)*delta - 1.0d0) - 3.0d0)* 1 th*d0dT - 4.0d0*bsq*(2.0d0*cbeta(1)*delta - 3.0d0)* 2 th**3*d0dT DO 20 i = 1,2 u(i) = (1.0d0 - bsq*(1.0d0 - 2.0d0*cbeta(i))*th**2) / q dudT(i) = (-2.0d0*bsq*(1.0d0 - 2.0d0*cbeta(i))*th*d0dT - 1 u(i)*dqdT) / q v(i) = ((cbeta(i) - cbeta(1)*delta)*th + 1 (cbeta(1)*delta - 3.0d0*cbeta(i))*th**3) / q dvdT(i) = ((cbeta(i) - cbeta(1)*delta)*d0dT + 1 3.0d0*(cbeta(1)*delta - 3.0d0*cbeta(i))* 2 th**2*d0dT - v(i)*dqdT) / q w(i) = ((1.0d0 - calpha(i))*(1.0d0 - 3.0d0*th**2)* 1 s(i) - cbeta(1)*delta*(th - th**3)*sp(i)) / q dwdT(i) = ((1.0d0 - calpha(i))*((1.0d0 - 3.0d0*th**2)* 1 dsdT(i) - 6.0d0*th*s(i)*d0dT) - cbeta(1)* 2 delta*((th - th**3)*dspdT(i) + sp(i)* 3 (d0dT - 3.0d0*th**2*d0dT)) - w(i)*dqdT) / q 20 CONTINUE ********************************************************************* *** *** Compute dP0dTT, ddelMT, dPdTT, dPdMMT, dPdMTT, dPPTT *** dP0dTT = Tc/T**2 * (2.0d0*P2 + 6.0d0*P3*delT) ddelMT = a*power(r,cbeta(1)*delta)* (cbeta(1)*delta*th/r* 1 (1.0d0 - th**2)*drdT + (1.0d0 - 3.0d0*th**2)*d0dT) dPdTT = 0.0d0 dPdMMT = 0.0d0 dPdMTT = 0.0d0 DO 30 i = 1,2 dPdTT = dPdTT + a*k(i) * (power(r,1.0d0-calpha(i))* 1 dsdT(i) + s(i)*(1.0d0 - calpha(i))* 2 power(r,-calpha(i))*drdT) dPdMMT = dPdMMT + k(i) * ((power(r,-cgamma(i))*dudT(i) - 1 u(i)*cgamma(i)*power(r,-1.0d0-cgamma(i))*drdT) / 2 a + 2.0d0*c*(power(r,cbeta(i)-1.0d0)*dvdT(i) + 3 v(i)*(cbeta(i) - 1.0d0)*power(r,cbeta(i)-2.0d0)* 4 drdT) + a*c**2*(power(r,-calpha(i))*dwdT(i) - 5 calpha(i)*w(i)*power(r,-1.0d0-calpha(i))*drdT)) dPdMTT = dPdMTT + k(i) * (power(r,cbeta(i)-1.0d0)*dvdT(i) + 1 v(i)*(cbeta(i) - 1.0d0)*power(r,cbeta(i)-2.0d0)* 2 drdT + a*c*(power(r,-calpha(i))*dwdT(i) - 3 calpha(i)*power(r,-1.0d0-calpha(i))*drdT*w(i))) 30 CONTINUE dPPTT = dP0dTT + dPdTT + P11*ddelMT - D/Dc*dPdMTT/d2PdM2 + 1 (P11 + d2PdMT)*(D/Dc*alpha/d2PdM2 + 2 D/Dc*dPdMMT/d2PdM2**2) pterm = P/Pc + dPdTcd *** compute (d(alpha)/dT)P dalLVS = Tc*Dc**2/D**2/T**2 * (-2.0d0/T*d2PdM2*pterm + 1 2.0d0*alpha*d2PdM2*pterm + pterm*dPdMMT + 2 d2PdM2*dPPTT) RETURN END ********************************************************************* *** backup - Save Pfind COMMON values during saturation check. SUBROUTINE backup IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION s(2), xk(2) COMMON /satur/ Dliq, Dvap, DH2O, iphase COMMON /param/ r1, th1 COMMON /deriv/ amu, s, Pw, Tw, dTw, dM0dT, dP0dT, 1 d2PdM2, d2PdMT, d2PdT2, p0th, p1th, xk COMMON /deri2/ dPdD, dPdT COMMON /store/ sav2, sav3, sav4, sav5, sav6, sav7, sav8, 1 sav9, sav10, sav11, sav12, sav13, sav14, sav15, 2 sav16, sav17, sav18, sav19, isav1 SAVE isav1 = iphase sav2 = r1 sav3 = th1 sav4 = amu sav5 = s(1) sav6 = s(2) sav7 = Pw sav8 = Tw sav9 = dTw sav10 = dM0dT sav11 = dP0dT sav12 = d2PdM2 sav13 = d2PdMT sav14 = d2PdT2 sav15 = p0th sav16 = p1th sav17 = xk(1) sav18 = xk(2) sav19 = dPdD RETURN END ********************************************************************* *** restor - Restore Pfind COMMON values after saturation check. SUBROUTINE restor IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION s(2), xk(2) COMMON /satur/ Dliq, Dvap, DH2O, iphase COMMON /param/ r1, th1 COMMON /deriv/ amu, s, Pw, Tw, dTw, dM0dT, dP0dT, 1 d2PdM2, d2PdMT, d2PdT2, p0th, p1th, xk COMMON /deri2/ dPdD, dPdT COMMON /store/ sav2, sav3, sav4, sav5, sav6, sav7, sav8, 1 sav9, sav10, sav11, sav12, sav13, sav14, sav15, 2 sav16, sav17, sav18, sav19, isav1 SAVE iphase = isav1 r1 = sav2 th1 = sav3 amu = sav4 s(1) = sav5 s(2) = sav6 Pw = sav7 Tw = sav8 dTw = sav9 dM0dT = sav10 dP0dT = sav11 d2PdM2 = sav12 d2PdMT = sav13 d2PdT2 = sav14 p0th = sav15 p1th = sav16 xk(1) = sav17 xk(2) = sav18 dPdD = sav19 RETURN END ********************************************************************** *** load - Load thermodynamic and transport property values from * ptemp into props. SUBROUTINE load(phase,ptemp,props) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPROP = 23, NPROP2 = 46) DOUBLE PRECISION ptemp(NPROP), props(NPROP2) INTEGER phase, key(NPROP,2) SAVE DATA key 1 / 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 2 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 3 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 4 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46 / DO 10 i = 1,NPROP 10 props(key(i,phase)) = ptemp(i) RETURN END ****************************************************************** *** tpset - Dimension triple point U, S, H, A, G values (in J/g from * Table 2, Helgeson & Kirkham, 1974a) into user-specified units. SUBROUTINE tpset IMPLICIT DOUBLE PRECISION (a-h,o-z) COMMON /units/ ft, fd, fvd, fvk, fs, fp, fh, fst, fc COMMON /tpoint/ Utripl, Stripl, Htripl, Atripl, Gtripl, 1 Ttripl, Ptripl, Dltrip, Dvtrip SAVE DATA Utr, Str, Htr, Atr, Gtr 1 / -15766.0d0, 3.5144d0, -15971.0d0, -12870.0d0, -13073.0d0 / Utripl = Utr * fh Stripl = Str * fh Htripl = Htr * fh Atripl = Atr * fh Gtripl = Gtr * fh END **************************************************************************** *** triple - Convert U, S, H, A, G values computed with reference to * zero triple point properties (Haar et al., 1984; * Levelt Sengers et al., 1983) into values referenced to * triple point properties given by Helgeson and Kirkham, 1974a. SUBROUTINE triple(T,wpzero) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPROP = 23) DOUBLE PRECISION wpzero(NPROP) INTEGER A, G, S, U, H COMMON /tpoint/ Utr, Str, Htr, Atr, Gtr, 1 Ttripl, Ptripl, Dltrip, Dvtrip SAVE DATA A, G, S, U, H 1 / 1, 2, 3, 4, 5 / wpzero(S) = wpzero(S) + Str TS = T*wpzero(S) - Ttripl*Str wpzero(G) = wpzero(H) - TS + Gtr wpzero(A) = wpzero(U) - TS + Atr wpzero(H) = wpzero(H) + Htr wpzero(U) = wpzero(U) + Utr END ********************************************************************* *** power - Returns base**exp utilizing the intrinsic FORTRAN * exponentiation function in such a manner so as to * insure computation of machine-independent values * for all defined exponentiations. Attempted undefined * exponentiations produce an error message and cause * program termination. DOUBLE PRECISION FUNCTION power(base,exp) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPLOTF = 8) INTEGER rterm, wterm, reacf, pronf, tabf, plotf(NPLOTF), outflg COMMON /io/ rterm, wterm, iconf, reacf, pronf, tabf, plotf, 1 outflg SAVE DATA TOL / 1.0d-7 / IF (base .GT. 0.0d0) THEN power = base**exp ELSE IF (DABS(base) .GT. TOL) THEN IF (DBLE(INT(exp)) .NE. exp) THEN WRITE(wterm,10) base, exp 10 FORMAT(/,' neg base ** real exp is complex', 1 /,' base,exp: ',2e20.13,/) STOP ELSE IF (MOD(exp,2.0d0) .EQ. 0.0d0) THEN power = (-base)**exp ELSE power = -((-base)**exp) END IF END IF ELSE IF (exp .GT. 0.0d0) THEN power = 0.0d0 ELSE WRITE(wterm,20) base, exp 20 FORMAT(/,' zero base ** (exp <= 0) is undefined', 1 /,' base,exp: ',2e20.13) STOP END IF END IF END IF RETURN END *********************************************************************** *** TdegK - Returns input temperature t converted from * user-specified units to degK. DOUBLE PRECISION FUNCTION TdegK(it,t) IMPLICIT DOUBLE PRECISION (a-h,o-z) SAVE GO TO (1,2,3,4), it 1 TdegK = t RETURN 2 TdegK = t + 273.15d0 RETURN 3 TdegK = t / 1.8d0 RETURN 4 TdegK = (t + 459.67d0) / 1.8d0 RETURN END *********************************************************************** *** TdegUS - Returns input temperature t converted * from degK to user-specified units. DOUBLE PRECISION FUNCTION TdegUS(it,t) IMPLICIT DOUBLE PRECISION (a-h,o-z) SAVE GO TO (1,2,3,4), it 1 TdegUS = t RETURN 2 TdegUS = t - 273.15d0 RETURN 3 TdegUS = t * 1.8d0 RETURN 4 TdegUS = t * 1.8d0 - 459.67d0 RETURN END ********************************************************************* *** dim[HGK,LVS] - Dimensioning routines for H2O88. ********************************************************************* *** dimHGK - Dimensions thermodynamic and transport property values * computed from the HGK equation of state per user-specified * choice of units. SUBROUTINE dimHGK(isat,itripl,t,p,d,epseqn) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPROP = 23) DOUBLE PRECISION wprops(NPROP), wpliq(NPROP) INTEGER aw, gw, sw, uw, hw, cvw, cpw, vsw, alw, bew, 1 diw, viw, tcw, stw, tdw, Prw, vikw, albew, 2 ZBw, YBw, QBw, dalwdT, XBw INTEGER epseqn COMMON /units/ ft, fd, fvd, fvk, fs, fp, fh, fst, fc COMMON /fcts/ ad, gd, sd, ud, hd, cvd, cpd, dpdt, dvdt, dpdd, 1 cjtt, cjth COMMON /aconst/ wm, gascon, tz, aa, z, dz, y, uref, sref COMMON /RTcurr/ rt COMMON /wpvals/ wprops, wpliq SAVE DATA aw, gw, sw, uw, hw, cvw, cpw, vsw, alw, bew, diw, viw, 1 tcw, stw, tdw, Prw, vikw, albew, ZBw, YBw, QBw, 2 dalwdT, XBw 3 / 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 4 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 / wprops(aw) = ad * rt * fh wprops(gw) = gd * rt * fh wprops(sw) = sd * gascon * fh * ft wprops(uw) = ud * rt * fh wprops(hw) = hd * rt * fh wprops(cvw) = cvd * gascon * fh * ft wprops(cpw) = cpd * gascon * fh * ft wprops(vsw) = DSQRT(DABS(cpd*dpdd*1.0d3/cvd)) * fs wprops(bew) = 1.0d0 / (d * dpdd * fp) wprops(alw) = d * dvdt wprops(dalwdT) = dalHGK(d,t,wprops(alw)) pbars = p*1.0d1 dkgm3 = d * 1.0d3 betaPa = wprops(bew)*fp / 1.0d6 betab = wprops(bew)*fp / 1.0d1 CpJKkg = wprops(cpw)/fh/ft * 1.0d3 wprops(viw) = viscos(t,pbars,dkgm3,betaPa) * fvd wprops(tcw) = thcond(t,pbars,dkgm3,wprops(alw),betaPa) * fc * ft IF ((isat .EQ. 0) .OR. (isat .EQ. 2)) THEN wprops(stw) = 0.0d0 ELSE wprops(stw) = surten(t) * fst END IF CALL Born92(t,pbars,dkgm3/1.0d3,betab,wprops(alw),wprops(dalwdT), 1 wprops(diw),wprops(ZBw),wprops(QBw),wprops(YBw), 2 wprops(XBw),epseqn) wprops(tdw) = wprops(tcw)/fc/ft / (dkgm3 * CpJKkg) * fvk IF (wprops(tcw) .NE. 0.0d0) THEN wprops(Prw) = wprops(viw)/fvd * CpJKkg / (wprops(tcw)/fc/ft) ELSE wprops(Prw) = 0.0d0 END IF wprops(vikw) = wprops(viw)/fvd / dkgm3 * fvk wprops(albew) = wprops(alw) / wprops(bew) IF (itripl .EQ. 1) CALL triple(t,wprops) END ***************************************************************************** *** dimLVS - Dimension critical region properties per user-specs * and load into tprops. SUBROUTINE dimLVS(isat,itripl,theta,T,Pbars,dl,dv,tprops,epseqn) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (NPROP = 23) DOUBLE PRECISION tprops(NPROP) INTEGER aw, gw, sw, uw, hw, cvw, cpw, vsw, alw, bew, 1 diw, viw, tcw, stw, tdw, Prw, vikw, albew, 2 ZBw, YBw, QBw, dalwdT, XBw INTEGER epseqn COMMON /therm/ AE, GE, U, H, Entrop, Cp, Cv, betaw, alphw, 1 heat, Speed COMMON /satur/ Dliq, Dvap, DH2O, iphase COMMON /units/ ft, fd, fvd, fvk, fs, fp, fh, fst, fc ***************************************************************** COMMON /abc2/ r, th ***************************************************************** SAVE DATA aw, gw, sw, uw, hw, cvw, cpw, vsw, alw, bew, diw, viw, 1 tcw, stw, tdw, Prw, vikw, albew, ZBw, YBw, QBw, 2 dalwdT, XBw 3 / 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 4 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 / IF (isat .EQ. 1) THEN dv = Dvap dl = Dliq END IF tprops(aw) = AE * fh tprops(gw) = GE * fh tprops(sw) = Entrop * fh * ft tprops(uw) = U * fh tprops(hw) = H * fh tprops(cvw) = Cv * fh * ft tprops(cpw) = Cp * fh * ft tprops(vsw) = Speed * fs tprops(bew) = betaw / fp tprops(alw) = alphw ***************************************************************** th = theta tprops(dalwdT) = dalLVS(DH2O,T,Pbars/1.0d1,tprops(alw)) ***************************************************************** CpJKkg = Cp * 1.0d3 betaPa = betaw / 1.0d6 betab = betaw / 1.0d1 IF (DABS(theta) .NE. 1.0d0) THEN dkgm3 = DH2O tprops(stw) = 0.0d0 ELSE IF (theta .LT. 0.0d0) THEN dkgm3 = Dvap tprops(stw) = 0.0d0 ELSE dkgm3 = Dliq dkgm3 = Dliq tprops(stw) = surten(T) * fst END IF END IF CALL Born92(T,Pbars,dkgm3/1.0d3,betab,tprops(alw),tprops(dalwdT), 1 tprops(diw),tprops(ZBw),tprops(QBw),tprops(YBw), 2 tprops(XBw),epseqn) tprops(viw) = viscos(T,Pbars,dkgm3,betaPa) * fvd tprops(tcw) = thcond(T,Pbars,dkgm3,tprops(alw),betaPa) * fc * ft tprops(tdw) = tprops(tcw)/fc/ft / (dkgm3 * CpJKkg) * fvk tprops(Prw) = tprops(viw)/fvd * CpJKkg / (tprops(tcw)/fc/ft) tprops(vikw) = tprops(viw)/fvd / dkgm3 * fvk tprops(albew) = tprops(alw) / tprops(bew) IF (itripl .EQ. 1) CALL triple(T,tprops) END ********************************************************************** *** tran88 - Set of FORTRAN77 functions that compute transport * properties of fluid H2O. Input state parameters * should be computed from the Haar et al. (1984) * and Levelt Sengers et al. (1983) equations of state in * order to facilitate comparision with published tabular * values referenced below for each function. * ********************************************************************** *** programmer: James W. Johnson *** abandoned: 20 January 1988 ********************************************************************** *** viscos - Returns dynamic viscosity of H2O in kg/m*s (= Pa*s) * if Tk, Pbars falls within the validity region (specified * by the initial IF statement) of the Watson et al. (1980) * equation; otherwise returns zero. See equations 3.1-2 and * 4.1-5 and Tables 1, 6, and 8 from Sengers and * Kamgar-Parsi (1984). DOUBLE PRECISION FUNCTION viscos(Tk,Pbars,Dkgm3,betaPa) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (Tstar = 647.270d0) PARAMETER (Dstar = 317.763d0) PARAMETER (Pstar = 22.1150d6) PARAMETER (ustar = 1.0d-6) DOUBLE PRECISION a(4), b(6,7) SAVE DATA a / 0.0181583d0, 0.0177624d0, 0.0105287d0, -0.0036744d0 / DATA b / 0.5132047d0, 0.3205656d0, 0.0d0, 0.0d0, 1 -0.7782567d0, 0.1885447d0, 0.2151778d0, 0.7317883d0, 2 1.2410440d0, 1.4767830d0, 0.0d0, 0.0d0, 3 -0.2818107d0, -1.0707860d0, -1.2631840d0, 0.0d0, 4 0.0d0, 0.0d0, 0.1778064d0, 0.4605040d0, 5 0.2340379d0, -0.4924179d0, 0.0d0, 0.0d0, 6 -0.0417661d0, 0.0d0, 0.0d0, 0.1600435d0, 7 0.0d0, 0.0d0, 0.0d0, -0.01578386d0, 8 0.0d0, 0.0d0, 0.0d0, 0.0d0, 9 0.0d0, 0.0d0, 0.0d0, -0.003629481d0, 1 0.0d0, 0.0d0 / DATA TOL /1.0d-2/ viscos = 0.0d0 TdegC = Tk - 273.15d0 IF ((Pbars .GT. 5000.0d0+TOL) .OR. 1 ((Pbars .GT. 3500.0d0+TOL).AND.(TdegC .GT. 150.0d0+TOL)).OR. 2 ((Pbars .GT. 3000.0d0+TOL).AND.(TdegC .GT. 600.0d0+TOL)) .OR. 3 (TdegC .GT. 900.0d0+TOL)) RETURN T = Tk / Tstar D = Dkgm3 / Dstar sum = 0.0d0 DO 10 i=0,3 10 sum = sum + a(i+1)/T**i u0 = ustar * DSQRT(T) / sum sum = 0.0d0 DO 20 i=0,5 DO 20 j=0,6 20 sum = sum + b(i+1,j+1) * (1.0d0/T-1)**i * (D-1)**j u1 = DEXP(D*sum) IF ((0.997d0 .LE. T) .AND. (T .LE. 1.0082d0) .AND. 1 (0.755d0 .LE. D) .AND. (D .LE. 1.2900d0)) THEN xt = Pstar/Dstar**2 * betaPa * Dkgm3**2 IF (xt .LT. 22.0d0) THEN u2 = 1.0d0 ELSE u2 = 0.922 * power(xt,0.0263d0) END IF ELSE u2 = 1.0d0 END IF viscos = u0 * u1 * u2 RETURN END ***************************************************************** *** thcond - Returns thermal conductivity of H2O in J/m*deg*s (=W/m*deg) * if Tk, Pbars falls within the validity region (specified * by the initial IF statement) of the Sengers et al. (1984) * equation; returns zero otherwise. See equations 3.2-14 * and tables 2-5 and I.5-6 from the above reference. DOUBLE PRECISION FUNCTION thcond(Tk,Pbars,Dkgm3,alph,betaPa) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (Tstar = 647.270d0) PARAMETER (Dstar = 317.763d0) PARAMETER (Pstar = 22.1150d6) PARAMETER (ustar = 1.0d-6) PARAMETER (C = 3.7711d-8) DOUBLE PRECISION aL(4), au(4), bL(6,5), bu(5,6), L0, L1, L2 SAVE DATA aL / 0.2022230d1, 0.1411166d2, 0.5255970d1, -0.2018700d1 / DATA au / 0.0181583d0, 0.0177624d0, 0.0105287d0, -0.0036744d0 / DATA bL / 1.329304600d0, -0.404524370d0, 0.244094900d0, 1 0.018660751d0, -0.129610680d0, 0.044809953d0, 2 1.701836300d0, -2.215684500d0, 1.651105700d0, 3 -0.767360020d0, 0.372833440d0, -0.112031600d0, 4 5.224615800d0, -1.012411100d1, 4.987468700d0, 5 -0.272976940d0, -0.430833930d0, 0.133338490d0, 6 8.712767500d0, -9.500061100d0, 4.378660600d0, 7 -0.917837820d0, 0.0d0, 0.0d0, 8 -1.852599900d0, 0.934046900d0, 0.0d0, 9 0.0d0, 0.0d0, 0.0d0 / DATA bu / 0.5019380d0, 0.2356220d0, -0.2746370d0, 0.1458310d0, 1 -0.0270448d0, 0.1628880d0, 0.7893930d0, -0.7435390d0, 2 0.2631290d0, -0.0253093d0, -0.1303560d0, 0.6736650d0, 3 -0.9594560d0, 0.3472470d0, -0.0267758d0, 0.9079190d0, 4 1.2075520d0, -0.6873430d0, 0.2134860d0, -0.0822904d0, 5 -0.5511190d0, 0.0670665d0, -0.4970890d0, 0.1007540d0, 6 0.0602253d0, 0.1465430d0, -0.0843370d0, 0.1952860d0, 7 -0.0329320d0, -0.0202595d0 / DATA TOL /1.0d-2/ thcond = 0.0d0 TdegC = Tk - 273.15d0 IF ((Pbars .GT. 4000.0d0+TOL) .OR. 1 ((Pbars .GT. 2000.0d0+TOL).AND.(TdegC .GT. 125.0d0+TOL)).OR. 2 ((Pbars .GT. 1500.0d0+TOL).AND.(TdegC .GT. 400.0d0+TOL)).OR. 3 (TdegC .GT. 800.0d0+TOL)) RETURN T = Tk / Tstar D = Dkgm3 / Dstar sum = 0.0d0 DO 10 i=0,3 10 sum = sum + aL(i+1)/T**i L0 = DSQRT(T) / sum sum = 0.0d0 DO 20 i=0,4 DO 20 j=0,5 20 sum = sum + bL(j+1,i+1) * (1.0d0/T-1)**i * (D-1)**j L1 = DEXP(D*sum) sum = 0.0d0 DO 40 i=0,3 40 sum = sum + au(i+1)/T**i u0 = ustar * DSQRT(T) / sum sum = 0.0d0 DO 50 i=0,5 DO 50 j=0,4 50 sum = sum + bu(j+1,i+1) * (1.0d0/T-1)**i * (D-1)**j u1 = DEXP(D*sum) xt = Pstar/Dstar**2 * betaPa * Dkgm3**2 dPdT = Tstar/Pstar * alph/betaPa L2 = C / (u0*u1) * (T/D)**2 * dPdT**2 * power(xt,0.4678d0) * 1 DSQRT(D) * DEXP(-18.66d0*(T-1)**2 - (D-1)**4) thcond = L0 * L1 + L2 RETURN END ****************************************************************** *** surten - Returns the surface tension of vapor-saturated liquid * H2O in MPa*cm (converted from N/m) as computed from * the Vargaftik et al. (1983) equation. See equations * 10.1-2, Kestin et al. (1984); compare also equation * C.5 and table 11, Haar et al. (1984). DOUBLE PRECISION FUNCTION surten(Tsatur) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (Ttripl = 273.16d0) PARAMETER (Tcrit = 647.067d0) PARAMETER (Tstar = 647.27d0) PARAMETER (Tcstar = 0.999686d0) PARAMETER (v = 1.256d0) PARAMETER (B = -0.625d0) PARAMETER (stref = 0.2358d0) PARAMETER (FPTOL = 1.0d-10) SAVE IF ((Tsatur .LT. Ttripl) .OR. (Tsatur .GT. Tcrit)) THEN surten = 0.0d0 RETURN END IF IF (Tsatur .GE. Tcrit-FPTOL) THEN Tnorm = 0.0d0 ELSE Tnorm = (Tcstar - Tsatur/Tstar) / Tcstar END IF surten = stref * power(Tnorm,v) * (1.0d0 + B*Tnorm) RETURN END ****************************************************************** *** Born92 - Computes the Z, Q, Y, and X Born functions at TK, Pbars. *** *** epseqn = 1 ...... use Helgeson-Kirkham (1974) equation *** epseqn = 2 ...... use Pitzer (1983) equation *** epseqn = 3 ...... use Uematsu-Franck (1980) equation *** epseqn = 4 ...... use Johnson-Norton (1991) equation *** epseqn = 5 ...... use Archer-Wang (1990) equation *** SUBROUTINE Born92(TK,Pbars,Dgcm3,betab,alphaK,daldT, 1 eps,Z,Q,Y,X,epseqn) IMPLICIT DOUBLE PRECISION (a-h,o-z) PARAMETER (TMAX = 1000.0d0, PMAX = 5000.0d0, TOL = 1.0d-3) INTEGER epseqn SAVE eps = 0.0d0 Z = 0.0d0 Y = 0.0d0 Q = 0.0d0 X = 0.0d0 TdegC = TK - 273.15d0 *** The following line can be commented out to facilitate probably *** unreliable, yet potentially useful, predictive calculations *** at state conditions beyond the validity limits of the aqueous *** species equation of state. IF ((TdegC .GT. TMAX+TOL) .OR. (Pbars .GT. PMAX+TOL)) RETURN * IF (epseqn .EQ. 1) THEN * CALL HK74(TK,Dgcm3,betab,alphaK,daldT, * 1 eps,dedP,dedT,d2edT2) * CALL epsBrn(eps,dedP,dedT,d2edT2,Z,Q,Y,X) * RETURN * END IF * IF (epseqn .EQ. 2) THEN * CALL Pitz83(TK,Dgcm3,betab,alphaK,daldT, * 1 eps,dedP,dedT,d2edT2) * CALL epsBrn(eps,dedP,dedT,d2edT2,Z,Q,Y,X) * RETURN * END IF * IF (epseqn .EQ. 3) THEN * CALL UF80(TK,Dgcm3,betab,alphaK,daldT, * 1 eps,dedP,dedT,d2edT2) * CALL epsBrn(eps,dedP,dedT,d2edT2,Z,Q,Y,X) * RETURN * END IF IF (epseqn .EQ. 4) THEN CALL JN91(TK,Dgcm3,betab,alphaK,daldT, 1 eps,dedP,dedT,d2edT2) CALL epsBrn(eps,dedP,dedT,d2edT2,Z,Q,Y,X) RETURN END IF * IF (epseqn .EQ. 5) THEN * Dkgm3 = Dgcm3 * 1.0d3 * PMPa = Pbars / 1.0d1 * betam = betab * 1.0d1 * CALL AW90(TK,PMPa,Dkgm3,betam,alphaK,daldT, * 1 eps,dedP,dedT,d2edT2) **** convert dedP FROM MPa**-1 TO bars**-1 * dedP = dedP / 1.0d1 * CALL epsBrn(eps,dedP,dedT,d2edT2,Z,Q,Y,X) * RETURN * END IF END ********************************************************************* *** JN91 - Compute (eps, dedP, dedT, d2edT2)(T,D) using equations *** given by Johnson and Norton (1991); fit parameters *** regressed from least squares fit to dielectric data *** consistent with the HK74 equation and low temperatures, *** and with the Pitz83 equation at high temperatures. *** *** Units: T ............... K *** D ............... g/cm**3 *** beta, dedP ...... bar**(-1) *** alpha, dedT ..... K**(-1) *** daldT, d2edT2 ... K**(-2) SUBROUTINE JN91(T,D,beta,alpha,daldT,eps,dedP,dedT,d2edT2) IMPLICIT DOUBLE PRECISION (a-h,o-z) DOUBLE PRECISION a(10), c(5), dcdT(5), dc2dTT(5) SAVE DATA Tref / 298.15d0 / DATA a / 1 0.1470333593E+02, 2 0.2128462733E+03, 3 -0.1154445173E+03, 4 0.1955210915E+02, 5 -0.8330347980E+02, 6 0.3213240048E+02, 7 -0.6694098645E+01, 8 -0.3786202045E+02, 9 0.6887359646E+02, 1 -0.2729401652E+02 / Tn = T / Tref c(1) = 1.0d0 dcdT(1) = 0.0d0 dc2dTT(1) = 0.0d0 c(2) = a(1)/Tn dcdT(2) = -a(1)*Tref/T**2 dc2dTT(2) = 2.0d0*a(1)*Tref/T**3 c(3) = a(2)/Tn + a(3) + a(4)*Tn dcdT(3) = -a(2)*Tref/T**2 + a(4)/Tref dc2dTT(3) = 2.0d0*a(2)*Tref/T**3 c(4) = a(5)/Tn + a(6)*Tn + a(7)*Tn**2 dcdT(4) = -a(5)*Tref/T**2 + a(6)/Tref 1 + 2.0d0*a(7)*T/Tref**2 dc2dTT(4) = 2.0d0*a(5)*Tref/T**3 + 2.0d0*a(7)/Tref**2 c(5) = a(8)/Tn**2 + a(9)/Tn + a(10) dcdT(5) = -2.0d0*a(8)*Tref**2/T**3 - a(9)*Tref/T**2 dc2dTT(5) = 6.0d0*a(8)*Tref**2/T**4 + 2.0d0*a(9)*Tref/T**3 eps = 0.0d0 DO 50 k=1,5 50 eps = eps + c(k)*D**(k-1) dedP = 0.0d0 DO 100 j = 0,4 100 dedP = dedP + j*c(j+1)*D**j dedP = beta * dedP dedT = 0.0d0 DO 200 j = 0,4 200 dedT = dedT + D**j*(dcdT(j+1) - j*alpha*c(j+1)) d2edT2 = 0.0d0 DO 300 j = 0,4 300 d2edT2 = d2edT2 + D**j*(dc2dTT(j+1) - j*(alpha*dcdT(j+1) + 1 c(j+1)*daldT) - j*alpha*(dcdT(j+1) - j*alpha*c(j+1))) END *************************************************************** *** epsBrn - Compute the Z, Q, Y, and X Born functions from their *** eps, dedP, dedT, and d2edT2 counterparts. SUBROUTINE epsBrn(eps,dedP,dedT,d2edT2,Z,Q,Y,X) IMPLICIT DOUBLE PRECISION (a-h,o-z) SAVE Z = -1.0d0/eps Q = 1.0d0/eps**2 * dedP Y = 1.0d0/eps**2 * dedT X = 1.0d0/eps**2 * d2edT2 - 2.0d0*eps*Y**2 END