Programa random walk






[nuclear] ~/for > cat all/random_walk.for
        subroutine random_walk
        REAL VARIA(23)
        real dummy(19)
        COMMON /urandom_walk/ rit, dist,  rNum, r_end, dummy
        EQUIVALENCE (VARIA,   rit)
        character*8 NAME(23)
        DATA   NAME /'rit','dist','rNum',20*' '/
        DATA VARIA/   1, 1, 10, 20*0. /
cjr     real*8 co,thetao,si,alo,beo,gao,alb,beb,gab,al,be,ga,thetap, xb,yb
        real co,thetao,si,alo,beo,gao,alb,beb,gab,al,be,ga,thetap, xb,yb
        character*80 inpLIN  ! Buffer for lines input
        data twopi /  6.2830/

C  *******************
999     imess = MESSmc( NAME,VARIA,
        1'iterate this number; -1:Description of Program',
        2'distance between collisions (any unit)',
        3'Number of displacements (in 3-dim)',
        4'Radius at the end of the 3-dim walk ',
        4 0)

        if (imess.eq.-1) return       !^Z (ctrl Z) returns
C
        if ( rit .lt. 0) then
          WRITE(*,3)
3      FORMAT(//' RANDOM_WALK: ',/
     1 ' This program was written to check subroutine DIRECT_COS,    ',/
     2 ' used in several programs such as PROTON_IMAGING.            ',/
     3 ' RANDOM_WALK deals with the isotropic random walk of an      ',/
     4 ' object (molecule) in 3-dimensions. That is, a molecule in a ',/
     5 ' gas moves equal distances D between collisions with equal   ',/
     6 ' probability in any  direction. After a total of N of such   ',/
     7 ' displacements, the mean square displacement from the ORIGEN ',/
     8 ' is  SUM(r^2)/N, and the RMS displacement is                 ',/
     9 '                             rms(r) = sqrt( SUM(r^2)/N )     ',/
     9 ' This problem can be solved analytically (see e.g. Rice, prob',/
     1 ' 1.18), and the answwer is                                   ',/
     1 '                              rms(r) = D * sqrt(N)           ',/
     1 ' So by running a Monte carlo in this program, one can test   ',/
     2 ' that the transport of the particle is done correctly, by    ',/
     3 ' generating a distribution and calculating rms(r)            ',/
     4 ' (from the ORIGEN, not from the average of the distribution).' )
          rit = 1
cjr          accept '(A)',I
          read (*,'(a)') inpLIN             !  read line

          go to 999
        end if
c pick initial phi, theta  (i.e., phio,thetao):
        Rn = random() !random number between 0 and 1
        co = 1. - 2.*Rn     !isotropic dist. in thetap
cjr     thetao = Dacos (co)
        thetao = acos (co)
cjr     si = Dsqrt(1.d0-co**2)
        si = sqrt(1.d0-co**2)
        Rn=random() !random number between 0 and 1
        phio = twopi*Rn

        alb = cos(phio)*si !init direction cosine along X-axis for unit vector
        beb = sin(phio)*si !                            Y-axis
        gab = co           !                            Z-axis
        xb  = 0
        yb  = 0
        zb  = 0

cjr     thetaf = Dacos(co) * 1000
        thetaf = acos(co) * 1000
        Number_steps = rNum
        rb = dist
        do i=1, Number_steps

c propagate along direction of unit vector k':
                xb  =  xb + alb*rb  !New position in XYZ coord system
                yb  =  yb + beb*rb
                zb  =  zb + gab*rb

c Set for iteration algorithm
                al = alb
                be = beb
                ga = gab

c pick phip, thetap (thetap is theta', phip is phi') (in system X'Y'Z', wich
c has its  Z' axis along last direction k')

                Rn=random() !random number between 0 and 1
                co = 1. - 2.*Rn   !isotropic dist in thetap for 3-d random walk
cjr             thetap = Dacos(co)
                thetap = acos(co)
                Rn=random() !random number between 0 and 1
                phip = twopi*Rn
                call direct_cos (thetap, phip, al, be, ga, 0., 0,
        1                                  alb, beb, gab)
        end do

2       continue

cjr     r_end = Dsqrt (xb**2 + yb**2 + zb**2 )
        r_end = sqrt (xb**2 + yb**2 + zb**2 )
        GO TO 999
        END !of s.r. random_walk
c*******************************************************************
        subroutine direct_cos (thetap,phip,al,be,ga,deg,iflg, alb,beb,gab)
c  iflg = 0, angles in rad;  = 1, angles in deg ( deg = 180./3.1415)
        thetapr = thetap
        phipr = phip
        if (iflg.eq.1) then  !thetap and phip in deg
                thetapr = thetap/deg    !in rad
                phipr = phip/deg        !in rad
        end if
        s = sin (thetapr)
        co = cos (phipr)
        si = sin (phipr)
        alp = co*s
        bep = si*s
        gap = cos (thetapr)
c       type *, alp,bep,gap
        den = sqrt(al*al + be*be)

c What follows depends on axis convention
c  Take  z' axis along incident unit vector k'
c  Take  x' axis along unit vector j', defined as : j' = (k x k')//k x k'/
c  Take  y' axis as a right-hand system: i' = j'x k'
c  Unit vector k is taken along Z axis in the fixed cartesian system X Y Z.

        gab = gap*ga - alp*den
        if (al.eq.0 .and. be.eq.0) then
                alb = 0
                beb = 0
                return
        end if
        alb = gap*al + (-bep*be + alp*al*ga)/den  !notice convention
        beb = gap*be + ( bep*al + alp*be*ga)/den
        return
        end  !of subroutine direct_cos

c*****************************************************************
c      This is not used. It uses an incovenient convention.
        subroutine direct_cost (thetap,phip,al,be,ga,deg,iflg,    als,bes,gas)
cjr     real*8 thetap,phip,al,be,ga,als,bes,gas, thetapr,phipr
        real thetap,phip,al,be,ga,als,bes,gas, thetapr,phipr
cjr     real*8 s, co, si, alp, bep, gap, den
        real s, co, si, alp, bep, gap, den
        thetapr = thetap
        phipr = phip
        if (iflg.eq.1) then  !thetap and phip in deg
                thetapr = thetap*deg    !in rad
                phipr = phip*deg        !in rad
        end if
cjr     s = Dsin (thetapr)
        s = sin (thetapr)
cjr     co = Dcos (phipr)
        co = cos (phipr)
cjr     si = Dsin (phipr)
        si = sin (phipr)
        alp = co*s
        bep = si*s
cjr     gap = Dcos (thetapr)
        gap = cos (thetapr)
c       type *, alp,bep,gap
cjr     den = Dsqrt(al*al + be*be)
        den = sqrt(al*al + be*be)

c What follows depends on axis convention
c  Take  z' axis along incident unit vector k'
c  Take  x' axis along unit vector i', defined as : i' = (k'x k)//k'x k/
c  Take  y' axis as a right-hand system: j' = k'x i'
c  Unit vector k is taken along Z axis in the fixed cartesian system X Y Z.

        gas = gap*ga - bep*den
        if (al.eq.0 .and. be.eq.0) then
                als = 0
                bes = 0
                return
        end if
        als = gap*al + (alp*be + bep*al*ga)/den  !notice convention
        bes = gap*be + (-alp*al + bep*be*ga)/den
        return
        end  !of subroutine direct_cost
C---------------------------------------------------------------------------