Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

king.f

Go to the documentation of this file.
00001 
00002 c       Generate a King model.
00003 c
00004 c       Parameters:     -n number
00005 c                       -w depth
00006 c                       -i random seed
00007 c
00008 c       Note: Uses functions qromb, rkode, and random numbers
00009 c             from "Numerical Recipes"
00010 
00011         program kingmodel
00012 
00013         implicit real*8 (a-h, o-z)
00014         parameter (NMAX = 50000)
00015         
00016         real*8 mass(NMAX), pos(NMAX, 3), vel(NMAX, 3)
00017         real*8 w0
00018         real*8 r, random
00019         integer n, iargc 
00020         integer iseed
00021         character*80 arg
00022 
00023 c       Settable parameters:    w0 = dimensionless depth
00024 c                               n  = number of particles
00025 
00026         iout = 1
00027 
00028 c       Initialize random number generator using iseed.
00029         iseed = 42
00030 
00031         n = 0
00032         do i=1,iargc()
00033             call getarg(i, arg)
00034             if (arg(1:2) .eq. '-w') then
00035                 call getarg(i+1, arg)
00036                 read(arg, '(i10)', iostat=io) iw
00037                 if (io.eq.0) then
00038                    w0 = iw
00039                 else
00040                    read(arg, '(f8.3)', iostat=io) w0
00041                    if (io.ne.0) then
00042                       write(6,'(a)')'Error reading w0.'
00043                       stop
00044                    end if
00045                 end if
00046                 call setking(w0)
00047             else if (arg(1:2) .eq. '-n') then
00048                 call getarg(i+1, arg)
00049                 read(arg, '(i10)', iostat=io) n
00050                 if (io.ne.0) then
00051                     write(6,'(a)')'Error reading N.'
00052                     stop
00053                  end if
00054             else if (arg(1:2) .eq. '-i') then
00055                 call getarg(i+1, arg)
00056                 read(arg, '(i10)', iostat=io) iseed
00057                 if (io.ne.0) then
00058                     write(6,'(a)')'Error reading iseed.'
00059                     stop
00060                 end if
00061                 r = random(iseed)
00062             end if
00063          end do
00064 
00065         if (n .le. 0) then
00066             write(6,'(a)')'Number of stars (N) not set: use "-n #".'
00067             stop
00068         end if
00069 
00070         call king(mass, pos, vel, n, NMAX, iout)
00071         
00072         do i=1,n
00073            print *, i, mass(i), (pos(i,k),k=1,3),  (vel(i,k),k=1,3)
00074         end do
00075         
00076         end
00077         
00078         
00079         block data init_king
00080 
00081         implicit real*8 (a-h,o-z)
00082 
00083         common/kpars1/w0,v0,e0,pi,twopi
00084         common/kpars2/nprof
00085         common/therm/g(0:1000)
00086 
00087         data w0/0./
00088         data g(0)/-1./
00089 
00090         end
00091         
00092         
00093         subroutine setking(w)
00094 
00095         implicit real*8 (a-h,o-z)
00096 
00097         common/kpars1/w0,v0,e0,pi,twopi
00098         common/kpars2/nprof
00099 
00100         w0=w
00101 
00102         end
00103         
00104         
00105         subroutine king(body,x,xdot,n,nmx,iout)
00106 
00107 c       Set up a King model, with total mass = 1, core radius = 1..
00108 
00109         implicit real*8 (a-h,o-z)
00110 
00111         dimension body(nmx),xdot(nmx,3)
00112         real*8 x(nmx,3)
00113 
00114         parameter (nm=2500)
00115         common/profile/rr(0:nm),d(0:nm),v2(0:nm),psi(0:nm),
00116      &       zm(0:nm),indx(0:100)
00117         common/kpars1/w0,v0,e0,pi,twopi
00118         common/kpars2/nprof
00119 
00120         if (w0.eq.0.) then
00121            write(6,'(a)')'Dimensionless depth of'//
00122      &         ' cluster potential (w0) not set: use "-w #".'
00123            stop
00124         end if
00125 
00126 c       Compute the cluster density/velocity/potential profile.
00127 
00128         call poisson(rr,d,v2,psi,zm,nm,w0,nprof,v20,iout)
00129 
00130 c       do i=0,nprof
00131 c           write(0,*), i, rr(i), d(i)
00132 c       end do
00133 
00134 c       Index the mass distribution.
00135 
00136         do 10 i=0,nprof
00137            zm(i)=zm(i)/zm(nprof)
00138  10     continue
00139         indx(0)=0
00140         indx(100)=nprof
00141 
00142 c       Determine core and half-mass radii.
00143 
00144         dz=.01
00145         z=dz
00146         iz=1
00147         do 20 j=1,nprof-1
00148            if (rr(j).lt.1.)jcore=j
00149            if (zm(j).lt..5)jhalf=j
00150            if (zm(j).gt.z) then
00151               indx(iz)=j-1
00152               z=z+dz
00153               iz=iz+1
00154            end if
00155  20     continue
00156         rhalf=rr(jhalf)+(rr(jhalf+1)-rr(jhalf))*(.5-zm(jhalf))
00157      &       /(zm(jhalf+1)-zm(jhalf))
00158         zmcore=zm(jcore)+(zm(jcore+1)-zm(jcore))*(1.-rr(jcore))
00159      &       /(rr(jcore+1)-rr(jcore))
00160 
00161         if (iout.ne.0)write(6,30)w0,nprof,v20,rr(nprof),rhalf,zmcore
00162 30      format(/' King model:  W0 =',f6.2,',  NPROF = ',i4/
00163      &          ' V20/E0 =',f7.3,', Rt/Rc =',f7.2,
00164      &          ', Rh/Rc =',f6.2,', Mc/M =',f7.4/)
00165 
00166         zmass=0.
00167         body(1)=1.
00168 
00169         do 50 i=1,n
00170             body(i)=body(1)
00171             zmass=zmass+body(i)
00172 50      continue
00173         d0=zmass/zm(nprof)
00174         pi=4.*atan(1.)
00175         twopi=2.*pi
00176         four3pi=4.*pi/3.
00177         e0=four3pi*d0/v20
00178         v0=.004*sqrt(2.*e0)
00179 
00180 c       Assign positions and velocities. Note that it may actually
00181 c       be preferable to do this in layers instead.
00182 
00183 c       Note also that rcore is taken to be unity.
00184 
00185         do 100 i=1,n
00186             call posvel(xx,yy,zz,uu,vv,ww)
00187             x(i,1)=xx
00188             x(i,2)=yy
00189             x(i,3)=zz
00190             xdot(i,1)=uu
00191             xdot(i,2)=vv
00192             xdot(i,3)=ww
00193 100     continue
00194 
00195         end
00196         
00197         
00198         subroutine posvel(x,y,z,vx,vy,vz)
00199 
00200         implicit real*8 (a-h,o-z)
00201 
00202         parameter (nm=2500)
00203         common/profile/xx(0:nm),d(0:nm),v2(0:nm),psi(0:nm),
00204      &          zm(0:nm),indx(0:100)
00205 
00206         common/kpars1/w0,v0,e0,pi,twopi
00207         common/kpars2/nprof
00208         common/therm/g(0:1000)
00209 
00210         dimension v33(0:1000)
00211         real*8 random,r
00212         data v33(1000)/0./
00213 
00214         if (v33(1000).eq.0.) then
00215             do 5 i=0,1000
00216                v33(i)=(.004*i)**3/3.
00217 5           continue
00218         end if
00219 
00220 c       Choose radius randomly from the mass distribution.
00221 
00222         r=random(0)
00223         i=100*r
00224         do 10 i1=indx(i),indx(i+1)+1
00225             if (zm(i1).gt.r) go to 15
00226 10      continue
00227 
00228         write(6,*)' **** ERROR in king.'
00229         stop
00230 
00231 15      rfac=(r-zm(i1-1))/(zm(i1)-zm(i1-1))
00232         r=xx(i1-1)+rfac*(xx(i1)-xx(i1-1))
00233 
00234 c       Angular position random.
00235 
00236         cth=2.*random(0)-1.
00237         sth=sqrt(1.-cth**2)
00238         ph=twopi*random(0)
00239         cph=cos(ph)
00240         sph=sin(ph)
00241         x=r*sth*cph
00242         y=r*sth*sph
00243         z=r*cth
00244 
00245 c       Choose speed randomly from the distribution at this radius.
00246 
00247         p=-(psi(i1-1)+rfac*(psi(i1)-psi(i1-1)))
00248         pfac=exp(p)
00249         il=0
00250         rl=0.
00251         iu=250.*sqrt(p)
00252         ru=pfac*g(iu)-v33(iu)
00253         r=random(0)*ru
00254 100     if (iu-il.gt.1) then
00255             im=(il+iu)/2
00256             rm=pfac*g(im)-v33(im)
00257             if (rm.gt.r) then
00258                 iu=im
00259                 ru=rm
00260             else
00261                 il=im
00262                 rl=rm
00263             end if
00264             go to 100
00265         end if
00266         v=v0*(il+(r-rl)/(ru-rl))
00267 
00268 c       Direction is random.
00269 
00270         cth=2.*random(0)-1.
00271         sth=sqrt(1.-cth**2)
00272         ph=twopi*random(0)
00273         cph=cos(ph)
00274         sph=sin(ph)
00275         vx=v*sth*cph
00276         vy=v*sth*sph
00277         vz=v*cth
00278 
00279         end
00280 
00281         
00282         subroutine poisson(x,d,v2,psi,zm,nmax,w0,nprof,v20,iout)
00283 
00284 c       Self-contained 1-D (spherical) Poisson's equation solver.
00285 c       Currently knows only about King models.
00286 c
00287 c       Input:  nmax is the maximum number of points allowed
00288 c               w0 is the dimensionless central potential
00289 c               iout allows messages if nonzero
00290 c
00291 c       Output: x   is scaled radius
00292 c               d   is scaled density
00293 c               v2  is scaled velocity dispersion
00294 c               psi is potential
00295 c               zm  is cumulative mass (scaling from x, d scalings)
00296 c               nprof is the actual number of points generated
00297 c               v20 is the central velocity dispersion
00298 
00299         implicit real*8 (a-h,o-z)
00300 
00301         external rhs
00302         parameter (RLIN=.25, NLIN=100, RMAX=1.e4, TOL=1.e-6)
00303 
00304         dimension x(0:nmax),d(0:nmax),v2(0:nmax),psi(0:nmax),
00305      &            zm(0:nmax),y(2)
00306 
00307         common/center/di
00308 
00309         parameter (four3=1.333333333333333, fourpi=12.5663706)
00310 
00311         psi0=-abs(w0)
00312 
00313 c       Initialize at center of cluster.
00314 
00315         xn=0.
00316         y(1)=0.
00317         y(2)=psi0
00318         x(0)=0.
00319         psi(0)=psi0
00320         v2(0)=1.
00321         call densvel(psi0,di,v2(0))
00322         d(0)=di
00323         di=1./di
00324         zm(0)=0.
00325         fac=10.**(log10(RMAX/RLIN)/(NMAX-NLIN))
00326 
00327 c       Equation to be solved is
00328 c
00329 c               (x psi)''  = 9 x d
00330 c
00331 c       by defining y(1) = (x psi)
00332 c                   y(2) = y(1)'
00333 c
00334 c       Cover the first RLIN core radii linearly with NLIN points;
00335 c       the remaining coverage is logarithmic, out to RMAX core radii,
00336 c       if necessary.  Stop when d <= 0.
00337 
00338         do 1000 i=1,nmax
00339             xo=xn
00340             if (i.le.NLIN) then
00341                 xn=(RLIN*i)/NLIN
00342             else
00343                 xn=fac*xo
00344             end if
00345             call rkode(y,2,xo,xn,TOL,.1*(xn-xo),.0001*(xn-xo),
00346      &              nok,nbad,rhs,ier)
00347 c           
00348 c           N.B. Remember that y(1) is x*psi
00349 c           
00350             if (ier.ne.0) then
00351                 if (iout.ne.0)write(6,100)ier
00352 100             format(1x,'ERROR #',i3,' IN RKODE')
00353                 stop
00354             end if
00355             x(i)=xn
00356             psi(i)=y(1)/xn
00357             v2(i)=1.
00358             call densvel(psi(i),d(i),v2(i))
00359             if (d(i).lt.0.) then
00360                 x(i)=x(i-1)+(x(i)-x(i-1))/(1.-d(i)/d(i-1))
00361                 d(i)=0.
00362                 v2(i)=0.
00363             end if
00364             zm(i)=x(i)*y(2)-y(1)
00365             if (d(i).le.0.) go to 2000
00366 1000    continue
00367         i=nmax
00368 2000    nprof=i
00369         v20=v2(0)
00370         do 2500 i=nprof,0,-1
00371             d(i)=d(i)/d(0)
00372             v2(i)=v2(i)/v2(0)
00373             zm(i)=fourpi/9.*zm(i)
00374 2500    continue
00375 
00376 99999   return
00377         end
00378 
00379 c
00380         subroutine rhs(x,y,ypr)
00381 
00382 c       Define RHS of ODE, for use by rkode.
00383 
00384         implicit real*8 (a-h,o-z)
00385 
00386         dimension y(2),ypr(2)
00387         common/center/di
00388         data zero/0./
00389 
00390         ypr(1)=y(2)
00391 
00392         if (x.le.0.) then
00393             d=1.
00394         else
00395             call densvel(y(1)/x,d,zero)
00396             d=d*di
00397         end if
00398         ypr(2)=9.*x*d
00399 
00400         end
00401 
00402 
00403         subroutine densvel(psi,d,v2)
00404 
00405 c       Return scaled density d and velocity dispersion v2,
00406 c       given scaled potential psi.
00407 
00408         implicit real*8 (a-h,o-z)
00409 
00410         d=0.
00411         if (psi.ge.0.) return
00412 
00413         dw=sqrt(-psi)
00414         w=dw
00415         g4=v2
00416         call gg(w,g2,g4)
00417         ep=exp(-psi)
00418         g2e=g2*ep
00419         d=g2e+dw*psi/3.
00420         if (v2.gt.0.and.d.gt.0.) v2=2.*(g4*ep-.2*dw*psi**2)/d
00421 
00422         end
00423 
00424 
00425         subroutine gg(w,g2,g4)
00426 
00427         implicit real*8 (a-h,o-z)
00428 
00429         common/therm/g(0:1000)
00430 
00431 c       Array g contains the integral (0-->x) of y**2 exp(-y**2) dy
00432 
00433         external gaus2
00434         data eps/1.e-6/
00435 
00436         if (g(0).lt.0.) then
00437             g(0)=0.
00438             xo=0.
00439             dx=.004
00440             do 100 i=1,1000
00441                 x=xo+dx
00442                 g(i)=g(i-1)+qromb(gaus2,xo,x,eps,ntr)
00443                 xo=x
00444 100         continue
00445         end if
00446 
00447         ww=250.*w
00448         iw=ww
00449         if (iw.ge.1000) then
00450             g2=g(1000)
00451         else
00452             g2=g(iw)+(ww-iw)*(g(iw+1)-g(iw))
00453         end if
00454         if (g4.lt.0.) return
00455         w2=w*w
00456         ew=exp(-w2)
00457         wew=w*ew
00458         g4=1.5*g2-.5*w2*w*ew
00459 
00460         end
00461 
00462 
00463         function gaus2(x)
00464 
00465         implicit real*8 (a-h,o-z)
00466 
00467         gaus2=x*x*exp(-x*x)
00468 
00469         end
00470 c
00471 c=======================================================================
00472 
00473 c       Routines from "Numerical Recipes".
00474 
00475 c               qromb - Romberg function integrator
00476 c               rkode - Runge-Kutta ODE integrator
00477 
00478         function qromb(f,a,b,eps,ntrap)
00479 
00480 c       Integrate the function f from a to b using Romberg integration
00481 c       with (relative) error tolerance eps.
00482 c       |ntrap| on return is number of trapezoidal subdivisions.
00483 c       ntrap < 0 indicates an error.
00484 
00485 c       See "Numerical Recipes," Chapter 4.3
00486 
00487 
00488         implicit real*8 (a-h,o-z)
00489 
00490         parameter (one=1.,quarter=.25,zero=0.)
00491 cd      parameter (one=1.d0,quarter=.25d0,zero=0.d0)
00492         parameter (jmax=20,jmaxp=jmax+1,k=5,km=k-1)
00493         dimension s(jmaxp),h(jmaxp)
00494         external f
00495 
00496         ntrap=0
00497         h(1)=one
00498         do 10 j=1,jmax
00499             call trapzd(f,a,b,s(j),j)
00500             ntrap=j
00501             if (j.ge.k) then
00502                 call polint(h(j-km),s(j-km),k,zero,qromb,dss,ier)
00503                 if (ier.ne.0) then
00504                     ntrap=-ntrap
00505                     qromb=0.
00506                     return
00507                 end if
00508                 if (abs(dss).lt.eps*abs(qromb)) return
00509             end if
00510             s(j+1)=s(j)
00511             h(j+1)=quarter*h(j)
00512 10      continue
00513         ntrap=-1-ntrap
00514 
00515         end
00516 
00517 
00518         subroutine trapzd(f,a,b,s,n)
00519 
00520         implicit real*8 (a-h,o-z)
00521 
00522         external f
00523         parameter (half=.5)
00524         save it
00525 
00526         if (n.eq.1) then
00527             s=half*(b-a)*(f(a)+f(b))
00528             it=1
00529         else
00530             tnm=it
00531             del=(b-a)/tnm
00532             x=a+half*del
00533             sum=0.
00534             do 10 j=1,it
00535                 sum=sum+f(x)
00536                 x=x+del
00537 10          continue
00538             s=half*(s+del*sum)
00539             it=2*it
00540         end if
00541 
00542         end
00543 
00544 
00545         subroutine polint(xa,ya,n,x,y,dy,ier)
00546 
00547         implicit real*8 (a-h,o-z)
00548 
00549         parameter (nmax=10)
00550         dimension xa(n),ya(n),c(nmax),d(nmax)
00551 
00552         ns=1
00553         dif=abs(x-xa(1))
00554         do 10 i=1,n
00555             dift=abs(x-xa(i))
00556             if (dift.lt.dif) then
00557                 ns=i
00558                 dif=dift
00559             end if
00560             c(i)=ya(i)
00561             d(i)=ya(i)
00562 10      continue
00563         y=ya(ns)
00564         ns=ns-1
00565         do 20 m=1,n-1
00566             do 15 i=1,n-m
00567                 ho=xa(i)-x
00568                 hp=xa(i+m)-x
00569                 w=c(i+1)-d(i)
00570                 den=ho-hp
00571                 if (den.eq.0.) then
00572                     ier=1
00573                     return
00574                 end if
00575                 den=w/den
00576                 d(i)=hp*den
00577                 c(i)=ho*den
00578 15          continue
00579             if (2*ns.lt.n-m) then
00580                 dy=c(ns+1)
00581             else
00582                 dy=d(ns)
00583                 ns=ns-1
00584             end if
00585             y=y+dy
00586 20      continue
00587         ier=0
00588 
00589         end
00590 
00591 c
00592 c-----------------------------------------------------------------------
00593 
00594         subroutine rkode(ystart,nvar,x1,x2,eps,h1,hmin,nok,nbad,
00595      &                   derivs,ier)
00596 
00597 c       FIFTH-order Runge-Kutta integrator with adaptive step size.
00598 c       See "Numerical Recipes," Chapter 15.2
00599 c       -- Note that their common block /path/ is not used.
00600 
00601         implicit real*8 (a-h,o-z)
00602 
00603         parameter (maxstp=10000,nmax=10,two=1.,zero=0.,tiny=1.e-30)
00604         dimension ystart(nvar),yscal(nmax),y(nmax),dydx(nmax)
00605         external derivs
00606 
00607         ier=0
00608         x=x1
00609         h=sign(h1,x2-x1)
00610         nok=0
00611         nbad=0
00612         kount=0
00613 
00614         do 10 i=1,nvar
00615             y(i)=ystart(i)
00616 10      continue
00617 
00618         do 50 nstp=1,maxstp
00619             call derivs(x,y,dydx)
00620             do 20 i=1,nvar
00621                 yscal(i)=abs(y(i))+abs(h*dydx(i))+tiny
00622 20          continue
00623             if ((x+h-x2)*(x+h-x1).gt.zero)h=x2-x
00624             if (x+h.eq.x) go to 39
00625             call rk(y,dydx,nvar,x,h,eps,yscal,hdid,hnext,derivs,ier)
00626             if (ier.ne.0) go to 9999
00627             if (hdid.eq.h) then
00628                 nok=nok+1
00629             else
00630                 nbad=nbad+1
00631             end if
00632             if ((x-x2)*(x2-x1).lt.zero) go to 45
00633 39          do 40 i=1,nvar
00634                 ystart(i)=y(i)
00635 40          continue
00636             return
00637 45          if (abs(hnext).lt.hmin) go to 99999
00638             h=hnext
00639 50      continue
00640 
00641 9999    ier=ier+1
00642 99999   ier=ier+1
00643 
00644         end
00645 
00646 
00647         subroutine rk(y,dydx,n,x,htry,eps,yscal,
00648      &                hdid,hnext,derivs,ier)
00649 
00650         implicit real*8 (a-h,o-z)
00651 
00652         parameter (nmax=10,pgrow=-.2,pshrink=-.25,fcor=1./15.,
00653      &          one=1.,safety=.9,errcon=6.e-4)
00654         external derivs
00655         dimension y(n),dydx(n),yscal(n),ytemp(nmax),ysav(nmax),
00656      &            dysav(nmax)
00657 
00658         ier=0
00659         xsav=x
00660         do 10 i=1,n
00661             ysav(i)=y(i)
00662             dysav(i)=dydx(i)
00663 10      continue
00664         h=htry
00665 1       hh=.5*h
00666         call rk4(ysav,dysav,n,xsav,hh,ytemp,derivs)
00667         x=xsav+hh
00668         call derivs(x,ytemp,dydx)
00669         call rk4(ytemp,dydx,n,x,hh,y,derivs)
00670         x=xsav+h
00671         if (x.eq.xsav) go to 99999
00672         call rk4(ysav,dysav,n,xsav,h,ytemp,derivs)
00673         errmax=0.
00674         do 20 i=1,n
00675             ytemp(i)=y(i)-ytemp(i)
00676             errmax=max(errmax,abs(ytemp(i)/yscal(i)))
00677 20      continue
00678         errmax=errmax/eps
00679         if (errmax.gt.one) then
00680             h=safety*h*(errmax**pshrink)
00681             go to 1
00682         else
00683             hdid=h
00684             if (errmax.gt.errcon) then
00685                 hnext=safety*h*(errmax**pgrow)
00686             else
00687                 hnext=4.*h
00688             end if
00689         end if
00690         do 30 i=1,n
00691             y(i)=y(i)+ytemp(i)*fcor
00692 30      continue
00693         return
00694 
00695 99999   ier=1
00696 
00697         end
00698 
00699 
00700         subroutine rk4(y,dydx,n,x,h,yout,derivs)
00701 
00702         implicit real*8 (a-h,o-z)
00703 
00704         parameter (nmax=10)
00705         dimension y(n),dydx(n),yout(n),yt(nmax),dyt(nmax),dym(nmax)
00706         external derivs
00707 
00708         hh=.5*h
00709         h6=h/6.
00710         xh=x+hh
00711         do 10 i=1,n
00712             yt(i)=y(i)+hh*dydx(i)
00713 10      continue
00714         call derivs(xh,yt,dyt)
00715         do 20 i=1,n
00716             yt(i)=y(i)+hh*dyt(i)
00717 20      continue
00718         call derivs(xh,yt,dym)
00719         do 30 i=1,n
00720             yt(i)=y(i)+h*dym(i)
00721             dym(i)=dyt(i)+dym(i)
00722 30      continue
00723         call derivs(x+h,yt,dyt)
00724         do 40 i=1,n
00725             yout(i)=y(i)+h6*(dydx(i)+dyt(i)+2.*dym(i))
00726 40      continue
00727 
00728         end
00729 
00730 c
00731 c=======================================================================
00732 
00733 c     Don't need to define random or anything below this line if a
00734 c     built-in exists...
00735 
00736       function random(iseed)
00737 
00738 c     Return a random number in the range [0,1), using the congruential
00739 c     random number generator CONGRNO below.
00740 
00741 c     Convention:  iseed = 0 ==> return next number in the sqruence.
00742 c                  iseed > 0 ==> initialize the random generator.
00743 
00744       implicit real*8 (a-h, o-z)
00745       real*8 random
00746       real*8 congrno
00747 
00748       save irset
00749       data irset/0/
00750 
00751       if (irset.eq.0.or.iseed.gt.0) then
00752 
00753 c         No system built-in random number generator is known:
00754 
00755           dum = congrno(iseed)
00756 
00757           irset = 1
00758       end if
00759 
00760 c     Return the next random number in the sequence.
00761 
00762       random = congrno(0)
00763 
00764       end
00765 
00766 
00767       function congrno(iseed)
00768 
00769 c     Random number generator (Press et al. p. 195).
00770 c     ---------------------------------------------
00771 
00772       implicit real*8 (a-h,o-z)
00773       real*8 congrno
00774 
00775       parameter (M=714025, IA=1366, IC=150889, RM=1.d0/M)
00776 
00777       integer ir(97) 
00778       save iy,iff,ir,idum
00779       data iff /0/
00780 
00781       if (iseed.lt.0.or.iff.eq.0) then
00782           idum = -abs(iseed)
00783           iff = 1
00784           idum = mod(IC-idum,M)
00785           do 11 j = 1,97
00786               idum = mod(IA*idum+IC,M)
00787               ir(j) = idum
00788 11        continue
00789           idum = mod(IA*idum+IC,M)
00790           iy = idum
00791       end if
00792 
00793       j = 1 + (97*iy)/m
00794       if (j.gt.97.or.j.lt.1) write (6,12) j, idum
00795 12    format (/' RAN2:  j, idum = ',2i12)
00796 
00797       iy = ir(j)
00798       congrno = iy*RM
00799       idum = mod(IA*idum+IC,M)
00800       ir(j) = idum
00801 
00802       end 

Generated at Sun Feb 24 09:57:05 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001