#### Scattering: important but challenging
#### Computation: breaking down the barrier
def numerov(q, u, n, x, h): # Numerov integrator for u''+q(x)u=0
nodes, c = 0, h*h/12. # given [u_0,u_1], return [u_0,u_1,...,u_{n+1}]
f0, f1 = 0., q(x+h)
for i in range(n):
x += h
f2 = q(x+h) # Numerov method below
u.append((2*(1-5*c*f1)*u[i+1] - (1+c*f0)*u[i])/(1+c*f2))
f0, f1 = f1, f2
if (u[-1]*u[-2] < 0.0): nodes += 1
return u, nodes
# needed libraries
import scipy
if scipy.__version__[0] < '1': # sph. Bessel func changed after ver 1.0.0
from scipy.special import sph_jn, sph_yn, lpn
else:
from scipy.special import spherical_jn as sph_jn, spherical_yn as sph_yn, lpn
import matplotlib.pyplot as plt, numpy as np
#%matplotlib notebook
def V(r, Z=2.0, s=1.0): # Yukawa potential
return -Z*np.exp(-r/s)/r
def q(r): # Sch eqn in Numerov form
return 2*(E - V(r)) - L*(L+1)/(r*r)
def wf(M, xm): # find w.f. and deriv at xm
c = (h*h)/6.
wfup, nup = numerov(q, [0,.1], M, 0., h) # 1 step past xm
dup = ((1+c*q(xm+h))*wfup[-1] - (1+c*q(xm-h))*wfup[-3])/(h+h)
return wfup, dup/wfup[-2]
plt.figure()
r = np.linspace(.01, 5,100)
plt.plot(r, V(r, Z=2., s=1.0))
plt.plot(r, V(r, Z=2., s=15.0))
plt.xlabel('r (a.u.)'), plt.ylabel('V (a.u.)')
plt.ylim(-5,0);
a, M, uL = 10., 200, [] # matching point, steps
h, Lmax, E =a/M, 15, 2. # step size, max L, energy
k, ps = np.sqrt(2*E), np.zeros(Lmax+1) # wave vector, phase shift
if scipy.__version__[0] < '1':
jl, dj = sph_jn(Lmax, k*a) # (j_l, j_l') tuple
nl, dn = sph_yn(Lmax, k*a) # (n_l, n_l')
else:
Lrange = range(Lmax + 1)
jl, dj = sph_jn(Lrange, k*a, False), sph_jn(Lrange, k*a, True) # (j_l, j_l')
nl, dn = sph_yn(Lrange, k*a, False), sph_yn(Lrange, k*a, True) # (n_l, n_l')
for L in range(Lmax+1):
u, g = wf(M, a) # g= u'/u
uL.append(u)
x = np.arctan(((g*a-1)*jl[L] - k*a*dj[L])/ # phase shift
((g*a-1)*nl[L] - k*a*dn[L]))
while (x < 0.0): x += np.pi # handle jumps by pi
ps[L] = x
theta, sigma = np.linspace(0., np.pi, 100), []
cos, La = np.cos(theta), np.arange(1,2*Lmax+2,2)
for x in cos: # calc cross section
pl = lpn(Lmax, x)[0] # Legendre polynomial
fl = La*np.exp(1j*ps)*np.sin(ps)*pl # amplitude
sigma.append(np.abs(np.sum(fl))**2/(k*k))
plt.figure() # plot scaled w.f.
uL = np.array(uL)
for L in range(0, 5, 2):
plt.plot(h*np.arange(len(uL[L])), uL[L]/max(abs(uL[L])))
plt.xlabel('r (a.u.)'), plt.ylabel('$u$', fontsize=16);
plt.figure() # plot phase shift vs L
plt.plot(range(Lmax+1), ps, '-o')
plt.xlabel('$\ell$', fontsize=20), plt.ylabel(r'$\delta_\ell$', fontsize=20);
plt.figure()
plt.plot(theta*180/np.pi, sigma) # plot cross sections
xtck = [0, 30, 60, 90, 120, 150, 180]
plt.xticks(xtck, [repr(i) for i in xtck]) # custom ticks
plt.xlabel(r'$\theta$ (deg)'), plt.ylabel(r'$\sigma(\theta)$ (a.u.)'), plt.semilogy();
