In [ ]:
import scipy.sparse as sparse
import scipy.sparse.linalg as linalg
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
# simulation constants
dt = 0.05
dx = 0.01
L = 100.0
v0 = 6.125
E = np.linspace(0.8,1.4,10)*v0
a = 2.
k_vector = np.sqrt(2*E)
transmission = np.zeros(len(k_vector))
n = np.floor(L/dx)
for i,k in enumerate(k_vector):
# two constants to simplify the expressions
c1 = 1.j * dt / (4. * dx**2) # i*hbar*dt/(4*m*dx^2)
c2 = 1.j * dt / 2. # i*dt/(2*hbar)
# generate x-coordinates and initial wave-function
x = np.linspace(0,L,n)
psi = np.exp(-0.005*(x-.25*L)**2) * np.exp(1.j*k*x)
psi /= np.sqrt(sum(abs(psi)**2*dx)) # normalize the wave function
# set a potential
v = np.zeros(n)
v[int(round((L - a)/(2*dx))):int(round((L + a)/(2*dx)))] = v0
# this barrier of width a = 56*dx = 0.56 should give a transmission of ~1/3
# E = V0 (=(k^2)/2=12.5) yields: T = 1/(1+0.5*V*a^2)
# numerically solve for the matrix equation A*psi(t+dt) = B*psi(t) where A and B are tridiagonal
A = sparse.diags(1.+2.*c1+c2*v, 0) - c1*sparse.eye(n,n,1) - c1*sparse.eye(n,n,-1)
B = sparse.diags(1.-2.*c1-c2*v, 0) + c1*sparse.eye(n,n,1) + c1*sparse.eye(n,n,-1)
# fill in for periodic boundary conditions
A = A + sparse.diags([[-c1, 0],[0, -c1]],[n-2, 2-n])
B = B + sparse.diags([[c1, 0],[0, c1]],[n-2, 2-n])
print "----calculating:",
print "E/V0 =",
print E[i]/v0,
print "----"
fig, ax = plt.subplots()
plt.vlines([(L-a)/2, (L+a)/2], 0, 2*max(abs(psi)**2))
ims = []
c = 0
c_old = 0
j = 0
while c_old<=c or c>10e-4:
c_old = c
if j%10 == 0:
im, = plt.plot(x, np.abs(psi)**2, 'b')
ims.append([im])
# use the sparse stabilized biconjugate gradient method to solve the matrix eq
[psi, garbage] = linalg.bicgstab(A, B*psi, x0=psi)
j += 1
c = sum(abs(psi[int(round((L - a)/(2*dx))):int(round((L + a)/(2*dx)))])**2)*dx
print "norm at the end: ",
print sum(abs(psi)**2)*dx
print "norm left: ",
print sum(abs(psi[0:int(round((L - a)/(2*dx)))])**2)*dx
print "norm right: ",
print sum(abs(psi[int(round((L - a)/(2*dx))):])**2)*dx
transmission[i] = sum(abs(psi[int(round((L - a)/(2*dx))):])**2)*dx/(sum(abs(psi)**2)*dx)
print "approximation Transmission: ",
print transmission[i]
im_ani = animation.ArtistAnimation(fig, ims, interval=100, repeat_delay=3000, blit=True)
plt.show()
plt.figure()
plt.plot(E/v0, transmission)
plt.show()
In [ ]: