c
Index
c file runge.f
c
c Testing Runge Kutta
c
c For Time-Dependent Schroedinger Equation
c
c Including the Jacobi diagonalization
c
c Written for NORDPLUS SCHOOL March 1993
c Modified for Stockholm Course March 1995
c
c Based on standard routines used by
c Atomic Physics Group in Bergen
c
c Collected and tested by L. Kocbach
c
c (based in part on standard functions and some routines
c by e.g. J.P. Hansen, IBM Scientific Package (1972)
c etc..... )
c
c commons:
complex vc(32,32)
real akof(32,32),vv(32,32)
c
c akof(*,*) and vv(*,*) define the matrix elements
c see vcalc()
c
complex y(32)
dimension vcc(32,32)
dimension vdiag(32)
dimension trafo(32,32)
common /blockb/ trafo
common /blocka/ vcc
common /block4/ vc, akof, vv,velo ,vdiag, rr
common /block5/ itest,iout,nout
c
open(11,file='values',status='old')
open(13,file='eigenvals')
open(14,file='diagonals')
open(15,file='probabs')
open(16,file='adiaprob')
c
iout=0
read(11,*) nout
read(11,*) itest
read(11,*) velo
read(11,*) tstep
read(11,*) nstat
write(*,*) nout , ' nout '
write(*,*) itest, ' itest '
write(*,*) velo, ' velo '
write(*,*) tstep, ' tstep dt '
write(*,*) nstat, ' no of states, '
c
c Example case: exp(-a(i,j)*t*t) Read from 'values'
c
do 13 i = 1,nstat
13 read(11,*) vdiag(i)
c
do 3 i = 1,nstat
do 4 j = i,nstat
read(11,*) vv(i,j),akof(i,j)
write(*,*) vv(i,j),akof(i,j) ,' V a ',i,j
vv(j,i) = vv(i,j)
akof(j,i) = akof(i,j)
4 continue
3 continue
c
c Starting Time-loop
c
do 6 i = 1,nstat
y(i) = cmplx(0.0,0.0)
6 continue
c
y(1) = cmplx(1.0,0.0)
c
tmin=-10.0/velo
t=tmin
tmax=-tmin
c
c Adjusting the values to avoid BIG FILES
c
c allpoi all points
c prinpo printed points
c fmaxpo maximum printed
c
fmaxpo=300.0
c
allpoi=(tmax - tmin)/tstep
prinpo=allpoi/float(nout)
if(prinpo.gt.fmaxpo) nout=ifix(allpoi/fmaxpo)
c
c
c Time-loop
c
1000 continue
ttt=t
call runge(y,nstat,ttt,tstep)
call output(nstat,y,t)
t=t+tstep
if (t.lt.tmax) goto 1000
END
c
subroutine runge(y,mm,t,dt)
c -----------------------------
c
c performs Runge Kutta 4-order for LINEAR systems
c for TDSE : complex amplitudes necesssary
c
c input y(t) , output y(t+dt)
c matrix elements calculated in vcalc
c
integer mm
real t,dt
complex y(32),k1(32),k2(32),k3(32),k4(32)
complex res(32)
c commons:
complex vc(32,32)
real akof(32,32),vv(32,32)
dimension vdiag(32)
dimension trafo(32,32)
common /blockb/ trafo
common /block4/ vc, akof, vv,velo ,vdiag,rr
c
call prdkt(k1,y,dt,mm)
do 10 i = 1,mm
res(i) = y(i)+ k1(i)*0.5
10 continue
call vcalc(mm,t+0.5*dt,dt/2.0)
call prdkt(k2,res,dt,mm)
do 11 i = 1,mm
res(i) = y(i)+ k2(i)*0.5
11 continue
call prdkt(k3,res,dt,mm)
do 12 i = 1,mm
res(i) = y(i)+ k3(i)
12 continue
t = t + dt
call vcalc(mm,t,dt/2.0)
call prdkt(k4,res,dt,mm)
c
c iteration step:
c
do 20 i = 1,mm
y(i) = y(i) + k1(i)/6 + k2(i)/3 + k3(i)/3 + k4(i)/6
20 continue
end
c
subroutine prdkt(ki,y,dt,mm)
c -----------------------------
c
c returns ki = coup.matrix * y - vector * dt
c
real dt
complex ki(*),y(*)
integer mm
c commons:
complex vc(32,32)
real akof(32,32),vv(32,32)
dimension vdiag(32)
dimension trafo(32,32)
common /blockb/ trafo
common /block4/ vc, akof, vv,velo ,vdiag, rr
do 10 i = 1,mm
ki(i) = cmplx(0.,0.)
do 15 j = 1,mm
ki(i) = ki(i) + vc(i,j)*y(j)
15 continue
ki(i) = ki(i)*dt
10 continue
end
c
subroutine vcalc(nstat,t,dtx)
c -----------------------------
c
c evaluates coupling matrix and multiplies by i
c
real dtx,drx,t,tt,velo
c commons:
complex vc(32,32)
real akof(32,32),vv(32,32)
dimension vcc(32,32)
dimension vdiag(32)
dimension trafo(32,32)
common /blockb/ trafo
common /blocka/ vcc
common /block4/ vc, akof, vv,velo ,vdiag,rr
c
c Build the matrix
c
c Example case: exp(-a(i,j)*t*t)
c
tt=t+dtx
rr=velo*tt
c
do 3 i = 1,nstat
do 4 j = i,nstat
vcc(i,j) = vv(i,j)*exp(-akof(i,j)*rr*rr)
if (abs(vcc(i,j)) .lt. 0.000001)
. vcc(i,j) = 0.000001
vc(i,j) = cmplx(1.0,0.0) * vcc(i,j)
vc(j,i) = vc(i,j)
vcc(j,i) = vcc(i,j)
4 continue
vcc(i,i) = vcc(i,i) + vdiag(i)
vc(i,i) = vc(i,i) + cmplx(vdiag(i),0.0)
3 continue
c
c Multiply matrix by i
c
do 8 i = 1,nstat
do 9 j = 1,nstat
vc(i,j) = cmplx(0.0,-1.0) * vc(i,j)
9 continue
8 continue
return
end
c
subroutine output(nn,yy,tt)
c -----------------------------
c
complex yy(32)
c commons:
complex vc(32,32)
complex yadiab(32),zsum
real akof(32,32),vv(32,32), ach(32)
dimension vdiag(32)
dimension trafo(32,32)
common /blockb/ trafo
common /block4/ vc, akof, vv,velo ,vdiag, rr
common /block5/ itest,iout,nout
c
if(iout.eq.0) then
sum=0.0
do 333 k=1,nn
bach=cabs(yy(k))
ach(k) = bach*bach
sum=sum+ach(k)
333 continue
call exJaco(nn)
c
write(15,802) tt,(ach(l),l=1,nn), rr
c
1111 format('time: ',f12.5,' ........................', f12.8)
1112 format(f12.5,'... follow amps in adiabatic basis .', f12.8)
2222 format(' ',2f12.8,' ',f12.8)
4444 format(' ....... ', 2f12.8)
c
c Transforming to the adiabatic basis
c Using the trafo(*,*)
c
zsum=cmplx(0.0,0.0)
c
do 71 k=1,nn
zsum=cmplx(0.0,0.0)
do 73 ii=1,nn
zsum=zsum+trafo(k,ii)*yy(ii)
73 continue
yadiab(k)=zsum
71 continue
c
sum=0.0
do 334 k=1,nn
bach=cabs(yadiab(k))
ach(k) = bach*bach
sum=sum+ach(k)
334 continue
write(16,902) tt ,(ach(l),l=1,nn) ,rr
802 format(f10.3,' ',5f15.6)
902 format(' ',f10.3,' ',5f15.6)
endif
iout=iout+1
if (iout.eq.nout) iout=0
c
return
end
c
c
c jacob.f
c
c
subroutine exJaco(n)
c --------------------
c
c This is modified main program of the
c test of the diagonalisation routine
c
c See also jacob.f
c
c the eigenvectors from jacob are arranged
c in columns
c v1 v2 v3
c v1 v2 v3
c v1 v2 v3
c eigenvalues are returned on diagonal of a( )
c
c the matrix a is destroyed by jacob
c
c i-th vector(k) = s (k,i)
c i-th eigenvalue is a(i,i)
c...............................................
dimension vcc(32,32)
dimension a(32,32),s(32,32)
dimension akof(32,32),vv(32,32)
dimension vinter1(32,32),vinter2(32,32)
dimension v(32)
dimension vdiag(32)
complex vc(32,32)
dimension trafo(32,32)
common /blockb/ trafo
common /blocka/ vcc
common /block4/ vc, akof, vv,velo ,vdiag, rr
common /block5/ itest,iout,nout
c
c instead of entering, the matrix a(*,*)
c is obtained from vcc(*,*)
c constructed in subroutine vcalc( )
c
do 3 k=1,n
do 33 l=1,n
33 a(k,l)=vcc(k,l)
3 continue
501 format()
601 format(' matrix to be diagonalized')
602 format(' ',10f10.3)
632 format(f9.5,' ',10f9.5)
call jacob(n,a,s)
c
c trafo(*,*) is inverted s(*,*)
c
do 61 k=1,n
do 62 l=1,n
trafo(k,l)=s(l,k)
62 continue
61 continue
c
609 format(' vectors in columns ')
610 format(' eigenvalues for R= ',f9.5)
619 format('____________________________________________________')
do 300 k=1,n
300 v(k)=a(k,k)
c
c writing to file 13 ( see the filenames at open()
c ( at the beginning of main )
c
write(13,632) rr, (v(i),i=1,n)
write(14,632) rr, (vcc(i,i),i=1,n)
c
c
if(itest.eq.1) then
c
c test of diagonals - (itest==1)
c
do 71 k=1,n
do 72 l=1,n
suma=0.0
do 73 ii=1,n
suma=suma+vcc(k,ii)*s(ii,l)
73 continue
vinter1(k,l)=suma
72 continue
71 continue
do 91 k=1,n
do 92 l=1,n
suma=0.0
do 93 ii=1,n
suma=suma+s(ii,k)*vinter1(ii,l)
93 continue
vinter2(k,l)=suma
92 continue
91 continue
endif
c
return
end
c
c This is the diagonalisation routine
c
c See also jacob.f
c
subroutine jacob(nn,a,s)
c -------------------------
c
c
integer p,q,flag
real nu,nuf
dimension a(32,32),s(32,32)
n=iabs(nn)
if(nn) 4,18,1
1 do 3 i=1,n
do 2 k=1,n
2 s(i,k)=0.0
3 s(i,i)=1.0
4 flag=0
if(n-1) 41,18,41
41 z=0.
do 5 q=2,n
m=q-1
do 5 p=1,m
5 z=z+a(p,q)*a(p,q)
nu=1.414*sqrt(z)
z=nu/float(n)
if(z-1.e-27) 18,18,6
6 nuf=z*1.0e-10
7 nu=nu/float(n)
8 do 15 q=2,n
m=q-1
do 15 p=1,m
if(abs(a(p,q))-nu) 15,9,9
9 flag=1
z=0.5*(a(p,p)-a(q,q))
zz=-a(p,q)
sn=sign(1.,z*zz)
zz=zz*zz/(zz*zz+z*z)
z=sqrt(zz)
sn=sn*z/sqrt(2.*(1.+sqrt(1.-zz)))
snsq=sn*sn
cssq=1.0-snsq
cs=sqrt(cssq)
sncs=sn*cs
do 14 i=1,n
if((i-p)*(i-q)) 11,12,11
11 ipr=min0(i,p)
ipc=max0(i,p)
iqr=min0(i,q)
iqc=max0(i,q)
z=a(ipr,ipc)
zz=a(iqr,iqc)
a(ipr,ipc)=z*cs-zz*sn
a(iqr,iqc)=z*sn+zz*cs
12 if(nn) 14,18,13
13 z=s(i,p)
zz=s(i,q)
s(i,p)=z*cs-zz*sn
s(i,q)=z*sn+zz*cs
14 continue
z=a(p,p)
zz=a(q,q)
a(p,p)=z*cssq+zz*snsq-2.0*a(p,q)*sncs
a(q,q)=z+zz-a(p,p)
a(p,q)=(z-zz)*sncs+a(p,q)*(cssq-snsq)
15 continue
if(flag) 18,17,16
16 flag=0
go to 8
17 if(nuf-nu) 7,18,18
18 return
end