|
|
1.1 ! root 1: program spice ! 2: implicit double precision (a-h,o-z) ! 3: c ! 4: c ! 5: c ! 6: c *** version VAX UNIX 2X.x (19aug79) ! 7: c developed from ! 8: c *** version 2d.2 (26sep76) *** ! 9: c *** version hp 2.0 (6dec77) *** ! 10: c ! 11: c by dick dowell - hewlett packard company ! 12: c richard newton - uc berkeley ! 13: c ! 14: c spice is an electronic circuit simulation program that was deve- ! 15: c loped by the integrated circuits group of the electronics research ! 16: c laboratory and the department of electrical engineering and computer ! 17: c sciences at the university of california, berkeley, california. the ! 18: c program spice is available free of charge to any interested party. ! 19: c the sale, resale, or use of this program for profit without the ! 20: c express written consent of the department of electrical engineering ! 21: c and computer sciences, university of california, berkeley, california, ! 22: c is forbidden. ! 23: c ! 24: c ! 25: c implementation notes: ! 26: c ! 27: c subroutines mclock and mdate return the time (as hh:mm:ss) and ! 28: c the date (as dd mmm yy), respectively. subroutine getcje returns in ! 29: c common block /cje/ various attributes of the current job environment. ! 30: c spice expects getcje to set /cje/ variables maxtim, itime, and icost. ! 31: c maxtim is the maximum cpu time in seconds, itime is the elapsed cpu ! 32: c time in seconds, and icost is the job cost in cents. ! 33: c subroutine memory is used to change the number of memory words ! 34: c allocated to spice. if the amount of memory allocated to a jobstep ! 35: c is fixed, subroutine memory need not be changed. ! 36: c ifamwa (set in a data statement below) should be set to the ! 37: c address of the first available word of memory (following overlays, if ! 38: c any). the proper value should be easily obtainable from any load map. ! 39: c with the exception of most flags, all data in spice is stored in ! 40: c the form of managed tables allocated in the /blank/ array value(). ! 41: c spice is particularly well-suited to being run using a one-level ! 42: c overlay structure beginning with routines spice (the overlay root), ! 43: c readin, errchk, setup, dctran, dcop, acan, and ovtpvt. the order of ! 44: c the routines in this listing corresponds to that structure. note ! 45: c that if cdc-style overlay is to be used, an overlay directive card ! 46: c must be inserted before the first line of each of the just-named ! 47: c routines. ! 48: c ! 49: c ! 50: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem, ! 51: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize, ! 52: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr, ! 53: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1, ! 54: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd, ! 55: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval ! 56: common /miscel/ atime,aprog(3),adate,atitle(10),defl,defw,defad, ! 57: 1 defas,rstats(50),iwidth,lwidth,nopage ! 58: common /line/ achar,afield(15),oldlin(15),kntrc,kntlim ! 59: common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop, ! 60: 1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs ! 61: common /mosarg/ gamma,beta,vto,phi,cox,vbi,xnfs,xnsub,xd,xj,xl, ! 62: 1 xlamda,utra,uexp,vbp,von,vdsat,theta,vcrit,vtra,gleff,cdrain ! 63: common /status/ omega,time,delta,delold(7),ag(7),vt,xni,egfet, ! 64: 1 xmu,mode,modedc,icalc,initf,method,iord,maxord,noncon,iterno, ! 65: 2 itemno,nosolv,ipostp,iscrch ! 66: common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts, ! 67: 1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof ! 68: common /knstnt/ twopi,xlog2,xlog10,root2,rad,boltz,charge,ctok, ! 69: 1 gmin,reltol,abstol,vntol,trtol,chgtol,eps0,epssil,epsox ! 70: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 71: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 72: 2 nwd8,nwd16 ! 73: common /dc/ tcstar(2),tcstop(2),tcincr(2),icvflg,itcelm(2),kssop, ! 74: 1 kinel,kidin,kovar,kidout ! 75: common /ac/ fstart,fstop,fincr,skw2,refprl,spw2,jacflg,idfreq, ! 76: 1 inoise,nosprt,nosout,nosin,idist,idprt ! 77: common /tran/ tstep,tstop,tstart,delmax,tdmax,forfre,jtrflg ! 78: common /outinf/ xincr,string(15),xstart,yvar(8),itab(8),itype(8), ! 79: 1 ilogy(8),npoint,numout,kntr,numdgt ! 80: common /cje/ maxtim,itime,icost ! 81: c.. common for putwds ! 82: common /blank/ value(50000) ! 83: integer nodplc(64) ! 84: complex*16 cvalue(32) ! 85: equivalence (value(1),nodplc(1),cvalue(1)) ! 86: integer*2 istats(200) ! 87: real*4 r4stat(100) ! 88: equivalence (rstats(1),istats(1),r4stat(1)) ! 89: integer*2 inknt ! 90: c ! 91: dimension acctit(4) ! 92: dimension remain(4) ! 93: data amrje /4hmrje/ ! 94: data ablnk /1h / ! 95: data acctit / 8hjob stat, 8histics s, 8hummary , 8h / ! 96: data ahdr1, ahdr2, ahdr3 / 8h spice 2,8h.Xx (vax,8h11/780) / ! 97: c ! 98: c ! 99: ipostp=0 ! 100: maxtim=1e8 ! 101: maxlin=50000 ! 102: icost=0 ! 103: ilines=0 ! 104: c ! 105: c initialization ! 106: c ! 107: aprog(1)=ahdr1 ! 108: aprog(2)=ahdr2 ! 109: aprog(3)=ahdr3 ! 110: achar=ablnk ! 111: keof=0 ! 112: call mclock(atime) ! 113: call mdate(adate) ! 114: boltz=1.3806226d-23 ! 115: charge=1.6021918d-19 ! 116: ctok=273.15d0 ! 117: eps0=8.854214871d-14 ! 118: epssil=11.7d0*eps0 ! 119: epsox=3.9d0*eps0 ! 120: twopi=8.0d0*datan2(1.0d0,1.0d0) ! 121: rad=360.0d0/twopi ! 122: xlog2=dlog(2.0d0) ! 123: xlog10=dlog(10.0d0) ! 124: root2=dsqrt(2.0d0) ! 125: nodata=1 ! 126: c ! 127: c begin job ! 128: c ! 129: 10 if (keof.eq.1) go to 1000 ! 130: call getcje ! 131: call second(time1) ! 132: icost1=icost ! 133: igoof=0 ! 134: mode=0 ! 135: nogo=0 ! 136: maxmem=100000 ! 137: call setmem(nodplc(1),maxmem) ! 138: if (nogo.ne.0) go to 1000 ! 139: call zero8(rstats,50) ! 140: c ! 141: c read remainder of data deck and check for input errors ! 142: c ! 143: call readin ! 144: if (nogo.ne.0) go to 300 ! 145: if (keof.eq.1) go to 1000 ! 146: nodata=0 ! 147: call errchk ! 148: if (nogo.ne.0) go to 300 ! 149: call setup ! 150: if (nogo.ne.0) go to 300 ! 151: c ! 152: c cycle through temperatures ! 153: c ! 154: itemno=1 ! 155: if (numtem.eq.1) go to 110 ! 156: 100 if (itemno.eq.numtem) go to 320 ! 157: itemno=itemno+1 ! 158: call tmpupd ! 159: c ! 160: c dc transfer curves ! 161: c ! 162: 110 if (icvflg.eq.0) go to 150 ! 163: c... see routine *dctran* for explanation of *mode*, etc. ! 164: mode=1 ! 165: modedc=3 ! 166: call dctran ! 167: call ovtpvt ! 168: if (nogo.ne.0) go to 300 ! 169: c ! 170: c small signal operating point ! 171: c ! 172: 150 if (kssop.gt.0) go to 170 ! 173: if (jacflg.ne.0) go to 170 ! 174: if ((icvflg+jtrflg).gt.0) go to 250 ! 175: 170 mode=1 ! 176: modedc=1 ! 177: call dctran ! 178: if (nogo.ne.0) go to 300 ! 179: call dcop ! 180: if (nogo.ne.0) go to 300 ! 181: c ! 182: c ac small signal analysis ! 183: c ! 184: 200 if (jacflg.eq.0) go to 250 ! 185: mode=3 ! 186: call acan ! 187: call ovtpvt ! 188: if (nogo.ne.0) go to 300 ! 189: c ! 190: c transient analysis ! 191: c ! 192: 250 if (jtrflg.eq.0) go to 100 ! 193: mode=1 ! 194: modedc=2 ! 195: call dctran ! 196: if (nogo.ne.0) go to 300 ! 197: call dcop ! 198: if (nogo.ne.0) go to 300 ! 199: mode=2 ! 200: call dctran ! 201: call ovtpvt ! 202: if (nogo.ne.0) go to 300 ! 203: go to 100 ! 204: c ! 205: c job concluded ! 206: c ! 207: 300 write (6,301) ! 208: 301 format(1h0,9x,'***** job aborted') ! 209: nodata=0 ! 210: c ! 211: c job accounting ! 212: c ! 213: 320 continue ! 214: numel=0 ! 215: do 360 i=1,18 ! 216: 360 numel=numel+jelcnt(i) ! 217: numtem=max0(numtem-1,1) ! 218: idist=min0(idist,1) ! 219: if (iprnta.eq.0) go to 800 ! 220: call title(-1,lwidth,1,acctit) ! 221: write (6,361) nunods,ncnods,numnod,numel,(jelcnt(i),i=11,14) ! 222: 361 format(' nunods ncnods numnod numel diodes bjts jfets mfets' ! 223: 1 //,i9,2i7,i6,i8,i6,2i7) ! 224: write (6,371) numtem,icvflg,jtrflg,jacflg,inoise,idist,nogo ! 225: 371 format(/'0 numtem icvflg jtrflg jacflg inoise idist nogo'/, ! 226: 1 2h0 ,7i7) ! 227: write (6,381) rstats(20),rstats(21),rstats(22),rstats(23), ! 228: 1 rstats(26),rstats(27) ! 229: 381 format(/'0 nstop nttbr nttar ifill iops perspa'//, ! 230: 1 1x,5f8.0,f9.3) ! 231: write (6,391) rstats(30),rstats(31),rstats(32),maxmem,maxuse, ! 232: 1 cpyknt ! 233: 391 format(/'0 numttp numrtp numnit maxmem memuse copyknt',//, ! 234: 1 2x,3f8.0,2x,i6,2x,i6,2x,f8.0) ! 235: write (6,401) (rstats(i),i=1,11) ! 236: 401 format(/, ! 237: 1 1h0,9x,'readin ',12x,f10.2/, ! 238: 2 1h0,9x,'setup ',12x,f10.2/, ! 239: 3 1h0,9x,'trcurv ',12x,f10.2,10x,f6.0/, ! 240: 4 1h0,9x,'dcan ',12x,f10.2,10x,f6.0/, ! 241: 5 1h0,9x,'acan ',12x,f10.2,10x,f6.0/, ! 242: 6 1h0,9x,'tranan ',12x,f10.2,10x,f6.0/, ! 243: 7 1h0,9x,'output ',12x,f10.2) ! 244: 800 call getcje ! 245: call second(time2) ! 246: et=time2-time1 ! 247: tcost=dfloat(icost-icost1)/100.0d0 ! 248: if (iprnta.eq.0) go to 810 ! 249: ohead=et-(rstats(1)+rstats(2)+rstats(3)+rstats(5)+rstats(7) ! 250: 1 +rstats(9)+rstats(11)) ! 251: write (6,801) ohead ! 252: 801 format(1h0,9x,'overhead',12x,f10.2) ! 253: 810 write (6,811) et ! 254: 811 format(1h0,9x,'total job time ',f10.2) ! 255: tcost=tcost*11.5d0/23.0d0 ! 256: c write(6,812) tcost ! 257: c 812 format(1h0,9x,'total job cost $',f8.2, ! 258: c 1 ' @ $11.50 per cpu minute', ! 259: c 2 /'0this lower rate applies for remainder of fiscal 79') ! 260: rstats(33)=cpyknt ! 261: rstats(34)=et ! 262: rstats(35)=tcost ! 263: rstats(36)=ohead ! 264: c.. convert dble to sgl - 72/2 is how many to convert ! 265: c call dblsgl(rstats(1),72) ! 266: istats(73)=nunods ! 267: istats(74)=ncnods ! 268: istats(75)=numnod ! 269: istats(76)=numel ! 270: istats(77)=jelcnt(11) ! 271: istats(78)=jelcnt(12) ! 272: istats(79)=jelcnt(13) ! 273: istats(80)=jelcnt(14) ! 274: istats(81)=numtem ! 275: istats(82)=icvflg ! 276: istats(83)=jtrflg ! 277: istats(84)=jacflg ! 278: istats(85)=inoise ! 279: istats(86)=idist ! 280: istats(87)=nogo ! 281: istats(88)=maxmem ! 282: istats(89)=maxuse ! 283: c do 820 i=1,36 ! 284: c 820 r4stat(i)=rlconv(r4stat(i)) ! 285: c call cadend(istats,100) ! 286: 900 if ((maxtim-itime).ge.limtim) go to 10 ! 287: write (6,901) ! 288: 901 format('1warning: further analysis stopped due to cpu time limit' ! 289: 1/) ! 290: 1000 if(nodata.ne.0) write(6,1001) ! 291: 1001 format(/1x,'input deck (file) contains no data.') ! 292: stop ! 293: end ! 294: subroutine tmpupd ! 295: implicit double precision (a-h,o-z) ! 296: c ! 297: c this routine updates the temperature-dependent parameters in the ! 298: c device models. it also updates the values of temperature-dependent ! 299: c resistors. the updated values are printed. ! 300: c ! 301: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem, ! 302: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize, ! 303: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr, ! 304: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1, ! 305: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd, ! 306: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval ! 307: common /miscel/ atime,aprog(3),adate,atitle(10),defl,defw,defad, ! 308: 1 defas,rstats(50),iwidth,lwidth,nopage ! 309: common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop, ! 310: 1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs ! 311: common /status/ omega,time,delta,delold(7),ag(7),vt,xni,egfet, ! 312: 1 xmu,mode,modedc,icalc,initf,method,iord,maxord,noncon,iterno, ! 313: 2 itemno,nosolv,ipostp,iscrch ! 314: common /knstnt/ twopi,xlog2,xlog10,root2,rad,boltz,charge,ctok, ! 315: 1 gmin,reltol,abstol,vntol,trtol,chgtol,eps0,epssil,epsox ! 316: common /blank/ value(50000) ! 317: integer nodplc(64) ! 318: complex*16 cvalue(32) ! 319: equivalence (value(1),nodplc(1),cvalue(1)) ! 320: c ! 321: c ! 322: dimension tmptit(4) ! 323: data tmptit / 8htemperat, 8hure-adju, 8hsted val, 8hues / ! 324: c ! 325: c ! 326: tempd=value(itemps+itemno)+ctok ! 327: xkt=boltz*tempd ! 328: oldvt=vt ! 329: vt=xkt/charge ! 330: ratio=tempd/(value(itemps+itemno-1)+ctok) ! 331: ratlog=dlog(ratio) ! 332: ratio1=ratio-1.0d0 ! 333: delt=value(itemps+itemno)-value(itemps+1) ! 334: deltsq=delt*delt ! 335: reftmp=27.0d0+ctok ! 336: oldeg=egfet ! 337: egfet=1.16d0-(7.02d-4*tempd*tempd)/(tempd+1108.0d0) ! 338: oldxni=xni ! 339: arg=-egfet/(xkt+xkt)+1.1151d0/(boltz*(reftmp+reftmp)) ! 340: factor=tempd/reftmp ! 341: factor=factor*dsqrt(factor) ! 342: xni=1.45d10*factor*dexp(charge*arg) ! 343: pbfact=(vt+vt)*dlog(oldxni/xni) ! 344: call title(0,lwidth,1,tmptit) ! 345: c ! 346: c resistors ! 347: c ! 348: loc=locate(1) ! 349: ititle=0 ! 350: 10 if (loc.eq.0) go to 100 ! 351: locv=nodplc(loc+1) ! 352: tc1=value(locv+3) ! 353: tc2=value(locv+4) ! 354: if (tc1.ne.0.0d0) go to 20 ! 355: if (tc2.eq.0.0d0) go to 40 ! 356: 20 if (ititle.ne.0) go to 30 ! 357: write (6,21) ! 358: 21 format(//'0**** resistors',/,'0name',8x,'value',//) ! 359: ititle=1 ! 360: 30 rnew=value(locv+2)*(1.0d0+tc1*delt+tc2*deltsq) ! 361: value(locv+1)=1.0d0/rnew ! 362: write (6,31) value(locv),rnew ! 363: 31 format(1x,a8,1p6d11.2) ! 364: 40 loc=nodplc(loc) ! 365: go to 10 ! 366: c ! 367: c diode model ! 368: c ! 369: 100 loc=locate(21) ! 370: if (loc.eq.0) go to 200 ! 371: write (6,101) ! 372: 101 format(//'0**** diode model parameters',/,'0name',9x,'is',9x,'pb', ! 373: 1//) ! 374: 110 if (loc.eq.0) go to 200 ! 375: locv=nodplc(loc+1) ! 376: c... is(t2)=is(t1)*dexp(eg/(n*vt)*(t2/t1-1))*(t2/t1)^(pt/n) ! 377: xn=value(locv+3) ! 378: factor=ratio1*value(locv+8)/(xn*vt)+value(locv+9)/xn*ratlog ! 379: factor=dexp(factor) ! 380: value(locv+1)=value(locv+1)*factor ! 381: oldpb=value(locv+6) ! 382: value(locv+6)=ratio*oldpb+pbfact ! 383: value(locv+12)=value(locv+12)*value(locv+6)/oldpb ! 384: value(locv+15)=value(locv+15)*value(locv+6)/oldpb ! 385: vte=value(locv+3)*vt ! 386: value(locv+18)=vte*dlog(vte/(root2*value(locv+1))) ! 387: write (6,31) value(locv),value(locv+1),value(locv+6) ! 388: loc=nodplc(loc) ! 389: go to 110 ! 390: c ! 391: c bipolar transistor model ! 392: c ! 393: 200 loc=locate(22) ! 394: if (loc.eq.0) go to 300 ! 395: write (6,201) ! 396: 201 format(//'0**** bjt model parameters',/,'0name',9x,'js',8x,'bf ', ! 397: 1 7x,'jle',7x,'br ',7x,'jlc',7x,'vje',7x,'vjc',//) ! 398: 210 if (loc.eq.0) go to 300 ! 399: locv=nodplc(loc+1) ! 400: c... is(t2)=is(t1)*dexp(eg/vt*(t2/t1-1))*(t2/t1)^pt ! 401: factln=ratio1*value(locv+42)/vt+value(locv+43)*ratlog ! 402: factor=dexp(factln) ! 403: value(locv+1)=value(locv+1)*factor ! 404: tb=value(locv+41) ! 405: bfactr=dexp(tb*ratlog) ! 406: value(locv+2)=value(locv+2)*bfactr ! 407: value(locv+8)=value(locv+8)*bfactr ! 408: value(locv+6)=value(locv+6)*dexp(factln/value(locv+7))/bfactr ! 409: value(locv+12)=value(locv+12)*dexp(factln/value(locv+13)) ! 410: 1 /bfactr ! 411: oldpb=value(locv+22) ! 412: value(locv+22)=ratio*oldpb+pbfact ! 413: value(locv+46)=value(locv+46)*value(locv+22)/oldpb ! 414: value(locv+47)=value(locv+47)*value(locv+22)/oldpb ! 415: oldpb=value(locv+30) ! 416: value(locv+30)=ratio*oldpb+pbfact ! 417: value(locv+50)=value(locv+50)*value(locv+30)/oldpb ! 418: value(locv+51)=value(locv+51)*value(locv+30)/oldpb ! 419: value(locv+54)=vt*dlog(vt/(root2*value(locv+1))) ! 420: write (6,211) value(locv),value(locv+1),value(locv+2), ! 421: 1 value(locv+6),value(locv+8),value(locv+12),value(locv+22), ! 422: 2 value(locv+30) ! 423: 211 format(1x,a8,1p7d10.2) ! 424: loc=nodplc(loc) ! 425: go to 210 ! 426: c ! 427: c jfet model ! 428: c ! 429: 300 loc=locate(23) ! 430: if (loc.eq.0) go to 400 ! 431: write (6,301) ! 432: 301 format(//'0**** jfet model parameters',/,'0name',9x,'is',9x,'pb', ! 433: 1//) ! 434: 310 if (loc.eq.0) go to 400 ! 435: locv=nodplc(loc+1) ! 436: value(locv+9)=value(locv+9)*dexp(ratio1*1.11d0/vt) ! 437: oldpb=value(locv+8) ! 438: value(locv+8)=ratio*oldpb+pbfact ! 439: value(locv+12)=value(locv+12)*value(locv+8)/oldpb ! 440: value(locv+13)=value(locv+13)*value(locv+8)/oldpb ! 441: value(locv+16)=vt*dlog(vt/(root2*value(locv+9))) ! 442: write (6,31) value(locv),value(locv+9),value(locv+8) ! 443: loc=nodplc(loc) ! 444: go to 310 ! 445: c ! 446: c mosfet model ! 447: c ! 448: 400 loc=locate(24) ! 449: if (loc.eq.0) go to 1000 ! 450: iprnt=1 ! 451: 410 if (loc.eq.0) go to 1000 ! 452: c.. no temperature effects have been coded for ga-as fets ! 453: if(nodplc(loc+2).eq.0) go to 430 ! 454: locv=nodplc(loc+1) ! 455: if(iprnt.ne.0) write (6,401) ! 456: 401 format(//'0**** mosfet model parameters',/,'0name',8x,'vto',8x, ! 457: 1 'phi',9x,'pb',9x,'js',7x,'kp',//) ! 458: iprnt=0 ! 459: ratio4=ratio*dsqrt(ratio) ! 460: value(locv+2)=value(locv+2)/ratio4 ! 461: value(locv+23)=value(locv+23)/ratio4 ! 462: oldphi=value(locv+4) ! 463: value(locv+4)=ratio*oldphi+pbfact ! 464: phi=value(locv+4) ! 465: type=nodplc(loc+2) ! 466: tps=value(locv+22) ! 467: vfb=value(locv+34)-type*oldphi ! 468: vstrip=vfb+0.5d0*type*oldphi ! 469: if(value(locv+21).ne.0.0d0) go to 415 ! 470: vstrip=vstrip+0.5d0*(oldeg-egfet) ! 471: go to 420 ! 472: 415 oldgat=oldvt*dlog(value(locv+21)/oldxni) ! 473: gatnew=vt*dlog(value(locv+21)/xni) ! 474: vstrip=vstrip+type*tps*(oldgat-gatnew) ! 475: 420 vfb=vstrip-0.5d0*type*phi ! 476: value(locv+34)=vfb+type*phi ! 477: value(locv+1)=value(locv+34)+type*value(locv+3)*dsqrt(phi) ! 478: value(locv+15)=value(locv+15)*dexp(-egfet/vt+oldeg/oldvt) ! 479: oldpb=value(locv+14) ! 480: value(locv+14)=ratio*oldpb+pbfact ! 481: pb=value(locv+14) ! 482: ratio2=oldpb/pb ! 483: ratio3=dsqrt(ratio2) ! 484: value(locv+11)=value(locv+11)*ratio3 ! 485: value(locv+12)=value(locv+12)*ratio3 ! 486: pbrat=1.0d0/ratio2 ! 487: value(locv+29)=value(locv+29)*pbrat ! 488: value(locv+30)=value(locv+30)*pbrat ! 489: write (6,31) value(locv),value(locv+1),value(locv+4), ! 490: 1 value(locv+14),value(locv+15),value(locv+2) ! 491: 430 loc=nodplc(loc) ! 492: go to 410 ! 493: c ! 494: c finished ! 495: c ! 496: 1000 return ! 497: end ! 498: subroutine find(aname,id,loc,iforce) ! 499: implicit double precision (a-h,o-z) ! 500: c ! 501: c this routine searches the list with number 'id' for an element ! 502: c with name 'aname'. loc is set to point to the element. if iforce is ! 503: c nonzero, then find expects to have to add the element to the list, and ! 504: c reports a fatal error if the element is found. if subcircuit defini- ! 505: c tion is in progress (nonzero value for nsbckt), then find searches the ! 506: c current subcircuit definition list rather than the nominal element ! 507: c list. ! 508: c ! 509: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem, ! 510: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize, ! 511: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr, ! 512: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1, ! 513: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd, ! 514: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval ! 515: common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop, ! 516: 1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs ! 517: common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts, ! 518: 1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof ! 519: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 520: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 521: 2 nwd8,nwd16 ! 522: common /blank/ value(50000) ! 523: integer nodplc(64) ! 524: complex*16 cvalue(32) ! 525: equivalence (value(1),nodplc(1),cvalue(1)) ! 526: c ! 527: c index to the contents of the various lists: ! 528: c ! 529: c list contents ! 530: c ---- -------- ! 531: c ! 532: c 1 resistors ! 533: c 2 nonlinear capacitors ! 534: c 3 nonlinear inductors ! 535: c 4 mutual inductors ! 536: c 5 nonlinear voltage controlled current sources ! 537: c 6 nonlinear voltage controlled voltage sources ! 538: c 7 nonlinear current controlled current sources ! 539: c 8 nonlinear current controlled voltage sources ! 540: c 9 independent voltage sources ! 541: c 10 independent current sources ! 542: c 11 diodes ! 543: c 12 bipolar junction transistors ! 544: c 13 junction field-effect transistors (jfets) ! 545: c 14 metal-oxide-semiconductor junction fets (mosfets) ! 546: c 15 s-parameter 2-port network ! 547: c 16 y-parameter 2-port network ! 548: c 17 transmission lines ! 549: c 18 <unused> ! 550: c 19 subcircuit calls ! 551: c 20 subcircuit definitions ! 552: c 21 diode model ! 553: c 22 bjt model ! 554: c 23 jfet model ! 555: c 24 mosfet model ! 556: c 25-30 <unused> ! 557: c 31 .print dc ! 558: c 32 .print tran ! 559: c 33 .print ac ! 560: c 34 .print noise ! 561: c 35 .print distortion ! 562: c 36 .plot dc ! 563: c 37 .plot tr ! 564: c 38 .plot ac ! 565: c 39 .plot noise ! 566: c 40 .plot distortion ! 567: c 41 outputs for dc ! 568: c 42 outputs for transient ! 569: c 43 outputs for ac ! 570: c 44 outputs for noise ! 571: c 45 outputs for distortion ! 572: c 46-50 <unused> ! 573: c ! 574: integer xxor ! 575: dimension lnod(50),lval(50) ! 576: data lnod / 9,13,15, 7,14,15,14,15,12, 7, ! 577: 1 17,37,26,34, 7, 7,34, 0, 5, 5, ! 578: 2 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, ! 579: 3 21,21,21,21,21,21,21,21,21,21, ! 580: 4 8, 8, 8, 8, 8, 0, 0, 0, 0, 0 / ! 581: data lval / 5, 4, 4, 2, 1, 1, 1, 1, 4, 4, ! 582: 1 3, 4, 4,13, 1, 1, 9, 0, 1, 1, ! 583: 2 19,55,17,41, 0, 0, 0, 0, 0, 0, ! 584: 3 1, 1, 1, 1, 1,17,17,17,17,17, ! 585: 4 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 / ! 586: data ndefin /2h.u/ ! 587: c ! 588: c ! 589: anam=aname ! 590: call sizmem(ielmnt,isize) ! 591: locn=ielmnt+isize+2 ! 592: if (nsbckt.eq.0) go to 10 ! 593: loct=nodplc(isbckt+nsbckt) ! 594: loc=nodplc(loct+3) ! 595: if (loc.ne.0) go to 20 ! 596: nodplc(loct+3)=locn ! 597: go to 60 ! 598: 10 loc=locate(id) ! 599: if (loc.ne.0) go to 20 ! 600: locate(id)=locn ! 601: go to 50 ! 602: c ! 603: c search list for a name match ! 604: c ! 605: 20 locv=nodplc(loc+1) ! 606: if (xxor(anam,value(locv)).ne.0) go to 30 ! 607: if (nsbckt.eq.0) go to 25 ! 608: if (nodplc(loc-1).ne.id) go to 30 ! 609: 25 if (nodplc(loc+2).eq.ndefin) go to 200 ! 610: if (iforce.eq.0) go to 200 ! 611: write (6,26) anam ! 612: 26 format('0*error*: above line attempts to redefine ',a8/) ! 613: nogo=1 ! 614: 30 if (nodplc(loc).eq.0) go to 40 ! 615: loc=nodplc(loc) ! 616: go to 20 ! 617: c ! 618: c reserve space for this element ! 619: c ! 620: 40 nodplc(loc)=locn ! 621: if (nsbckt.ne.0) go to 60 ! 622: 50 jelcnt(id)=jelcnt(id)+1 ! 623: 60 loc=locn ! 624: itemp=loc+lnod(id)*nwd4-1 ! 625: locv=nxtevn(itemp-1)+1 ! 626: itemp=locv-itemp ! 627: ktmp=lnod(id)*nwd4+lval(id)*nwd8+itemp ! 628: call extmem(ielmnt,ktmp) ! 629: locv=(locv-1)/nwd8+1 ! 630: iptr=0 ! 631: if (nsbckt.eq.0) go to 80 ! 632: iptr=id ! 633: 80 nodplc(loc-1)=iptr ! 634: nodplc(loc)=0 ! 635: nodplc(loc+1)=locv ! 636: value(locv)=anam ! 637: c ! 638: c background storage ! 639: c ! 640: 100 nodplc(loc+2)=ndefin ! 641: nword=lnod(id)-4 ! 642: if (nword.lt.1) go to 120 ! 643: call zero4(nodplc(loc+3),nword) ! 644: 120 nword=lval(id)-1 ! 645: if (nword.lt.1) go to 200 ! 646: call zero8(value(locv+1),nword) ! 647: c ! 648: c exit ! 649: c ! 650: 200 return ! 651: end ! 652: subroutine title(ifold,len,icom,coment) ! 653: implicit double precision (a-h,o-z) ! 654: c ! 655: c this routine writes a title on the output file. ifold indicates ! 656: c whether the page eject should be to the next concave, convex, or any ! 657: c page fold depending on whether its value is <0, >0, or =0. the page ! 658: c eject is suppressed (as is much of the heading) if the variable nopage ! 659: c is nonzero. ! 660: c ! 661: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem, ! 662: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize, ! 663: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr, ! 664: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1, ! 665: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd, ! 666: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval ! 667: common /miscel/ atime,aprog(3),adate,atitle(10),defl,defw,defad, ! 668: 1 defas,rstats(50),iwidth,lwidth,nopage ! 669: common /status/ omega,time,delta,delold(7),ag(7),vt,xni,egfet, ! 670: 1 xmu,mode,modedc,icalc,initf,method,iord,maxord,noncon,iterno, ! 671: 2 itemno,nosolv,ipostp,iscrch ! 672: common /blank/ value(50000) ! 673: integer nodplc(64) ! 674: complex*16 cvalue(32) ! 675: equivalence (value(1),nodplc(1),cvalue(1)) ! 676: c ! 677: c ! 678: dimension coment(4) ! 679: c ! 680: c ! 681: if(nopage.eq.1) go to 150 ! 682: c ! 683: 30 if (len.le.80) go to 100 ! 684: write (6,31) adate,aprog,atime,(atitle(i),i=1,10) ! 685: 31 format(1h1,9(2h* ),a10,1x,11(2h* ),3a8,11(2h* ),a10,9(2h *),//1h0, ! 686: 1 15a8/) ! 687: if (icom.eq.0) go to 40 ! 688: write (6,36) coment,value(itemps+itemno) ! 689: 36 format(5h0****,17x,4a8,21x,'temperature =',f9.3,' deg c'/) ! 690: 40 write (6,41) ! 691: 41 format(1h0,63(2h* )//) ! 692: go to 200 ! 693: c ! 694: c ! 695: 100 write (6,101) adate,aprog,atime,(atitle(i),i=1,10) ! 696: 101 format(1h1,5(1h*),a10,1x,8(1h*),3a8,8(1h*),a10,5(1h*)//1h0,10a8/) ! 697: if (icom.eq.0) go to 110 ! 698: write (6,106) coment,value(itemps+itemno) ! 699: 106 format(10h0**** ,4a8,' temperature =',f9.3,' deg c'/) ! 700: 110 write (6,111) ! 701: 111 format(1h0,71(1h*)//) ! 702: go to 200 ! 703: c ! 704: c ! 705: 150 if (icom.eq.0) go to 160 ! 706: write (6,106) coment,value(itemps+itemno) ! 707: go to 200 ! 708: 160 write (6,161) aprog ! 709: 161 format(1h0,3a8,/) ! 710: c ! 711: c finished ! 712: c ! 713: 200 return ! 714: end ! 715: subroutine dcdcmp ! 716: implicit double precision (a-h,o-z) ! 717: c ! 718: c this routine performs an in-place lu factorization of the coef- ! 719: c ficient matrix. ! 720: c ! 721: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem, ! 722: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize, ! 723: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr, ! 724: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1, ! 725: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd, ! 726: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval ! 727: common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop, ! 728: 1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs ! 729: common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts, ! 730: 1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof ! 731: common /knstnt/ twopi,xlog2,xlog10,root2,rad,boltz,charge,ctok, ! 732: 1 gmin,reltol,abstol,vntol,trtol,chgtol,eps0,epssil,epsox ! 733: common /blank/ value(50000) ! 734: integer nodplc(64) ! 735: complex*16 cvalue(32) ! 736: equivalence (value(1),nodplc(1),cvalue(1)) ! 737: data ikount /0/ ! 738: c ! 739: c ! 740: do 100 i=2,nstop ! 741: io=nodplc(iorder+i) ! 742: if (dabs(value(lynl+io)).ge.gmin) go to 10 ! 743: value(lynl+io)=gmin ! 744: igoof=igoof+1 ! 745: if(ikount.gt.20) go to 10 ! 746: ikount=ikount+1 ! 747: if(io.le.nunods) write(6,9) nodplc(junode+io) ! 748: 9 format(' at node ',i5) ! 749: 10 jstart=nodplc(ilc+i) ! 750: jstop=nodplc(ilc+i+1)-1 ! 751: if (jstart.gt.jstop) go to 100 ! 752: do 90 j=jstart,jstop ! 753: value(lyl+j)=value(lyl+j)/value(lynl+io) ! 754: icol=nodplc(ilr+j) ! 755: kstart=nodplc(iur+i) ! 756: kstop=nodplc(iur+i+1)-1 ! 757: if (kstart.gt.kstop) go to 90 ! 758: do 80 k=kstart,kstop ! 759: irow=nodplc(iuc+k) ! 760: if (icol-irow) 20,60,40 ! 761: c ! 762: c find (icol,irow) matrix term (upper triangle) ! 763: c ! 764: 20 l=nodplc(iur+icol+1) ! 765: 30 l=l-1 ! 766: if (nodplc(iuc+l).ne.irow) go to 30 ! 767: ispot=lyu+l ! 768: go to 70 ! 769: c ! 770: c find (icol,irow) matrix term (lower triangle) ! 771: c ! 772: 40 l=nodplc(ilc+irow+1) ! 773: 50 l=l-1 ! 774: if (nodplc(ilr+l).ne.icol) go to 50 ! 775: ispot=lyl+l ! 776: go to 70 ! 777: c ! 778: c find (icol,irow) matrix term (diagonal) ! 779: c ! 780: 60 ispot=lynl+nodplc(iorder+irow) ! 781: c ! 782: 70 value(ispot)=value(ispot)-value(lyl+j)*value(lyu+k) ! 783: 80 continue ! 784: 90 continue ! 785: 100 continue ! 786: return ! 787: end ! 788: subroutine dcsol ! 789: implicit double precision (a-h,o-z) ! 790: c ! 791: c this routine solves the system of circuit equations by performing ! 792: c a forward and backward substitution step using the previously-computed ! 793: c lu factors. ! 794: c ! 795: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem, ! 796: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize, ! 797: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr, ! 798: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1, ! 799: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd, ! 800: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval ! 801: common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop, ! 802: 1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs ! 803: common /blank/ value(50000) ! 804: integer nodplc(64) ! 805: complex*16 cvalue(32) ! 806: equivalence (value(1),nodplc(1),cvalue(1)) ! 807: c ! 808: c forward substitution ! 809: c ! 810: do 20 i=2,nstop ! 811: jstart=nodplc(ilc+i) ! 812: jstop=nodplc(ilc+i+1)-1 ! 813: if (jstart.gt.jstop) go to 20 ! 814: io=nodplc(iorder+i) ! 815: if (value(lvn+io).eq.0.0d0) go to 20 ! 816: do 10 j=jstart,jstop ! 817: jo=nodplc(ilr+j) ! 818: jo=nodplc(iorder+jo) ! 819: value(lvn+jo)=value(lvn+jo)-value(lyl+j)*value(lvn+io) ! 820: 10 continue ! 821: 20 continue ! 822: c ! 823: c back substitution ! 824: c ! 825: k=nstop+1 ! 826: do 50 i=2,nstop ! 827: k=k-1 ! 828: io=nodplc(iorder+k) ! 829: jstart=nodplc(iur+k) ! 830: jstop=nodplc(iur+k+1)-1 ! 831: if (jstart.gt.jstop) go to 40 ! 832: do 30 j=jstart,jstop ! 833: jo=nodplc(iuc+j) ! 834: jo=nodplc(iorder+jo) ! 835: value(lvn+io)=value(lvn+io)-value(lyu+j)*value(lvn+jo) ! 836: 30 continue ! 837: 40 value(lvn+io)=value(lvn+io)/value(lynl+io) ! 838: 50 continue ! 839: return ! 840: end ! 841: subroutine setmem(ipntr,ksize) ! 842: implicit double precision (a-h,o-z) ! 843: c ! 844: c this routine performs dynamic memory management. it is used in ! 845: c spice2, and useable in any program. ! 846: c ! 847: c memory is managed within an array selected by the calling program. ! 848: c one may either dimension this array to the 'maxmem' size, or more ! 849: c desirably, find the address of the first available word of memory ! 850: c above your program, and dimension your array to '1'. passing the ! 851: c address of the first data word available permits the manager to ! 852: c use 'illegal' indices into the data area. ! 853: c ! 854: c this routine must have access to an integer function called 'locf' ! 855: c which returns the address of its argument. addresses as used by this ! 856: c program refer to 'integer' addresses, not byte addresses. ! 857: c ! 858: c entry points: ! 859: c setmem - set initial memory ! 860: c getm4 - get block for table of integers ! 861: c getm8 - get block for table of floating point variables ! 862: c getm16 - get block for table of complex variables ! 863: c relmem - release part of block ! 864: c extmem - extend size of existing block ! 865: c sizmem - determine size of existing block ! 866: c clrmem - release block ! 867: c ptrmem - reset memory pointer ! 868: c crunch - force memory compaction ! 869: c avlm4 - amount of space available (integers) ! 870: c avlm8 - amount of space available (real) ! 871: c avlm16 - amount of space available (complex) ! 872: c ! 873: c calling sequences: ! 874: c call setmem(imem(1),maxmem) ! 875: c call setmem(imem(1),maxmem,kfamwa) non 3000 machines kfamwa is ! 876: c address of first available word ! 877: c of data ! 878: c call getm4 (ipntr,blksiz) where blksize is the number of entries ! 879: c call getm8 (ipntr,blksiz) ! 880: c call getm16(ipntr,blksiz) ! 881: c call relmem(ipntr,relsiz) ! 882: c call extmem(ipntr,extsiz) extsiz is the number of entries to be added ! 883: c call sizmem(ipntr,blksiz) ! 884: c call clrmem(ipntr) ! 885: c call ptrmem(ipntr1,ipntr2) ! 886: c call avlm4(ispace) ! 887: c call avlm8(ispace) ! 888: c call avlm16(ispace) ! 889: c call crunch ! 890: c ! 891: c ! 892: c general comments: ! 893: c for each block which is allocated, a 5-word entry is maintained ! 894: c in a table kept in high memory, of the form ! 895: c ! 896: c word contents ! 897: c ---- -------- ! 898: c ! 899: c 1 index of imem(.) into origin of block ! 900: c i.e. contents of pointer (used for error check) ! 901: c 2 block size (in words) ! 902: c 3 number of words in use ! 903: c 4 address of variable containing block origin ! 904: c 5 number of words used per table entry ! 905: c ! 906: c all allocated blocks are an 'even' (nxtevn) number of words in length, ! 907: c where a 'word' is the storage unit required for an 'integer' variable. ! 908: c since block repositioning may be necessary, the convention that ! 909: c only one variable contain a block origin should be observed. ! 910: c for *getmem*, *ipntr* is set such that *array(ipntr+1)* is the ! 911: c first word of the allocated block. 'ipntr' is set to address the first ! 912: c entry of the table when used with the appropriate variable type, i.e., ! 913: c nodplc(ipntr+1), value(ipntr+1), or cvalue(ipntr+1). ! 914: c for *clrmem*, *ipntr* is set to 'invalid' to enable rapid detection ! 915: c of an attempt to use a cleared block. ! 916: c if any fatal errors are found, a message is printed and a flag ! 917: c set inhibiting further action until *setmem* is called. (in this ! 918: c context, insufficient memory is considered a fatal error.) ! 919: c throughout this routine, *ldval* always contains the subscript of ! 920: c the last addressable word of memory, *memavl* always contains the ! 921: c number of available words of memory, *numblk* always contains the ! 922: c number of allocated blocks, and istack(*loctab* +1) always contains ! 923: c the first word of the block table. ! 924: c ! 925: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 926: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 927: 2 nwd8,nwd16 ! 928: c ! 929: c.. arguments to memory manager are set up as arrays, even though ! 930: c.. the calling programs usually use simple variables for arguments. ! 931: c.. this is necessary if we are to guarantee that the parameters are ! 932: c.. passed by 'address' and not by 'value'. we must insure that locf(arg) ! 933: c.. returns the address of the argument, and not the address of a local ! 934: c.. copy of the argument. as currently configured, this subroutine should ! 935: c.. work on any ansi fortran compiler, provided the function 'locf' can ! 936: c.. be provided. ! 937: dimension ipntr(1) ! 938: c ! 939: logical memptr ! 940: c ! 941: c... approximate time required to copy *nwords* integer values ! 942: nwd4=1 ! 943: nwd8=2 ! 944: nwd16=4 ! 945: memerr=0 ! 946: nevn=nxtevn(1) ! 947: icheck=mod(nevn,nwd4)+mod(nevn,nwd8)+mod(nevn,nwd16)+ ! 948: 1 mod(nxtmem(1),nevn) ! 949: if(icheck.eq.0) go to 2 ! 950: memerr=1 ! 951: call errmem(6,memerr,ipntr(1)) ! 952: 2 cpyknt=0.0d0 ! 953: ifamwa=locf(ipntr(1)) ! 954: maxmem=ksize ! 955: ntab=nxtevn(5) ! 956: c... add 'lorg' to an address and you get the 'istack' index to that word ! 957: lorg=1-locf(istack(1)) ! 958: ifwa=ifamwa+lorg-1 ! 959: nwoff=locf(ipntr(1))+lorg-1 ! 960: icore=nxtmem(1) ! 961: c... don't take chances, back off from 'end of memory' by nxtevn(1) ! 962: ldval=ifwa+nxtmem(1)-nxtevn(1) ! 963: memavl=ldval-ntab-ifwa ! 964: maxcor=0 ! 965: maxuse=0 ! 966: call memory ! 967: if(memerr.ne.0) call errmem(6,memerr,ipntr(1)) ! 968: numblk=1 ! 969: loctab=ldval-ntab ! 970: istack(loctab+1)=0 ! 971: istack(loctab+2)=memavl ! 972: istack(loctab+3)=0 ! 973: istack(loctab+4)=-1 ! 974: istack(loctab+5)=1 ! 975: return ! 976: end ! 977: subroutine getm4(ipntr,ksize) ! 978: implicit double precision (a-h,o-z) ! 979: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 980: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 981: 2 nwd8,nwd16 ! 982: dimension ipntr(1) ! 983: iwsize=nwd4 ! 984: call getmx(ipntr(1),ksize,iwsize) ! 985: return ! 986: end ! 987: subroutine getm8(ipntr,ksize) ! 988: implicit double precision (a-h,o-z) ! 989: dimension ipntr(1) ! 990: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 991: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 992: 2 nwd8,nwd16 ! 993: iwsize=nwd8 ! 994: call getmx(ipntr(1),ksize,iwsize) ! 995: return ! 996: end ! 997: subroutine getm16(ipntr,ksize) ! 998: implicit double precision (a-h,o-z) ! 999: dimension ipntr(1) ! 1000: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1001: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1002: 2 nwd8,nwd16 ! 1003: iwsize=nwd16 ! 1004: call getmx(ipntr(1),ksize,iwsize) ! 1005: return ! 1006: end ! 1007: subroutine getmx(ipntr,ksize,iwsize) ! 1008: implicit double precision (a-h,o-z) ! 1009: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1010: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1011: 2 nwd8,nwd16 ! 1012: logical memptr ! 1013: dimension ipntr(1) ! 1014: c ! 1015: c*** getmem - get block ! 1016: c ! 1017: c ! 1018: isize=ksize*iwsize ! 1019: c... check for valid size ! 1020: if (isize.ge.0) go to 5 ! 1021: memerr=2 ! 1022: call errmem(3,memerr,ipntr(1)) ! 1023: c... check for attempt to reallocate existing block ! 1024: 5 if (.not.memptr(ipntr(1))) go to 8 ! 1025: memerr=3 ! 1026: call errmem(3,memerr,ipntr(1)) ! 1027: 8 jsize=nxtevn(isize) ! 1028: call comprs(0,ldval) ! 1029: c... check if enough space already there ! 1030: need=jsize+ntab-memavl ! 1031: if (need.le.0) go to 10 ! 1032: c... insufficient space -- bump memory size ! 1033: need=nxtmem(need) ! 1034: icore=icore+need ! 1035: call memory ! 1036: if(memerr.ne.0) call errmem(3,memerr,ipntr(1)) ! 1037: ltab1=ldval-ntab ! 1038: istack(ltab1+2)=istack(ltab1+2)+need ! 1039: c... relocate block entry table ! 1040: nwords=numblk*ntab ! 1041: cpyknt=cpyknt+dfloat(nwords) ! 1042: call copy4(istack(loctab+1),istack(loctab+need+1),nwords) ! 1043: loctab=loctab+need ! 1044: ldval=ldval+need ! 1045: memavl=memavl+need ! 1046: c... a block large enough now exists -- allocate it ! 1047: 10 ltab1=ldval-ntab ! 1048: morg=istack(ltab1+1) ! 1049: msiz=istack(ltab1+2) ! 1050: muse=istack(ltab1+3) ! 1051: muse=nxtevn(muse) ! 1052: madr=istack(ltab1+4) ! 1053: c... construct new table entry ! 1054: 15 istack(ltab1+2)=muse ! 1055: loctab=loctab-ntab ! 1056: nwords=numblk*ntab ! 1057: cpyknt=cpyknt+dfloat(nwords) ! 1058: call copy4(istack(loctab+ntab+1),istack(loctab+1),nwords) ! 1059: numblk=numblk+1 ! 1060: memavl=memavl-ntab ! 1061: istack(ltab1+1)=morg+muse ! 1062: istack(ltab1+2)=msiz-muse-ntab ! 1063: c... set user size into table entry for this block ! 1064: 20 istack(ltab1+3)=isize ! 1065: istack(ltab1+4)=locf(ipntr(1)) ! 1066: istack(ltab1+5)=iwsize ! 1067: memavl=memavl-jsize ! 1068: ipntr(1)=istack(ltab1+1)/iwsize ! 1069: call memadj ! 1070: return ! 1071: end ! 1072: subroutine avlm4(iavl) ! 1073: implicit double precision (a-h,o-z) ! 1074: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1075: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1076: 2 nwd8,nwd16 ! 1077: c ! 1078: c*** avlmem - how much space is available ? ! 1079: c ! 1080: iavl=((maxmem-icore)/nxtmem(1))*nxtmem(1)-ntab+memavl ! 1081: iavl=iavl/nwd4 ! 1082: return ! 1083: end ! 1084: subroutine avlm8(iavl) ! 1085: implicit double precision (a-h,o-z) ! 1086: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1087: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1088: 2 nwd8,nwd16 ! 1089: iavl=((maxmem-icore)/nxtmem(1))*nxtmem(1)-ntab+memavl ! 1090: iavl=iavl/nwd8 ! 1091: return ! 1092: end ! 1093: subroutine avlm16(iavl) ! 1094: implicit double precision (a-h,o-z) ! 1095: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1096: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1097: 2 nwd8,nwd16 ! 1098: iavl=((maxmem-icore)/nxtmem(1))*nxtmem(1)-ntab+memavl ! 1099: iavl=iavl/nwd16 ! 1100: return ! 1101: end ! 1102: subroutine relmem(ipntr,ksize) ! 1103: implicit double precision (a-h,o-z) ! 1104: dimension ipntr(1) ! 1105: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1106: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1107: 2 nwd8,nwd16 ! 1108: logical memptr ! 1109: c ! 1110: c*** relmem - release part of block ! 1111: c ! 1112: c ! 1113: c... check for valid pointer ! 1114: if (memptr(ipntr(1))) go to 10 ! 1115: memerr=5 ! 1116: call errmem(5,memerr,ipntr(1)) ! 1117: 10 isize=ksize*istack(ltab+5) ! 1118: c... check for valid size ! 1119: if (isize.ge.0) go to 20 ! 1120: memerr=2 ! 1121: call errmem(5,memerr,ipntr(1)) ! 1122: 20 jsize=istack(ltab+3) ! 1123: if (isize.le.jsize) go to 30 ! 1124: memerr=6 ! 1125: call errmem(5,memerr,ipntr(1)) ! 1126: 30 istack(ltab+3)=istack(ltab+3)-isize ! 1127: memavl=memavl+(nxtevn(jsize)-nxtevn(istack(ltab+3))) ! 1128: call memadj ! 1129: return ! 1130: end ! 1131: subroutine extmem(ipntr,ksize) ! 1132: implicit double precision (a-h,o-z) ! 1133: dimension ipntr(1) ! 1134: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1135: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1136: 2 nwd8,nwd16 ! 1137: logical memptr ! 1138: c ! 1139: c*** extmem - extend size of existing block ! 1140: c ! 1141: c ! 1142: c... check for valid pointer ! 1143: if (memptr(ipntr(1))) go to 10 ! 1144: memerr=5 ! 1145: call errmem(2,memerr,ipntr(1)) ! 1146: 10 isize=ksize*istack(ltab+5) ! 1147: c... check for valid size ! 1148: if (isize.ge.0) go to 20 ! 1149: memerr=2 ! 1150: call errmem(2,memerr,ipntr(1)) ! 1151: c... check if enough space already there ! 1152: 20 if ((istack(ltab+2)-istack(ltab+3)).ge.isize) go to 40 ! 1153: need=nxtevn(isize)-memavl ! 1154: if (need.le.0) go to 30 ! 1155: c... insufficient space -- bump memory size ! 1156: need=nxtmem(need) ! 1157: icore=icore+need ! 1158: call memory ! 1159: if(memerr.ne.0) call errmem(2,memerr,ipntr(1)) ! 1160: ltab1=ldval-ntab ! 1161: istack(ltab1+2)=istack(ltab1+2)+need ! 1162: c... relocate block entry table ! 1163: nwords=numblk*ntab ! 1164: cpyknt=cpyknt+dfloat(nwords) ! 1165: call copy4(istack(loctab+1),istack(loctab+need+1),nwords) ! 1166: loctab=loctab+need ! 1167: ldval=ldval+need ! 1168: memavl=memavl+need ! 1169: ltab=ltab+need ! 1170: c... move blocks to make space ! 1171: 30 continue ! 1172: call comprs(0,ltab) ! 1173: call comprs(1,ltab) ! 1174: 40 jsize=istack(ltab+3) ! 1175: istack(ltab+3)=istack(ltab+3)+isize ! 1176: memavl=memavl-(nxtevn(istack(ltab+3))-nxtevn(jsize)) ! 1177: call memadj ! 1178: return ! 1179: end ! 1180: subroutine sizmem(ipntr,ksize) ! 1181: implicit double precision (a-h,o-z) ! 1182: dimension ipntr(1) ! 1183: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1184: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1185: 2 nwd8,nwd16 ! 1186: logical memptr ! 1187: c ! 1188: c*** sizmem - determine size of existing block ! 1189: c ! 1190: c ! 1191: c... check for valid pointer ! 1192: if (memptr(ipntr(1))) go to 10 ! 1193: memerr=5 ! 1194: call errmem(7,memerr,ipntr(1)) ! 1195: 10 ksize=istack(ltab+3)/istack(ltab+5) ! 1196: return ! 1197: end ! 1198: subroutine clrmem(ipntr) ! 1199: implicit double precision (a-h,o-z) ! 1200: dimension ipntr(1) ! 1201: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1202: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1203: 2 nwd8,nwd16 ! 1204: logical memptr ! 1205: c ! 1206: c*** clrmem - release block ! 1207: c ! 1208: c ! 1209: c... check that pointer is valid ! 1210: if (memptr(ipntr(1))) go to 10 ! 1211: memerr=5 ! 1212: call errmem(1,memerr,ipntr(1)) ! 1213: 10 msiz=istack(ltab+2) ! 1214: muse=istack(ltab+3) ! 1215: memavl=memavl+nxtevn(muse) ! 1216: c... assumption: first allocated block is never cleared. ! 1217: ltab1=ltab-ntab ! 1218: istack(ltab1+2)=istack(ltab1+2)+msiz ! 1219: c... reposition the block table ! 1220: nwords=ltab-loctab ! 1221: cpyknt=cpyknt+dfloat(nwords) ! 1222: call copy4(istack(loctab+1),istack(loctab+ntab+1),nwords) ! 1223: numblk=numblk-1 ! 1224: loctab=loctab+ntab ! 1225: memavl=memavl+ntab ! 1226: ltab1=ldval-ntab ! 1227: istack(ltab1+2)=istack(ltab1+2)+ntab ! 1228: ipntr(1)=2**31-1 ! 1229: call memadj ! 1230: return ! 1231: end ! 1232: subroutine ptrmem(ipntr,ipntr2) ! 1233: implicit double precision (a-h,o-z) ! 1234: dimension ipntr(1),ipntr2(1) ! 1235: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1236: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1237: 2 nwd8,nwd16 ! 1238: logical memptr ! 1239: c ! 1240: c*** ptrmem - reset memory pointer ! 1241: c ! 1242: c... verify that pointer is valid ! 1243: if (memptr(ipntr(1))) go to 10 ! 1244: memerr=5 ! 1245: call errmem(4,memerr,ipntr(1)) ! 1246: c... reset block pointer to be *ipntr2* ! 1247: 10 ipntr2(1)=ipntr(1) ! 1248: istack(ltab+4)=locf(ipntr2(1)) ! 1249: call memadj ! 1250: return ! 1251: end ! 1252: subroutine crunch ! 1253: implicit double precision (a-h,o-z) ! 1254: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1255: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1256: 2 nwd8,nwd16 ! 1257: c ! 1258: c*** crunch - force memory compaction ! 1259: c ! 1260: call comprs(0,ldval) ! 1261: call memadj ! 1262: return ! 1263: end ! 1264: subroutine errmem(inam,ierror,ipntr) ! 1265: implicit double precision (a-h,o-z) ! 1266: dimension ipntr(1) ! 1267: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1268: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1269: 2 nwd8,nwd16 ! 1270: dimension errnam(7) ! 1271: data errnam /6hclrmem,6hextmem,6hgetmem,6hptrmem,6hrelmem, ! 1272: 1 6hsetmem,6hsizmem/ ! 1273: c ! 1274: go to (200,410,420,300,510,530),ierror ! 1275: c ! 1276: c*** error(s) found *** ! 1277: c ! 1278: c.. nxtevn and/or nxtmem incompatible with nwd4, nwd8, and nwd16 ! 1279: c ! 1280: 200 write(6,201) ! 1281: 201 format('0memory manager variables nwd4-8-16 incompatible with nxte ! 1282: 1vn and nxtmem') ! 1283: go to 900 ! 1284: c ! 1285: c... memory needs exceed maximum available space ! 1286: 300 write (6,301) maxmem ! 1287: 301 format('0*error*: memory needs exceed',i6,/, ! 1288: 1 '0probable remedy, replace your "// exec spice" card with',/ ! 1289: 2 '0// exec spice,region=2000k') ! 1290: go to 900 ! 1291: c... *isize* < 0 ! 1292: 410 write(6,411) ! 1293: 411 format('0size parameter negative') ! 1294: go to 900 ! 1295: c... getmem: attempt to reallocate existing block ! 1296: 420 write(6,421) ! 1297: 421 format('0attempt to reallocate existing table') ! 1298: go to 900 ! 1299: c... *ipntr* invalid ! 1300: 510 write(6,511) ! 1301: 511 format('0table pointer invalid') ! 1302: go to 900 ! 1303: c... relmem: *isize* larger than indicated block ! 1304: 530 write(6,531) ! 1305: 531 format('0attempt to release more than total table') ! 1306: c... issue error message ! 1307: 900 write (6,901) errnam(inam) ! 1308: 901 format('0*abort*: internal memory manager error at entry ', ! 1309: 1 a7) ! 1310: 950 call dmpmem(ipntr(1)) ! 1311: 1000 stop ! 1312: end ! 1313: subroutine memadj ! 1314: implicit double precision (a-h,o-z) ! 1315: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1316: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1317: 2 nwd8,nwd16 ! 1318: c ! 1319: c*** adjust memory downward *** ! 1320: c ! 1321: 50 maxuse=max0(maxuse,ldval-memavl-ifwa) ! 1322: memdec=2*nxtmem(1) ! 1323: if (memavl.lt.memdec) return ! 1324: c... compress current allocations of memory ! 1325: call comprs(0,ldval) ! 1326: c... adjust memory size ! 1327: memdel=0 ! 1328: 60 icore=icore-memdec ! 1329: memdel=memdel+memdec ! 1330: memavl=memavl-memdec ! 1331: if (memavl.ge.memdec) go to 60 ! 1332: ltab1=ldval-ntab ! 1333: istack(ltab1+2)=istack(ltab1+2)-memdel ! 1334: c... relocate block entry table ! 1335: nwords=numblk*ntab ! 1336: cpyknt=cpyknt+dfloat(nwords) ! 1337: call copy4(istack(loctab+1),istack(loctab-memdel+1),nwords) ! 1338: loctab=loctab-memdel ! 1339: ldval=ldval-memdel ! 1340: call memory ! 1341: return ! 1342: end ! 1343: integer function nxtevn(n) ! 1344: c ! 1345: c.. function returns the smallest value nxtevn greater than or equal to ! 1346: c.. n which is evenly divisible by 'nwd4, nwd8, and nwd16' as defined ! 1347: c.. in setmem ! 1348: c ! 1349: nxtevn=((n+3)/4)*4 ! 1350: return ! 1351: end ! 1352: integer function nxtmem(memwds) ! 1353: c ! 1354: c.. function returns the in nxtmem the next available memory size ! 1355: c.. (which must be evenly divisible by 'nwd4, nwd8, and nwd16' as ! 1356: c.. defined in setmem ! 1357: c ! 1358: nxtmem=((memwds+1999)/2000)*2000 ! 1359: return ! 1360: end ! 1361: subroutine comprs(icode,limit) ! 1362: implicit double precision (a-h,o-z) ! 1363: c ! 1364: c this routine compresses all available memory into a single block. ! 1365: c if *icode* is zero, compression of memory from word 1 to *limit* is ! 1366: c done; otherwise, compression from *ldval* down to *limit* is done. ! 1367: c ! 1368: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1369: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1370: 2 nwd8,nwd16 ! 1371: c ! 1372: c... approximate time required to copy *nwords* real values ! 1373: if (icode.ne.0) go to 100 ! 1374: nblk=numblk ! 1375: ltab2=loctab ! 1376: 10 ltab1=ltab2 ! 1377: if (ltab1.ge.limit) go to 200 ! 1378: if (nblk.eq.1) go to 200 ! 1379: nblk=nblk-1 ! 1380: ltab2=ltab1+ntab ! 1381: morg=istack(ltab1+1) ! 1382: msiz=istack(ltab1+2) ! 1383: muse=istack(ltab1+3) ! 1384: muse=nxtevn(muse) ! 1385: if (msiz.eq.muse) go to 10 ! 1386: c... move succeeding block down ! 1387: morg2=istack(ltab2+1) ! 1388: muse2=istack(ltab2+3) ! 1389: madr2=istack(ltab2+4) ! 1390: iwsize=istack(ltab2+5) ! 1391: if (madr2.ne.0) go to 15 ! 1392: if (muse2.eq.0) go to 20 ! 1393: 15 cpyknt=cpyknt+dfloat(muse2) ! 1394: call copy4(istack(nwoff+morg2+1),istack(nwoff+morg+muse+1),muse2) ! 1395: istack(lorg+madr2)=(morg+muse)/iwsize ! 1396: 20 istack(ltab1+2)=muse ! 1397: istack(ltab2+1)=morg+muse ! 1398: istack(ltab2+2)=istack(ltab2+2)+(msiz-muse) ! 1399: go to 10 ! 1400: c ! 1401: c ! 1402: 100 nblk=numblk ! 1403: ltab2=ldval-ntab ! 1404: 110 ltab1=ltab2 ! 1405: if (ltab1.le.limit) go to 200 ! 1406: if (nblk.eq.1) go to 200 ! 1407: nblk=nblk-1 ! 1408: ltab2=ltab1-ntab ! 1409: morg=istack(ltab1+1) ! 1410: msiz=istack(ltab1+2) ! 1411: muse=istack(ltab1+3) ! 1412: muse=nxtevn(muse) ! 1413: madr=istack(ltab1+4) ! 1414: iwsize=istack(ltab1+5) ! 1415: mspc=msiz-muse ! 1416: if (mspc.eq.0) go to 110 ! 1417: cpyknt=cpyknt+dfloat(muse) ! 1418: call copy4(istack(nwoff+morg+1),istack(nwoff+morg+mspc+1),muse) ! 1419: istack(ltab1+1)=morg+mspc ! 1420: istack(ltab1+2)=muse ! 1421: istack(ltab2+2)=istack(ltab2+2)+mspc ! 1422: if (madr.eq.0) go to 110 ! 1423: istack(lorg+madr)=(morg+mspc)/iwsize ! 1424: go to 110 ! 1425: c... all done ! 1426: 200 return ! 1427: end ! 1428: logical function memptr(ipntr) ! 1429: implicit double precision (a-h,o-z) ! 1430: c ! 1431: c this routine checks whether *ipntr* is a valid block pointer. ! 1432: c if it is valid, *ltab* is set to point to the corresponding entry in ! 1433: c the block table. ! 1434: c ! 1435: c... ipntr is an array to avoid 'call by value' problems (see setmem) ! 1436: dimension ipntr(1) ! 1437: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1438: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1439: 2 nwd8,nwd16 ! 1440: c ! 1441: memptr=.false. ! 1442: ltab=loctab ! 1443: locpnt=locf(ipntr(1)) ! 1444: do 20 i=1,numblk ! 1445: if (locpnt.ne.istack(ltab+4)) go to 10 ! 1446: if (ipntr(1)*istack(ltab+5).ne.istack(ltab+1)) go to 10 ! 1447: memptr=.true. ! 1448: go to 30 ! 1449: 10 ltab=ltab+ntab ! 1450: 20 continue ! 1451: 30 return ! 1452: end ! 1453: subroutine dmpmem(ipntr) ! 1454: implicit double precision (a-h,o-z) ! 1455: c ! 1456: c this routine prints out the current memory allocation map. ! 1457: c *ipntr* is the table pointer of the current memory manager call ! 1458: c ! 1459: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem, ! 1460: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize, ! 1461: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr, ! 1462: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1, ! 1463: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd, ! 1464: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval ! 1465: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1466: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1467: 2 nwd8,nwd16 ! 1468: c... ipntr is an array to avoid 'call by value' problems ! 1469: dimension ipntr(1) ! 1470: dimension aptr(61) ! 1471: data aptr /6hielmnt,6hisbckt,6hnsbckt,6hiunsat,6hnunsat,6hitemps, ! 1472: 1 6hnumtem,6hisens ,6hnsens ,6hifour ,6hnfour ,6hifield, ! 1473: 2 6hicode ,6hidelim,6hicolum,6hinsize, ! 1474: 3 6hjunode,6hlsbkpt,6hnumbkp,6hiorder,6hjmnode, ! 1475: 4 6hiur ,6hiuc ,6hilc ,6hilr ,6hnumoff,6hisr , ! 1476: 5 6hnmoffc,6hiseq ,6hiseq1 ,6hneqn ,6hnodevs, ! 1477: 6 6hndiag ,6hiswap ,6hiequa ,6hmacins,6hlvnim1, ! 1478: 7 6hlx0 ,6hlvn ,6hlynl ,6hlyu ,6hlyl , ! 1479: 8 6hlx1 ,6hlx2 ,6hlx3 ,6hlx4 ,6hlx5 ,6hlx6 , ! 1480: 9 6hlx7 ,6hld0 ,6hld1 ,6hltd ,6himynl ,6himvn ,6hloutpt, ! 1481: * 6hnsnod ,6hnsmat ,6hnsval ,6hicnod ,6hicmat ,6hicval / ! 1482: data ablnk /1h / ! 1483: iaddr=locf(ielmnt)-1 ! 1484: itemp=locf(ipntr(1))-iaddr ! 1485: anam=ablnk ! 1486: if(itemp.gt.0.and.itemp.le.61) anam=aptr(itemp) ! 1487: iadr=locf(ipntr(1)) ! 1488: write (6,5) anam,iadr,icore,maxmem,memavl,ldval ! 1489: 5 format('0current pointer 'a6,'@ = z',z6,/' corsiz=',i7, ! 1490: 1 /' maxmem=',i7,/' avlspc=',i7,/' ldval=',i7, ! 1491: 2 /1h0,24x,'memory allocation map'/14x,'blknum memorg memsiz', ! 1492: 3 ' memuse usrptr addr name') ! 1493: ltab1=loctab ! 1494: do 20 i=1,numblk ! 1495: morg=istack(ltab1+1) ! 1496: msiz=istack(ltab1+2) ! 1497: muse=istack(ltab1+3) ! 1498: madr=istack(ltab1+4) ! 1499: anam=ablnk ! 1500: ndex=madr-iaddr ! 1501: if(ndex.gt.0.and.ndex.le.61) anam=aptr(ndex) ! 1502: jptr=0 ! 1503: if (madr.gt.0) jptr=istack(lorg+madr) ! 1504: write (6,11) i,morg,msiz,muse,jptr,madr,anam ! 1505: 11 format(13x,5i7,3x,z7,'z',1x,a6) ! 1506: ltab1=ltab1+ntab ! 1507: 20 continue ! 1508: write (6,21) ! 1509: 21 format(1h0,24x,'end of allocation map'/) ! 1510: return ! 1511: end ! 1512: subroutine memory ! 1513: implicit double precision (a-h,o-z) ! 1514: common /memmgr/ cpyknt,istack(1),lorg,icore,maxcor,maxuse,memavl, ! 1515: 1 ldval,numblk,loctab,ltab,ifwa,nwoff,ntab,maxmem,memerr,nwd4, ! 1516: 2 nwd8,nwd16 ! 1517: if(icore.le.maxmem) go to 10 ! 1518: memerr=4 ! 1519: return ! 1520: 10 continue ! 1521: return ! 1522: end ! 1523: subroutine magphs(cvar,xmag,xphs) ! 1524: implicit double precision (a-h,o-z) ! 1525: c ! 1526: c this routine computes the magnitude and phase of its complex arg- ! 1527: c ument cvar, storing the results in xmag and xphs. ! 1528: c ! 1529: common /knstnt/ twopi,xlog2,xlog10,root2,rad,boltz,charge,ctok, ! 1530: 1 gmin,reltol,abstol,vntol,trtol,chgtol,eps0,epssil,epsox ! 1531: complex*16 cvar ! 1532: c ! 1533: c ! 1534: xreal=dreal(cvar) ! 1535: ximag=dimag(cvar) ! 1536: xmag=dsqrt(xreal*xreal+ximag*ximag) ! 1537: if (xmag.ge.1.0d-20) go to 10 ! 1538: xmag=1.0d-20 ! 1539: xphs=0.0d0 ! 1540: return ! 1541: 10 xphs=rad*datan2(ximag,xreal) ! 1542: return ! 1543: end ! 1544: integer function xxor(a,b) ! 1545: implicit double precision (a-h,o-z) ! 1546: c ! 1547: c this routine computes a single-precision integer result which is ! 1548: c the result of exclusive-or*ing the two real-valued arguments a and b ! 1549: c together. ! 1550: c ! 1551: xxor=1 ! 1552: if(a.eq.b) xxor=0 ! 1553: return ! 1554: end ! 1555: subroutine outnam(loc,ktype,string,ipos) ! 1556: implicit double precision (a-h,o-z) ! 1557: c ! 1558: c this routine constructs the 'name' for the output variable indi- ! 1559: c cated by loc, adding the characters to the character array 'string', ! 1560: c beginning with the position marked by ipos. ! 1561: c ! 1562: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem, ! 1563: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize, ! 1564: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr, ! 1565: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1, ! 1566: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd, ! 1567: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval ! 1568: common /blank/ value(50000) ! 1569: integer nodplc(64) ! 1570: complex*16 cvalue(32) ! 1571: equivalence (value(1),nodplc(1),cvalue(1)) ! 1572: c ! 1573: dimension string(1) ! 1574: dimension aout(19),lenout(19),aopt(5),lenopt(5) ! 1575: data aout / 6hv , 6hvm , 6hvr , 6hvi , 6hvp , ! 1576: 1 6hvdb , 6hi , 6him , 6hir , 6hii , ! 1577: 2 6hip , 6hidb , 6honoise, 6hinoise, 6hhd2 , ! 1578: 1 6hhd3 , 6hdim2 , 6hsim2 , 6hdim3 / ! 1579: data lenout / 1,2,2,2,2,3,1,2,2,2,2,3,6,6,3,3,4,4,4 / ! 1580: data aopt / 5hmag , 5hreal , 5himag , 5hphase, 5hdb / ! 1581: data lenopt / 3,4,4,5,2 / ! 1582: data alprn, acomma, arprn, ablnk / 1h(, 1h,, 1h), 1h / ! 1583: c ! 1584: c ! 1585: ioutyp=nodplc(loc+5) ! 1586: if (ioutyp.ge.2) go to 10 ! 1587: lout=ktype+ioutyp*6 ! 1588: go to 20 ! 1589: 10 lout=ioutyp+11 ! 1590: 20 call move(string,ipos,aout(lout),1,lenout(lout)) ! 1591: ipos=ipos+lenout(lout) ! 1592: if (ioutyp.ge.2) go to 200 ! 1593: call move(string,ipos,alprn,1,1) ! 1594: ipos=ipos+1 ! 1595: if (ioutyp.ne.0) go to 100 ! 1596: node1=nodplc(loc+2) ! 1597: call alfnum(nodplc(junode+node1),string,ipos) ! 1598: node2=nodplc(loc+3) ! 1599: if (node2.eq.1) go to 30 ! 1600: call move(string,ipos,acomma,1,1) ! 1601: ipos=ipos+1 ! 1602: call alfnum(nodplc(junode+node2),string,ipos) ! 1603: 30 call move(string,ipos,arprn,1,1) ! 1604: ipos=ipos+1 ! 1605: go to 1000 ! 1606: c ! 1607: 100 locv=nodplc(loc+1) ! 1608: anam=value(locv) ! 1609: achar=ablnk ! 1610: do 110 i=1,8 ! 1611: call move(achar,1,anam,i,1) ! 1612: if (achar.eq.ablnk) go to 120 ! 1613: call move(string,ipos,achar,1,1) ! 1614: ipos=ipos+1 ! 1615: 110 continue ! 1616: 120 call move(string,ipos,arprn,1,1) ! 1617: ipos=ipos+1 ! 1618: go to 1000 ! 1619: c ! 1620: 200 if (ktype.eq.1) go to 1000 ! 1621: call move(string,ipos,alprn,1,1) ! 1622: ipos=ipos+1 ! 1623: call move(string,ipos,aopt(ktype-1),1,lenopt(ktype-1)) ! 1624: ipos=ipos+lenopt(ktype-1) ! 1625: call move(string,ipos,arprn,1,1) ! 1626: ipos=ipos+1 ! 1627: c ! 1628: c finished ! 1629: c ! 1630: 1000 return ! 1631: end ! 1632: subroutine alfnum(number,string,ipos) ! 1633: implicit double precision (a-h,o-z) ! 1634: c ! 1635: c this routine converts number into character form, storing the ! 1636: c characters in the character array string, beginning with the position ! 1637: c indicated by ipos. ! 1638: c ! 1639: c **** note that the 'ipos' variable is changed to indicate the position ! 1640: c of the next unwritten character. this could clobber constants if ! 1641: c ipos is not a variable in the calling program ! 1642: c ! 1643: dimension string(1) ! 1644: dimension adigit(10) ! 1645: data adigit / 1h0,1h1,1h2,1h3,1h4,1h5,1h6,1h7,1h8,1h9 / ! 1646: data aminus / 1h- / ! 1647: c ! 1648: c ! 1649: num=number ! 1650: c ! 1651: c check for number < 0 ! 1652: c ! 1653: if (num.ge.0) go to 10 ! 1654: num=-num ! 1655: c... negative number: insert minus sign ! 1656: call move(string,ipos,aminus,1,1) ! 1657: ipos=ipos+1 ! 1658: c ! 1659: c convert number one digit at a time, in reverse order ! 1660: c ! 1661: 10 istart=ipos ! 1662: 20 numtmp=num/10 ! 1663: idigit=num-numtmp*10 ! 1664: call move(string,ipos,adigit(idigit+1),1,1) ! 1665: ipos=ipos+1 ! 1666: num=numtmp ! 1667: if (num.ne.0) go to 20 ! 1668: istop=ipos-1 ! 1669: c ! 1670: c now reverse the order of the digits ! 1671: c ! 1672: 30 if (istop.le.istart) go to 40 ! 1673: call move(tmpdgt,1,string,istart,1) ! 1674: call move(string,istart,string,istop,1) ! 1675: call move(string,istop,tmpdgt,1,1) ! 1676: istart=istart+1 ! 1677: istop=istop-1 ! 1678: go to 30 ! 1679: c ! 1680: c conversion complete ! 1681: c ! 1682: 40 return ! 1683: end ! 1684: subroutine getcje ! 1685: implicit double precision (a-h,o-z) ! 1686: common /cje/ maxtim,itime,icost ! 1687: call second(xtime) ! 1688: itime=xtime ! 1689: icost=xtime*38.3333 ! 1690: return ! 1691: end ! 1692: subroutine move(a,iposa,b,iposb,nchar) ! 1693: character a(1),b(1) ! 1694: do 10 i=1,nchar ! 1695: a(iposa+i-1)=b(iposb+i-1) ! 1696: 10 continue ! 1697: return ! 1698: end ! 1699: subroutine copy4(ifrom,ito,nwords) ! 1700: implicit double precision (a-h,o-z) ! 1701: c ! 1702: dimension ifrom(1),ito(1) ! 1703: c this routine copies a block of #nwords# words (of the appropriate ! 1704: c type) from the array #from# to the array #to#. it determines from ! 1705: c which end of the block to transfer first, to prevent over-stores which ! 1706: c might over-write the data. ! 1707: c ! 1708: if (nwords.eq.0) return ! 1709: if (locf(ifrom(1)).lt.locf(ito(1))) go to 20 ! 1710: c... locf() returns as its value the address of its argument ! 1711: do 10 i=1,nwords ! 1712: ito(i)=ifrom(i) ! 1713: 10 continue ! 1714: return ! 1715: c ! 1716: 20 i=nwords ! 1717: 30 ito(i)=ifrom(i) ! 1718: i=i-1 ! 1719: if (i.ne.0) go to 30 ! 1720: return ! 1721: c ! 1722: c ! 1723: end ! 1724: subroutine copy8(rfrom,rto,nwords) ! 1725: implicit double precision (a-h,o-z) ! 1726: c ! 1727: dimension rfrom(1),rto(1) ! 1728: if (nwords.eq.0) return ! 1729: if (locf(rfrom(1)).lt.locf(rto(1))) go to 120 ! 1730: do 110 i=1,nwords ! 1731: rto(i)=rfrom(i) ! 1732: 110 continue ! 1733: return ! 1734: c ! 1735: 120 i=nwords ! 1736: 130 rto(i)=rfrom(i) ! 1737: i=i-1 ! 1738: if (i.ne.0) go to 130 ! 1739: return ! 1740: c ! 1741: c ! 1742: end ! 1743: subroutine copy16(cfrom,cto,nwords) ! 1744: implicit double precision (a-h,o-z) ! 1745: c ! 1746: complex*16 cfrom(1),cto(1) ! 1747: if (nwords.eq.0) return ! 1748: if (locf(cfrom(1)).lt.locf(cto(1))) go to 220 ! 1749: do 210 i=1,nwords ! 1750: cto(i)=cfrom(i) ! 1751: 210 continue ! 1752: return ! 1753: c ! 1754: 220 i=nwords ! 1755: 230 cto(i)=cfrom(i) ! 1756: i=i-1 ! 1757: if (i.ne.0) go to 230 ! 1758: return ! 1759: end ! 1760: subroutine zero4(iarray,length) ! 1761: implicit double precision (a-h,o-z) ! 1762: c ! 1763: dimension iarray(1) ! 1764: c this routine zeroes the memory locations indicated by array(1) ! 1765: c through array(length). ! 1766: c ! 1767: if (length.eq.0) return ! 1768: do 10 i=1,length ! 1769: iarray(i)=0 ! 1770: 10 continue ! 1771: return ! 1772: end ! 1773: subroutine zero8(array,length) ! 1774: implicit double precision (a-h,o-z) ! 1775: c ! 1776: dimension array(1) ! 1777: c this routine zeroes the memory locations indicated by array(1) ! 1778: c through array(length). ! 1779: c ! 1780: if (length.eq.0) return ! 1781: do 10 i=1,length ! 1782: array(i)=0.0d0 ! 1783: 10 continue ! 1784: return ! 1785: end ! 1786: subroutine zero16(carray,length) ! 1787: implicit double precision (a-h,o-z) ! 1788: complex*16 carray(1) ! 1789: c ! 1790: c this routine zeroes the memory locations indicated by array(1) ! 1791: c through array(length). ! 1792: c ! 1793: if (length.eq.0) return ! 1794: do 10 i=1,length ! 1795: carray(i)=dcmplx(0.0d0,0.0d0) ! 1796: 10 continue ! 1797: return ! 1798: c ! 1799: c ! 1800: c ! 1801: end ! 1802: integer function locf(ivar) ! 1803: iabsa=loc(ivar) ! 1804: locf=iabsa/4 ! 1805: if(iabsa.eq.locf*4) return ! 1806: write(6,100) iabsa ! 1807: 100 format('0*error*: system 370 error..address ',t10, ! 1808: 1 ' is not on a 4-byte boundary') ! 1809: stop ! 1810: end ! 1811: subroutine mdate(anam) ! 1812: implicit double precision (a-h,o-z) ! 1813: call date(anam) ! 1814: return ! 1815: end ! 1816: subroutine mclock(anam) ! 1817: implicit double precision (a-h,o-z) ! 1818: call todalf(anam) ! 1819: 100 return ! 1820: end ! 1821: subroutine second(t1) ! 1822: implicit double precision (a-h,o-z) ! 1823: dimension ibuff(4) ! 1824: real*8 t1 ! 1825: call times (ibuff) ! 1826: t1 = dfloat (ibuff(1)) / 60.d0 ! 1827: return ! 1828: end ! 1829: subroutine todalf(anam) ! 1830: double precision anam ! 1831: anam=0.0d0 ! 1832: return ! 1833: end ! 1834: double precision function cpusec(time) ! 1835: cpusec=0.0d0 ! 1836: return ! 1837: end ! 1838: subroutine date(anam) ! 1839: double precision anam ! 1840: anam=1.0d0 ! 1841: return ! 1842: end ! 1843: FUNCTION DREAL ( X ) ! 1844: COMPLEX*16 X ! 1845: DREAL = REAL (X) ! 1846: RETURN ! 1847: END ! 1848: cunix FUNCTION DIMAG ( X ) ! 1849: cunix COMPLEX*16 X ! 1850: cunix DIMAG = AIMAG (X) ! 1851: cunix RETURN ! 1852: cunix END ! 1853: cunix COMPLEX FUNCTION DCMPLX ( X , Y ) ! 1854: cunix DCMPLX = CMPLX ( X , Y ) ! 1855: cunix RETURN ! 1856: cunix END ! 1857: cunix COMPLEX FUNCTION DCONJG ( X ) ! 1858: cunix COMPLEX*16 X ! 1859: cunix DCONJG = CONJG ( X ) ! 1860: cunix RETURN ! 1861: cunix END ! 1862: FUNCTION IFIXD ( X ) ! 1863: IFIXD = IFIX ( X ) ! 1864: RETURN ! 1865: END
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.