University Programming Project: Modelling Quantum Mechanics
'Program to solve Schrodingers Equation for Hydrogen, plot the Probability Density wavefunctions and return Energy values for other states'
import numpy
import scipy.integrate
import matplotlib.pyplot as plt # import relevant modules
import time #This module is purely for measuring efficiency of code.
#returns input values for solving the schrodinger equation, n and l can be changed as desired.
#These are the values of the masses of an electron, proton and alpha (fine-structure) constant.
def get_input_data():
reduced_mass = 0.510998910
alpha = 7.29735257e-03
beta = 0
n = 2
l = 0
E1 = -9e-6
E3 = -1e-6
return reduced_mass, alpha, beta, n, l, E1, E3
#create schrodinger equation for hydrogen
#Reduced Radial Schrodinger Equation (hc = 1; has been assumed)
def hydrogen_se(Unl, r, l, E_nl):
SE_part = ((l*(l+1))/(r**2))-((2*reduced_mass)*(E_nl+((alpha/r))))
return (Unl[1], (SE_part)*Unl[0])
#solve schrodinger equation for hydrogen using the scipy.inegrate.odeint function
def solve_hydrogen_se(r, E_nl, l):
solve_se = [0., 1.]
return scipy.integrate.odeint(hydrogen_se, solve_se, r, args=(l, E_nl, ))
#function to calculate the number of points that pass through the x axis
def find_number_intersect_points(object_array):
num_intersect_points = 0
for i in range(len(object_array)-1):
if object_array[i]*object_array[i+1] <= 0: #if the sign changes between two points then the graph must have crossed the x axis
num_intersect_points = num_intersect_points + 1
return num_intersect_points
#Function that iterates towards the correct energy where the number of turning points is given as n-l-1
#This function needs tightening up as clear inefficiencies not looping over the arrays.
def iterate_towards_energy(E1, E3, radius, n, l):
while abs(E3-E1)> 1e-9: #condition on the accuracy of the energy values
E2 = 0.5*(E1+E3)
E123 = [E1, E2, E3]
wavefunction_E1 = solve_hydrogen_se(radius, E1, l)
wavefunction_E2 = solve_hydrogen_se(radius, E2, l)
wavefunction_E3 = solve_hydrogen_se(radius, E3, l)
t_E1 = find_number_intersect_points(wavefunction_E1[:,1])
t_E2 = find_number_intersect_points(wavefunction_E2[:,1])
t_E3 = find_number_intersect_points(wavefunction_E3[:,1])
n_E1 = find_number_intersect_points(wavefunction_E1[:,0])
n_E2 = find_number_intersect_points(wavefunction_E2[:,0])
n_E3 = find_number_intersect_points(wavefunction_E3[:,0])
while n_E1 != n_E2 != n-l-2 and t_E1 != t_E2 != n-l-1:
E3 = E2
E2 = 0.5*(E1+E3)
wavefunction_E1 = solve_hydrogen_se(radius, E1, l)
wavefunction_E2 = solve_hydrogen_se(radius, E2, l)
wavefunction_E3 = solve_hydrogen_se(radius, E3, l)
t_E1 = find_number_intersect_points(wavefunction_E1[:,1])
t_E2 = find_number_intersect_points(wavefunction_E2[:,1])
t_E3 = find_number_intersect_points(wavefunction_E3[:,1])
n_E1 = find_number_intersect_points(wavefunction_E1[:,0])
n_E2 = find_number_intersect_points(wavefunction_E2[:,0])
n_E3 = find_number_intersect_points(wavefunction_E3[:,0])
if n_E2 != n_E3 != n-l-2 or t_E2 != t_E3 != n-l-1:
E1 = E2
E2 = 0.5*(E1+E3)
return E2
if __name__ == "__main__":
start = time.time()
reduced_mass, alpha, beta, n, l, E1, E3 = get_input_data()
radius = numpy.linspace(0.1,7000,1000) #create radius limits, starting at 0 will give an undefined error if l does not = 1
Enl_hydrogen = iterate_towards_energy(E1, E3, radius, n, l) # iterate towards the correct energy using the function
hydrogen_wavefunction = solve_hydrogen_se(radius, Enl_hydrogen, l)
print "The energy of the n=2, l=1 state is", Enl_hydrogen ,"Mev" #returns the value of the energy for the 2,1 state to the user
scaling_factor = scipy.integrate.simps((abs(hydrogen_wavefunction[:,0])**2), radius) #normalises the probability density function
max_radius = radius[hydrogen_wavefunction[:,0].argmax()] # Find the value of the radius corresponding to the maximum probability density
print "The maximum probability density is at a radius of", max_radius ,"Mev^-1" # prints the value of the radius where it is greatest
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlabel("Radius (MeV^-1)")
ax.set_title("Radial Probability Density Function of Hydrogen in the n=2, l=1 state")
ax.set_ylabel("Radial Probability Density abs[Unl(r)]^2")
energy_text = 'En=',n,'l=',l,'is', Enl_hydrogen ,'MeV'
ax.text(2000, 0.0005, energy_text, style='italic', bbox={'facecolor':'blue', 'alpha':0.5, 'pad':10})
ax.plot(radius, (abs(hydrogen_wavefunction[:,0])**2)/scaling_factor)
plt.show() # plots radial probability density of the wave function in the 2,1 state
elapsed =time.time()-start
print elapsed