Wave Propagation on a String: FORTRAN source code for the frames

c string.f
C- 01 NOV 1997 Seth Stein
C- Modified to be more compatible with GMT
C- 02 NOV 1997 JED
C- f77 -o STRING string.f -lm -lmath
c version of istring.f: find “snapshots” of displacement u(x)
c at various times t for waves propagating on
c inhomogeneous string. normal modes solution
c following exact solution in Geller & Stein 1978
c assumes junction at alngth/2. between string of
c density rho1, stiffness c1 and density rho2, stiffness c2
c outputs successive frames to file fort.N
c needs math library subroutine zreal, so compile with -lmath
character lab(70)
dimension para(22)
dimension omega(300),asym(300)
dimension aa(300),bb(300),qq(300)
dimension u(200),x(200),xs(2),ys(2)
dimension uu(200),xx(200)
common /consts/ rho1,rho2,c1,c2,alngth
external root
pi = 3.1415927
write (6,*) ‘ synthetic seismogram for string’
c length, number of length increments
read(5,*) alngth, nlen
write (6,*) ‘ string length ‘,alngth,’number of steps’, nlen
c space step
dx=alngth/float(nlen)
write (6,*) ‘space step ‘, dx
c time step (sec), number of time steps
read(5,*) dt, ntstep, tzero
write (6,*) ‘time step ‘,dt,’number of steps’, ntstep
write (6,*) ‘time start ‘,tzero
c source position
read(5,*) xsrc
write (6,*) ‘ source at ‘,xsrc
c number of modes
read(5,*) nmode
write (6,*) ‘ number of modes ‘,nmode
c source shape term
read(5,*) tau
write (6,*) ‘ source shape term’,tau
c string constants
read(5,*) c1, rho1
read(5,*) c2, rho2
c compute acoustic impedences
aip1=c1*rho1
aip2=c2*rho2
c compute reflection & transmission coefficients
refl12=(aip1-aip2) /(aip1+aip2)
trans12=2.*aip1 /(aip1+aip2)
refl21=(aip2-aip1) /(aip1+aip2)
trans21=2.*aip2 /(aip1+aip2)
c compute tensions
ten1=c1*c1*rho1
ten2=c2*c2*rho2
c list parameters
write (6,*) ‘lhs: c, rho,impedance, tension : ‘,c1,rho1,aip1,ten1
write (6,*) ‘rhs: c, rho,impedance, tension : ‘,c2,rho2,aip2,ten2
write (6,*) ‘reflection coefficient l-r’, refl12
write (6,*) ‘transmission coefficient l-r’, trans12
write (6,*) ‘reflection coefficient r-l’, refl21
write (6,*) ‘transmission coefficient r-l’, trans21
c parameters for root searching
eps=.1
eps2=.1
eta=0.2
nsig=5
itmax=6
pi=3.141596
c set up initial guesses for eigenfrequencies
caverg=2./(1./c1 + 1./c2)
do 10 i=1,nmode
asym(i)=i*pi*caverg/alngth
omega(i)=asym(i)
10 continue
c find eigenfrequencies
write(6,*) ‘calling zreal2’
call zreal2(root,eps,eps2,eta,nsig,nmode,omega,itmax,ier)
write(6,*) ‘roots found: ier=’,ier
write(6,*) ‘mode asymptote root’
c find constants for eigenfunctions
do 20 i=1,nmode
c write(6,*) i, asym(i), omega(i)
call eigcon (omega(i),aa(i),bb(i),qq(i))
20 continue
c
nlen1=nlen+1
c loop over times
do 50 j = 1, ntstep
t=dt*j + tzero
c initialize displacement
do 15 k = 1, nlen1
15 u(k) = 0.0
c
c outer loop over modes
do 40 i = 1, nmode
c mode frequency
wn = omega(i)
dmp = (tau*wn)**2
c time dependant term
scale = exp(-dmp)*cos(wn*t)
c source position term
phis= phi (xsrc,i,wn,aa(i),bb(i),qq(i))
c compute displacement at each point
do 40 k = 1, nlen1
x(k)=(k-1)*dx
phix= phi (x(k),i,wn,aa(i),bb(i),qq(i))
40 u(k) = u(k)-phis*phix*scale

c find value to normalize u(x) values from first time step
if (j.eq.1) then
call maxmin(nlen,u,amax,amin,imax,imin)
anorm= max(abs(amax),abs(amin))*2.
write (6,*) ‘wave normalization’,anorm
endif

 

c output this frame to fort.ifile
C- First, output the left-hand side data
ifile=9+j
write(6,*) ‘frame number ‘,j,ifile
write(ifile,*) j,t
do 42 k = 1, (nlen/2)
write(ifile,*) x(k),u(k)/anorm,0.5
42 continue
close(ifile)
C- Now output the right-hand side data
ifile=109+j
write(6,*) ‘frame number ‘,j,ifile
write(ifile,*) j,t
do 43 k = (nlen/2), (nlen1-1)
write(ifile,*) x(k),u(k)/anorm,1.5
43 continue
close(ifile)

50 continue
stop
end

 

real function root (freq)
c secular equation for eigenfrequencies assuming junction at alngth/2.
common /consts/ rho1,rho2,c1,c2,alngth
oml=freq*alngth
oml1=oml/(2.*c1)
oml2=oml/(2.*c2)
ratio=rho1*c1/(rho2*c2)
root=sin(oml1)*cos(oml2) + ratio*cos(oml1)*sin(oml2)
return
end

subroutine eigcon (freq,a,b,q)
c given eigenfrequency compute constants for eigenfunctions
c assuming junction at alngth/2.
common /consts/ rho1,rho2,c1,c2,alngth
oml=freq*alngth/2.
oml1=oml/c1
oml2=oml/c2
ratio=rho1*c1/(rho2*c2)
a=sin(oml1)*sin(oml2) + ratio*cos(oml1)*cos(oml2)
b=sin(oml1)*cos(oml2) – ratio*cos(oml1)*sin(oml2)
c normalization
omll=freq*alngth
omll1=omll/c1
omll2=omll/c2
x1=alngth/4. – c1*sin(omll1)/(4.*freq)
x2=alngth *(a**2.0 + b**2.0)/4.
x3=(c2 / (4.*freq))*(b**2.0 – a**2.0)
x4=sin(2.*omll2)- sin(omll2)
x5=c2*a*b / (2.*freq)
x6=cos(2.*omll2)- cos(omll2)
q= rho1*x1 + rho2 * (x2 + x3 * (x4 – x5*x6))
c check by computing left and right displacements
ald=sin(oml1)
ard=a*sin(oml2) + b*cos(oml2)
diff=ald-ard
write(6,*) ‘a,b,left,right,difference,normalization’
write(6,*) a,b,ald,ard,diff,q
return
end

real function phi (x,i,freq,a,b,q)
c evaluate ith eigenfunction with eigenfrequency freq at point x
common /consts/ rho1,rho2,c1,c2,alngth
sq=sqrt(q)
if (x.le.alngth/2.) then
phi=sin(freq*x/c1)/sq
else
phi=(a*sin(freq*x/c2) +b*cos(freq*x/c2))/sq
endif
return
end

 

subroutine maxmin(ndat,dat,amax,amin,imax,imin)
c find max and min and their indicies
dimension dat(1)
amax=dat(1)
imax=1
amin=dat(1)
imin=1
do 10 i=2,ndat
if(dat(i).le.amax) go to 15
amax=dat(i)
imax=i
go to 10
15 if(dat(i).ge.amin) go to 10
amin=dat(i)
imin=i
10 continue
return
end