+
Light Emission from a Finite Well: Python RootFinding
Specialized IPython/Jupyter Notebook material developed by Michael BurnsKaurin  Published May 13, 2022
DOI: 10.1119/PICUP.Exercise.qmwell
The context of these calculations is to find the width of a finite symmetric quantum well with given depth so that the photon emitted during a transition from the secondlowest level to the lowest level has a particular wavelength. A possible physical example is the design of layers of materials to create a solidstate laser.
This set of exercises (also embedded in a python notebook) introduces the students to using a python rootfinding function to solve the energy levels of a finite quantum well. The initial "guesses" are the energies of the infinite well. Then, the students tackle the full challenge of varying the well width to achieve a given photon wavelength. The exercise set is fairly scaffolded; students are not creating the entire code from scratch but are guided to learn certain aspects of python.
Subject Area  Quantum Mechanics 

Level  Beyond the First Year 
Specialized Implementation  IPython/Jupyter Notebook 
Learning Objectives 
After doing these exercises, students will be able to:
 Derive and use properties of an infinite well [Exercises 1, 2, and 3].
 Look up information and do unit conversions [Exercise 2].
 Define a function [Exercises 3, 4, and 9].
 Write code to do math calculations, including the use of math functions built into python [Exercises 2, 3, 4, 5, 7, and 9].
 Derive and use boundary conditions for a finite well [Exercise 4].
 Use a rootfinding function from a library [Exercises 5 and 10].
 Use a print function [Exercises 3, 5, 7, and 10].
 Use photon properties [Exercises 7, 8, 9, and 10].
 Interpret results from a program [Exercises 6 and 8].
 Use and change code to achieve a particular result [Exercise 8].
 Interpret an error message and modify the code appropriately [Exercise 8].
 Use python lists [Exercises 9 and 10].

These exercises are also embedded in the accompanying python notebook (also uploaded in pdf).
##Exercise 1
Consider an infinite well with walls at $ x =a $ and at $ x =+a $. (These walls are probably not at the same place as in your book.) The potential energy is zero inside the well. The wave function is zero at both walls. Show that possible wave functions inside the well are cos(*kx*) and sin(*kx*) with $k = \frac {n\pi} {2a}$ , where *n* is odd for the cosine solution and *n* is even for the sine solution. Show that the energy levels are
$$ E_n = n^2 \frac {h^2} { 8m(2a)^2} = n^2 \frac {(hc)^2} { 8mc^2(2a)^2} $$
where *h* is Planck's constant and *c* is the speed of light.
##Exercise 2
Look up the numbers missing in the code below, convert them to units of eV and nm, and insert the numbers into the code. Also put in the equation for the energy of the lowest level of the infinite well, using the defined constants.
A note about python: Anything after a **#** is a "comment", which is not code (it will not be part of the running program) but is there to help understand the program or, in this notebook, help indicate where you need to type something to complete the code.
```
V0 = 5 # depth of the well, eV
hc = # Planck's constant times speed of light, eV*nm
hbarc = # previous, divided by 2*pi, eV*nm
a = 0.5 # the side of the well is at x = a and x = +a, in nm
mc2 = # mass energy of electron, eV
num = a * math.sqrt(2*mc2)/hbarc # combining some factors in the equation
E1Inf = # fill in the energy of lowest level, infinite well,
# using the variables defined in this code cell
```
##Exercise 3
The code below shows how to define a "function" that can be "called" later to make a calculation, using numbers for the "parameter" given in parentheses. Type in the formula after **return** that will calculate the correct infinitewell energy for level *n*, using the variable *E1Inf* set up in the previous code cell. The last line tests the function.
```
def energy_infinite(n):
return # put in the calculation of the nth level, using the
# first level defined in the previous code cell
print(energy_infinite(1),energy_infinite(2))
```
##Exercise 4
For a well with two finite walls of height $V_0$, find the wavefunction outside the well. Match the values and derivatives of the wavefunction inside the well and the wave function outside the well at $x = a$ to derive an equation of the form **f** = 0 for an even wavefunction (*n* is odd) and a different equation of the same form for an odd wavefunction (*n* is even). (The other boundary would lead to the same result.)
The answers will be, where *E* is energy,
$$ \sqrt{E} \tan \left(\frac{a \sqrt{2m} \sqrt{E}}{\hbar c} \right)  \sqrt{EV_0} = 0 {.} $$
and
$$ \sqrt{E} \cot \left(\frac{a \sqrt{2m} \sqrt{E}}{\hbar c} \right) + \sqrt{EV_0} = 0 {.} $$
In the code snippet below, the functions **f** are calculated in the functions named **func_even** (for the cosine function which is an even function) and **func_odd** (for the sine function which is an odd function). In the function definitions, **x** in the parenthesis is the energy, which will be "passed" to the function by the later code that uses the function. Type the needed math (formula only, no "=") after the word "return" for each function. You will need a function from the math library that you imported in the first code cell. Again, write the math in terms of energy (called **x**).
```
def func_even(x):
return # function that equals zero for even wavefunctions (odd n)
def func_odd(x):
return # function that equals zero for odd wavefunctions (even n)
```
##Exercise 5
The next code snippet uses the infinitewell energy of the lowest level (*n* = 1) as the initial "guess" for the root of **func_even** (a cosine function in the well, e.g. the lowest level) in the rootfinding function **root**. In the root function, the first argument is the defined function whose root you are finding, and the second argument is an initial "guess". The output of the root function, given the name **result**, is a bit complicated. **result.x** contains the root, in an array, and **result.x[0]**, the first (and only) element of that array, is the desired root, in this case the energy of the lowest level of the finite well.
```
result = root(func_even,energy_infinite(1))
print(result,"\n") # for reference, you can delete this line
e1 = result.x[0]
print("for lowest level", e1, "eV\n")
```
In the next code cell, use the same basic lines but adapt them for the second level (*n*=2, odd function).
```
result = # add code here
print(result,"\n") # for reference, you can delete this line
e2 = result.x[0]
print() # put needed information inside the parenthesis
```
##Exercise 6
Make some sketches of the wavefunctions for the infinite well and for the finite well, remembering the boundary conditions. Is the wavelength inside the well larger or smaller for the finite well compared to the infinite well? What does that say about energies? Did we find the correct roots for the lowest two levels?
##Exercise 7
Find the photon wavelength for the transition between the two lowest levels by deriving the formula for photon wavelength in terms of the constant named hc and the two lowest energies e1 and e2, and enter that formula into the next cell after the **=** in the first line.
```
wavelength = # photon wavelength in terms of the energies of the lowest
# two levels and the constant hc
print("Photon wavelength is", wavelength, "nm")
```
##Exercise 8
Change the value of **a** and rerun the code cells, until you achieve a photon wavelength of 600 nm. If you get a “domain error", then you need to lower the initial “guess” since the code is trying to take the square root of a negative number (because the guess for the energy is above the top of the well).
What is the width of the well (2 *a*) that will give a photon wavelength of 600 nm?
##Exercise 9
Changing the width "by hand" to achieve a particular wavelength is tedious. The root function can actually do the job in one go by finding the roots of several equations at the same time. Two of the equations to be solved are the equation for even functions and the equation for odd functions, as before. In addition, the difference between the desired photon wavelength and the wavelength of the photon emitted for the transition must also be zero.
See the next code snippet. The function **all_funcs** now contains all three functions whose roots are needed. The argument of **all_funcs** is a python **list**, named **X**, of the initial "guesses" for the energies of the two lowest levels and *a*. These numbers get separated out in the line
```
x1,x2,d = X
```
The values of the three functions are returned by the function in the form of another python **list** consisting of square brackets enclosing the three values, separated by commas. By returning a list, this new function will allow us to find the roots of three equations at once.
Put the missing equations into the next code cell, then run it to define **all_funcs** for later use.
```
desiredWavelength = 600 # desired photon wavelength, nm
a = 0.5 # initial "guess" of needed well width, nm
# define one function that contains all three functions to be solved
def all_funcs(X): # X is a list of the initial "guesses"
# x is energy, d is halfwidth of well
x1,x2,d = X
num = d * math.sqrt(2*mc2) / hbarc # combining some factors in the equation
# set up the even function, calling it f1 for now
f1 = # enter the function
# set up the odd function, calling it f2 for now
f2 = # enter the function
# set up the function of transition wavelength minus desired wavelength
f3 = # enter the function
return [f1,f2,f3] # returns a list of the function values
```
##Exercise 10
The next code snippet will set up a list **guess** that contains the same initial guesses as before for energy of the even and odd functions, plus the original value of **a** as the initial guess for the width. Now **all_funcs** will get sent to the rootfinding function, along with the list of initial values. The rootfinding function will now find the roots of all three equations and return a list of the best values for the two energies and the width, so that all three equations are solved at once. Since **root** was sent three initial values, it returns a list **result.x** of three final values. The first value (or "element" is accessed as **result.x[0]** where 0 is the "index" of that element of the list, the second as **result.x[1]**, and so forth (python starts counting at 0).
In the next code cell, type in the proper variable names for the initial values of the two energies and the width in the list **guess**. Also type in the correct index for each **result.x** to obtain the appropriate final values of the rootfinding function, which now returns a list of the best values for the two energies and the width.
```
guess = [] # enter the three variables, separated by commas
result = root(all_funcs,guess)
print(result.x)
print("depth is",V0,"eV")
# enter the correct index between the brackets for the next three lines
print("width is",2*result.x[],"nm")
print("energies are",result.x[],"eV and",result.x[],"eV")
print("photon wavelength is",hc/(result.x[]result.x[]),"nm")
```
Download Options
Share a Variation
Did you have to edit this material to fit your needs? Share your changes by
Creating a Variation
Credits and Licensing
Michael BurnsKaurin, "Light Emission from a Finite Well: Python RootFinding," Published in the PICUP Collection, May 2022, https://doi.org/10.1119/PICUP.Exercise.qmwell.
DOI: 10.1119/PICUP.Exercise.qmwell
The instructor materials are ©2022 Michael BurnsKaurin.
The exercises are released under a Creative Commons AttributionNonCommercialShareAlike 4.0 license