#!/usr/bin/env python # coding: utf-8 # # # # # Band Structures and Newton's Method # # ### Example – Quantum Mechanics #
# By Øystein Hiåsen, Henning G. Hugdal and Peter Berg #
# Last edited: April 15 2016 # # ___ # # One of the first great triumphs of quantum mechanics in applied physics was the electron band theory of solids [[1]](#rsc). The band structure arises due to the periodic potential experienced by the electrons in a solid. In the following, we will use Newton's method to calculate the band structure for the simple Dirac comb potential in one dimension. # ### Particle in a One-Dimensional Lattice # # A simple model for a particle in a periodic lattice, i.e. a crystal, is a periodic potential of delta peaks in one dimension, also known as the Dirac comb potential, # # $$ # V(x) = V_0 \sum_{j}\delta(x-ja), # $$ # # where $a$ is the distance between the delta function peaks. In order to make this seem like a more realistic model, we can imagine that the potential wraps around in a circle that includes a macroscopic amount of peaks, $N \sim 10^{23}$. This means that the wavefunction of the system has to fulfill periodic boundary conditions, # # $$ # \psi(x+Na)=\psi(x). # $$ # ### Bloch's Theorem # # Bloch's theorem [[2]](#rsc) states that for a periodic potential # # $$ # V(x + a ) = V(x) # $$ # # of period $a$, the wavefunction $\psi(x)$ satisfies # # $$ # \psi(x +a) = e^{iKa} \psi(x). # $$ # # Using periodic boundary conditions as stated above, we find # # $$ # \psi(x+Na) = e^{iNKa} \psi(x) = \psi(x). # $$ # # Hence, we must have $e^{iKNa} = 1$ which means # # $$ # K=\frac{2\pi n}{Na}, \qquad n\in \mathbb{Z}. # $$ # # For large $N$, which is the case in macroscopic materials, these values of $K$ essentially represent a continuum. # # The above implies that one only needs to find $\psi(x)$ within a single period with respect to $x$, for example $0 PRECISION): iteration += 1 assert iteration <= MAX_NEWTON_ITERATIONS, "The method has run for max iterations={}".format(MAX_NEWTON_ITERATIONS) z_new = newton_iteration(z_new, beta, y0) return z_new # This function will be used to calculate the lower bound of each of the first ten bands. # Since we know the end value of each band, it might be a good idea to begin the search from values close to, but slightly smaller than those end values. This is what the following code does, including a plot of the final band structure. # In[7]: def calculate_bands(beta=DEFAULT_BETA, num_bands=10, start_band=0): """Returns the z-values of the beginning and end of each band. The values are formatted as a 2xN matrix where N is the number of bands. """ band_numbers = np.arange(start_band, num_bands+start_band) end_points = (band_numbers+1)*pi # The known end points start_points = np.zeros(num_bands) # Initializing the array of start points previous_end_point = 0 # Loop through each band and find the start point of the band # by guessing a value close to the end point. for n in range(num_bands): band_number = band_numbers[n] end_point = end_points[n] z0 = end_point - 0.2*pi # Initial guess y0 = (-1)**(band_number) # The value of f(z) we are looking for. # Find new possible start_point possible_start_point = run_newton(z0, y0, beta) # If not between end points try a new initial guess z0 while(not (previous_end_point < possible_start_point < end_point) ): z0 -= pi*0.1 assert (z0 > previous_end_point) # Make sure the initial guess is between end points possible_start_point = run_newton(z0, y0, beta) start_points[n] = possible_start_point previous_end_point = end_point # Assert that all end points comes after the start_points assert (end_points > start_points).all(), "Not all end points are after start points" return np.array([start_points, end_points]) # Using the above function, the width of the energy bands are calculated. # In[8]: b = calculate_bands(start_band=2) print('Band widths:\n', b[1]-b[0]) # The following code will plot the energy bands for a given $\beta$. # In[9]: def plot_bands(bands, ax=None): """Plots the bands given a list of tuples containing beginning and end positions of the band.""" if ax is None: ax=plt.gca() xranges = zip(bands[0], bands[1]-bands[0]) ylim = ax.get_ylim() collection=collections.BrokenBarHCollection(xranges=xranges, yrange=ylim, facecolor='#bb9999') ax.add_collection(collection) return ax beta = DEFAULT_BETA zstop = 30 num_bands= int(zstop//pi) bands = calculate_bands(beta=beta, num_bands=num_bands) plot_f(beta=beta, zstop=zstop) plot_bands(bands) plt.ylim([-2,2]) plt.title(r"Energy bands for $\beta=$ %d " % beta); # As we see, the band widths increase with increasing $z$. Let's calculate the lowest allowed energy value: # In[10]: print(r'Lowest allowed value of z = %.4f.' % bands[0,0]) # We know that $z$ is related to $k$ by # # $$ # z=ka, # $$ # # and that $k$ is related to the energy $E$ by # # $$ # k = \frac{\sqrt{2mE}}{\hbar}. # $$ # # Setting $\hbar=m=a=1$ for simplicity, we obtain # # $$ # E = \frac{z^2}{2}. # $$ # # Hence, the lowest allowed electron energy in the crystal is $E_0 = 3.5703$. In this case $\beta=10$, which corresponds to a delta function strength $V_0=10$. Similarly, one can calculate the range of allowed energies in each band. # # It is also interesting to investigate how the band widths depend on $\beta$. # In[11]: def plot_bandwidths(betas, num_bands): """Plots the bandwidths against band_number for different betas.""" for beta in betas: bands = calculate_bands(beta, num_bands) width = bands[1,:] - bands[0,:] plt.plot(width, label=str(beta)) plt.title(r'Band widths for different values of $\beta$') plt.xlabel('Band number') plt.ylabel('Band width') plt.legend(loc=4) plot_bandwidths(betas=[5,10,20,30,40,50], num_bands=60) plt.plot([0,60],[pi, pi],':'); # We see that the width of the bands increases towards $\pi$. When the band width is equal to $\pi$, it means that the bands are in fact connected and can be regarded as one continuous band. # # ___ # # ## References: # # [1]: Hemmer, P. C. _Kvantemekanikk_. Tapir Akademisk Forlag, 2005 #
# [2]: Griffiths, D. J. _Introduction to Quantum Mechanics_. Pearson Education, 2004.