Obligatorisk øving i TFY4215 april 2018¶

Løsningsforslag til oppgave 2¶

Vi starter som vanlig med å importere numpy, samt matplotlib for å lage figurer:

In [1]:
import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib import animation

Vi trenger ℏ og elektronmassen m; og bruker ganske enkelt SI-enheter:

In [2]:
hbar=1.05E-34
m=9.11E-31

Velger steglengden dx=1 Å, samt bølgepakkens senterenergi E0=1.0 eV:

In [3]:
dx=1.0E-10
E0=1.0*1.6E-19

Fra E0 beregnes tilhørende bølgetall k0, impuls p0 og hastighet v0, med en fri partikkel antagelse:

In [4]:
k0=np.sqrt(2.0*m*E0)/hbar
p0=hbar*k0
v0=p0/m

Som i oppgave 1 velger vi et område med bredde L=Ntot⋅dx mellom to harde vegger, med Ntot=1000. For å unngå at bølgepakken kommer i berøring med de harde veggene, kan vi for eksempel velge et harmonisk potensial omkring midten av "totalområdet", og "kontakter" med konstant potensial V0≫E0 på hver side. Og som i oppgave 1 konstrueres Hamilton-matrisen, med diagonalelementer Vi+ℏ2/m(dx)2 og med H(i,i±1)=−ℏ2/2m(dx)2. Egenverdier og egenvektorer til matrisen H returneres fra numpy-funksjonen linalg.eigh(H):

In [5]:
#Ntot = N*10 = totalt antall punkter langs x-aksen
N = 100
#Lager harmonisk potensial med kontakter med konstant potensial på hver side.
#Velger "kontakter" med 4*N punkter på hver side og V = V0 >> E0.
#Mellom de to "kontaktene" er potensialet harmonisk, symmetrisk og med
#minimumsverdi V = 0 i midten.
V0 = 50.0*1.6E-19
V = [V0]*4*N + [V0*((n-1.0*N)/(N*1.0))**2 for n in range(2*N+1)] + [V0]*4*N
#Gjør om listen til numpy array
V = np.asarray(V)
#Potensialet i enhet eV (i tilfelle plottebehov)
V_eV = V/1.6E-19
#d = liste med diagonalelementer i Hamiltonmatrisen H
d = [v + hbar**2/(m*dx**2) for v in V]
#e = verdi til ikke-diagonale elementer i H, dvs H(i,i+-1) = -e
e = - hbar**2/(2*m*dx**2)
#Ntot = antall elementer i V = totalt antall punkter langs x-aksen
Ntot=len(V)
#Initialisering av matrisen H: Legger inn verdi 0 i samtlige elementer
H = [[0]*(Ntot) for n in range(Ntot)]
#Dobbel for-løkke som lager den tridiagonale matrisen H
for i in range(Ntot):
    for j in range(Ntot):
        if i==j:
            H[i][j]=d[i]
        if abs(i-j)==1:
            H[i][j]=e

#Gjør om H fra liste til numpy array (muligens uten betydning?)
H = np.asarray(H)
#Finner energy = egenverdiene og psi_matrix = egenvektorene til matrisen H           
energy,psi_matrix = np.linalg.eigh(H)
#energy_eV = liste med energiegenverdier i enheten eV
energy_eV = energy/1.6E-19

Vi kan nå plotte de beregnede energiegenverdiene som funksjon av "nummer" n:

In [6]:
n_axis = [n for n in range(Ntot)]
plt.figure('Energiegenverdier')
#plt.plot(n_axis,energy_eV,'bo')
plt.plot(n_axis,energy_eV)
plt.title('Energiegenverdier',fontsize=16)
plt.xlabel('$n$',fontsize=16)
plt.ylabel('Energi (eV)',fontsize=16)
plt.show()

Vi ser at for små verdier av n har vi en lineær sammenheng mellom En og n. Dette er som forventet for en harmonisk oscillator. For E>V0 får vi en dispersjonsrelasjon lik den vi hadde i oppgave 1.

Vi lager i neste omgang starttilstanden Ψ(x,0) som en "minimum uskarphet" (normert) gaussisk bølgepakke:

Ψ(x,0)=1(2πσ2)1/4exp⁡[−(x−x0)24σ2+ik0x].
Med denne funksjonen har starttilstanden et standardavvik i posisjon lik σ, "tyngdepunktet" i posisjon x0, og en senterimpuls p0=ℏk0. I eksemplet nedenfor brukes tallverdiene σ=10dx og x0=Ntot∗dx/2, som er omtrent midt i det harmoniske potensialet:

In [7]:
#x = liste med posisjonsverdier (i enheten m)
x = np.asarray([dx*n for n in range(Ntot)])
#x_nm = liste med posisjonsverdier i enheten nanometer
x_nm = x * 1.0E9
#INITIALTILSTANDEN Psi(x,0)
#sigma = initialtilstandens standardavvik i posisjon
sigma = dx*10.0
#x0 = pakkens senterposisjon; start minst 5*sigma til høyre for x=0
x0 = Ntot*dx/2
#
#Lager starttilstanden Psi(x,0)
normfactor = (2*np.pi*sigma**2)**(-0.25)
gaussinit = np.exp(-(x-x0)**2/(4*sigma**2))
planewavefactor = np.exp(1j*k0*x)
Psi0 = normfactor*gaussinit*planewavefactor
#Plotter sannsynlighetstettheten for initialtilstanden
plt.figure('Initiell sannsynlighetstetthet')
plt.plot(x_nm,np.abs(Psi0**2))
plt.title('Initiell sannsynlighetstetthet',fontsize=16)
plt.xlabel('$x$ (nm)',fontsize=16)
plt.ylabel('$|\Psi(x,0)|^2$',fontsize=16)
plt.show()

Nå kan vi beregne utviklingskoeffisientene cn i utviklingen av Ψ(x,0) i stasjonære tilstander:

Ψ(x,0)=∑n=0N−1cnψn(x),
som betyr at
cn=∫0Lψn∗(x)Ψ(x,0)dx.

In [8]:
#Lager Psi(x,0) som lineærkombinasjon av egentilstander
#Lager utviklingskoeffisientene c[0] ... c[Ntot-1]
#Omgjør egenfunksjonene fra reelt til komplekst representerte tall
psi_matrix_complex = psi_matrix*(1.0 + 0.0j)
c = np.zeros(Ntot, dtype = np.complex128)
for n in range(Ntot):
    c[n] = np.vdot(psi_matrix_complex[:,n],Psi0)    
#Plotter |c[n]|**2
#Dette representerer på et vis impulsfordelingen i bølgepakken
n_axis = [n for n in range(Ntot)]
plt.figure('Utviklingskoeffisientene')
plt.plot(n_axis,np.abs(c)**2)
plt.title('Utviklingskoeffisientene',fontsize=16)
plt.xlabel('$n$',fontsize=16)
plt.ylabel('$|c(n)|^2$',fontsize=16)
plt.show()

Som en sjekk på at programmet fungerer som det skal, rekonstruerer vi starttilstanden med utgangspunkt i de beregnede utviklingskoeffisientene cn. Deretter plotter vi både den "originale" og den rekonstruerte sannsynlighetstettheten |Ψ(x,0)|2 i samme figur.

In [9]:
#Rekonstruerer Psi(x,0) fra utviklingskoeffisientene
Psi0rekon = np.zeros(Ntot,dtype=np.complex128)
for n in range(Ntot):
    Psi0rekon = Psi0rekon + c[n]*psi_matrix_complex[:,n]

#Plotter sannsynlighetstetthet for rekonstruert initialtilstand
plt.figure('Rekonstruert og original initialtilstand')
plt.plot(x_nm,np.abs(Psi0rekon**2),x_nm,np.abs(Psi0**2))
plt.title('Rekonstruert og original initialtilstand',fontsize=16)
plt.xlabel('$x$ (nm)',fontsize=16)
plt.ylabel('$|\Psi(x,0)|^2$',fontsize=16)
plt.show()

Fornøyd noterer vi oss at de to kurvene overlapper perfekt.

Vi må nå velge et passende tidssteg og et passende tidsintervall, beregne Ψ(x,t), og deretter tidsutviklingen av bølgepakkens standardavvik i både posisjon og impuls, dvs Δx(t) og Δp(t). Med senterenergi E0 har vi de to klassiske vendepunktene for x-verdier som oppfyller V(x)=E0. Potensialet er på formen V(x)=12mω2(x−x0)2, med x0=5Ndx, slik at vendepunktene er ved x0±2E0/mω2. Med V(x0)=0 og V(x0±Ndx)=V0 blir ω=2V0/m/Ndx, slik at svingeperioden i det harmoniske potensialet er T=2π/ω=2πNdxm/2V0. Med tallverdiene N=100, V0=50 eV og dx=1 Å er T=15 fs.

In [10]:
#Potensialet er V(x) = (1/2)m*w^2*(x-x0)^2. Området for det harmoniske potensialet
#har utstrekning 2*N*dx. Perioden blir da T = 2*pi/w = 2*pi*N*dx*sqrt(m/2*V0).
#Med tallverdiene N=100, dx=1Ã…, V0=50eV og m=elektronmassen finner vi
#T = 1.5E-14 s = 15 fs.
#Da er det rimelig å velge tidssteget med basis i perioden T, f eks som
#tidssteg = T/100.
#Med M=200 tidsverdier studerer vi dermed ca to hele svingeperioder, dvs fire
#kollisjoner med de myke veggene
#
T = 2*np.pi*N*dx*np.sqrt(m/(2*V0))
tidssteg = T/100
M = 200
xmean = np.zeros(M)
x2mean = np.zeros(M)
xmean2 = np.zeros(M)
pmean = np.zeros(M)
pmean2 = np.zeros(M)
p2mean = np.zeros(M)
norm = np.zeros(M)
halfhbar = np.zeros(M)
tid = np.zeros(M)
null = 0.0 + 0.0j
for i in range(M):
    halfhbar[i] = hbar/2
    tid[i] = i*tidssteg
    #Lager Psi(x,t) 
    Psi_t = np.zeros(Ntot,dtype=np.complex128)
    for n in range(Ntot):
        Psi_t = Psi_t + c[n]*psi_matrix_complex[:,n]*np.exp(-1j*energy[n]*tid[i]/hbar)
    
    Psi_t_conj = np.conjugate(Psi_t)
    d_Psi_t = np.append(np.diff(Psi_t)/dx, null)
    d2_Psi_t = np.append(np.diff(d_Psi_t)/dx, null) 
    rho_t = np.abs(Psi_t)**2
    norm[i] = 0.0
    for n in range(Ntot):
        norm[i] = norm[i] + rho_t[n]

    norm[i] = norm[i]*dx
    xmean[i] = dx*np.dot(x,rho_t)
    x2mean[i] = dx*np.dot(x**2,rho_t)
    xmean2[i] = xmean[i]**2
    pmean[i] = dx*hbar*np.imag(np.dot(Psi_t_conj,d_Psi_t))
    p2mean[i] = dx*hbar*hbar*np.dot(np.abs(d_Psi_t),np.abs(d_Psi_t))
    pmean2[i] = pmean[i]**2

deltax = np.sqrt(x2mean-xmean2)
deltap = np.sqrt(p2mean-pmean2)

Vi plotter utregnede størrelser som funksjon av tiden:

  • Normeringsintegralet
  • Midlere posisjon
  • Midlere impuls
  • ⟨p2⟩ og ⟨p⟩2
  • Δx(t)
  • Δp(t)
  • Δx⋅Δp
In [11]:
plt.figure('Normering')
plt.plot(tid,norm)
plt.title('Normering',fontsize=20)
plt.xlabel('$t$ (s)',fontsize=20)
plt.ylabel('Normering',fontsize=20)
plt.show()


plt.figure('Midlere posisjon')
plt.plot(tid,xmean)
plt.title('Midlere posisjon',fontsize=20)
plt.xlabel('$t$ (s)',fontsize=20)
plt.ylabel('$x$ (m)',fontsize=20)
plt.show()

plt.figure('Midlere impuls')
plt.plot(tid,pmean)
plt.title('Midlere impuls',fontsize=20)
plt.xlabel('$t$ (s)',fontsize=20)
plt.ylabel('$p$ (kg m/s)',fontsize=20)
plt.show()

plt.figure('Midlere kvadratiske impuls og middelimpuls i kvadrat')
plt.plot(tid,p2mean,tid,pmean2)
plt.title('Midlere kvadratiske impuls og middelimpuls i kvadrat',fontsize=20)
plt.xlabel('$t$ (s)',fontsize=20)
plt.ylabel('$p^2$',fontsize=20)
plt.show()


plt.figure('Standardavvik i posisjon')
plt.plot(tid,deltax)
plt.title('Standardavvik i posisjon',fontsize=20)
plt.xlabel('$t$ (s)',fontsize=20)
plt.ylabel('$\Delta x$ (m)',fontsize=20)
plt.show()

plt.figure('Standardavvik i impuls')
plt.plot(tid,deltap)
plt.title('Standardavvik i impuls',fontsize=20)
plt.xlabel('$t$ (s)',fontsize=20)
plt.ylabel('$\Delta p$ (kg m/s)',fontsize=20)
plt.show()

plt.figure('Uskarphetsprodukt')
plt.plot(tid,deltax*deltap,tid,halfhbar)
plt.title('Uskarphetsprodukt',fontsize=20)
plt.xlabel('$t$ (s)',fontsize=20)
plt.ylabel('$\Delta x \cdot \Delta p$',fontsize=20)
plt.show()

Noen kommentarer:

  • Bølgepakken holder seg normert.
  • Midlere posisjon og midlere impuls svinger harmonisk, som forventet.
  • Standardavvik i posisjon oscillerer og nÃ¥r sine minimumsverdier der bølgepakken snur.
  • Standardavvik i impuls oscillerer ogsÃ¥; her omtrent i motfase med standardavviket i posisjon.
  • Uskarphetsproduktet blir ikke mindre enn ℏ/2.