From Atoms to DevicesNanoelectronic modeling, lecture by lecture

Lecture 9

Nano-scaled electronic states — the particle in a box revisited

In the lecture

  • The fifteen-well structure whose transmission produced four bands, looked at as one box: a continuum box (infinitely many states on a parabola) against a discrete box of fifteen "atoms" (fifteen states per band).
  • The states of the first band, one by one: each is an envelope (s-, p-, d-, f-like, as in the textbook box) times an s-like state in every well.
  • The surprise at the top of the band: state 15 has the same envelope as state 1, but its well states are antibonding; bottom and top states form bonding/antibonding pairs, and the middle of the band is mixed.
  • Electrons at the bottom of a band (bonding), holes at the top (antibonding): why the textbooks say the conduction band is bonding and the valence band antibonding.
  • The ground state of every band has an s-like envelope; only the basis (s, p, d, f) changes from band to band. These basis states are the Bloch states, and they come from the atoms, not from periodic boundary conditions.

In this notebook

you compute the 60 states of the lecture's box (fifteen 10 nm GaAs wells between 2 nm, 0.7 eV barriers, m* = 0.067 m₀) with open-nemo, and read off what the slides show: envelopes and well amplitudes, the symmetry between states j and 16 − j, the bonding character of every state, the masses of electrons and holes from the band's cosine, the projection of each state on the single-well basis states (a 15-site tight-binding chain per band), and how many wells it takes for the band of the infinite crystal to appear.

This lecture has no transcript; the narrative follows the slides.

Run the notebookEvery number and figure on this page comes from it. Change it, rerun it, take it further.
Run it on your own machine

The notebook needs open-nemo (Python ≥ 3.10 and a C++20 compiler; BLAS/LAPACK).

git clone https://github.com/denphi/open-nemo.git && cd open-nemo
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[notebooks]"
jupyter lab From_Atoms_to_Devices/04_nanoscale_electronic_states/09_0_particle_in_a_box_revisited.ipynb
Code47 lines · cell 1
import numpy as np
import matplotlib.pyplot as plt
import opennemo as nemo
from opennemo.visualization import style

style.use(notebook=True)
EMM = nemo.structures.materials.EffectiveMassMaterial
H2M0 = nemo.core.units.HBAR2_2M0              # ħ²/2m₀ in eV nm²
M, V0, DX = 0.067, 0.7, 0.1                    # mass (m₀), barrier height (eV), grid spacing (nm)
WELL, BAR, LEAD, NW = 10.0, 2.0, 10.0, 15      # well and barrier width, lead length (nm); number of wells
OUTER = 8.0                                    # outer barriers of the closed box (nm)
D = WELL + BAR                                 # period (nm)
NAMES = "spdf"
gaas, barrier = EMM("GaAs", M, 12.9), EMM("barrier", M, 12.9, conduction_band_edge=V0)


def stack(nwells, filled=(), outer=OUTER):
    # outer barrier, nwells × (well, 2 nm barrier) with the last barrier `outer` wide;
    # the wells listed in `filled` (0-based) are barrier material
    out = [nemo.Layer(barrier, outer)]
    for m in range(nwells):
        out += [nemo.Layer(barrier if m in filled else gaas, WELL),
                nemo.Layer(barrier, outer if m == nwells - 1 else BAR)]
    return out


def closed_box(nwells, filled=(), num=None):
    # hard walls just outside the outer barriers: real states below the barrier top, unit norm
    box = nemo.Heterostructure1D(stack(nwells, filled), spacing=DX)
    sol = nemo.eigenstates(box.hamiltonian.sparse, num=num or 4 * nwells + 4)
    keep = sol["energies"] < V0
    psi = sol["vectors"][:, keep].real.T
    psi /= np.sqrt((psi**2).sum(axis=1, keepdims=True))
    for p in psi:                                      # sign: the leftmost lobe positive
        p *= np.sign(p[np.argmax(np.abs(p) > 0.5 * np.abs(p).max())])
    return box, sol["energies"][keep], psi


box, energy, psi = closed_box(NW)
x = box.x
centre = OUTER + WELL / 2 + D * np.arange(NW)          # well centres (nm)
ic = np.searchsorted(x, centre)                        # their grid indices
ib = np.searchsorted(x, centre[:-1] + D / 2)           # centres of the 14 inner barriers
well_of = [(x > c - WELL / 2) & (x < c + WELL / 2) for c in centre]
band = energy.reshape(4, NW)                           # 4 bands × 15 states
states = psi.reshape(4, NW, -1)
print(f"{box.num_sites} grid sites, {len(energy)} states below {V0} eV = 4 bands × {NW} states")
1940 grid sites, 60 states below 0.7 eV = 4 bands × 15 states

1. Forget transport: a particle in a box#

Lecture 8 ended with a promise: a new look at the particle in a box. The starting point is the structure of lecture 7, fifteen GaAs wells of 10 nm separated by sixteen barriers of 2 nm and 0.7 eV, whose transmission showed fifteen resonances near each of the four levels of a single well: four bands. The slides recall the rules learned there (one resonance per well for each quasi-bound level, the degeneracy lifted by the interaction, cosine-like bands, heavier masses in the lower bands) and the student questions that lecture 8 began to answer.

Then Klimeck asks the reader to forget that these states were computed from transport, and to look at the structure as a particle in a box: what are the states in this box? The open structure (with leads, as PCPBT computes it) and a closed box have practically the same states. In the closed box the two outer barriers are thickened to 8 nm and followed by hard walls, which isolates the fifteen wells from their surroundings; the inner wells and barriers are those of the lecture.

Code25 lines · cell 3
lead = nemo.Layer(gaas, LEAD)
dev = nemo.Heterostructure1D([lead] + stack(NW, outer=BAR) + [lead], spacing=DX)   # the lecture's structure
res = nemo.resonances(dev)
e = np.unique(np.concatenate([np.linspace(1e-3, V0 - 1e-3, 1200)]
                             + [e0 + w * np.tan(np.linspace(-1.4, 1.4, 31)) / 2
                                for e0, w in zip(res["energy"], res["width"])]))
e = e[(e > 0) & (e < V0)]
t = nemo.Transport(dev.hamiltonian).transmission(e)

fig, (a1, a2, a3) = plt.subplots(1, 3, figsize=(12, 3.9), sharey=True,
                                 gridspec_kw={"width_ratios": [1.4, 1, 0.8]})
a1.plot(dev.x, dev.band_edge, color=style.CONTEXT, lw=0.8)
a1.hlines(energy, LEAD, dev.x[-1] - LEAD, color=style.OPEN_NEMO, lw=0.5)
a1.set(xlabel="position (nm)", ylabel="energy (eV)", title="15 wells: the states of the box", ylim=(0, 0.72))
a2.semilogx(np.maximum(t, 1e-12), e, color=style.OPEN_NEMO, lw=0.8)
a2.set(xlabel="transmission T(E)", xlim=(1e-12, 3), title="transmission (open structure)")
a3.plot(np.arange(1, len(energy) + 1), energy, "o", color=style.OPEN_NEMO, ms=3)
a3.set(xlabel="state number", title="closed box")
fig.tight_layout()
print(f"{len(res['energy'])} resonances of the open structure")
diff = np.abs(energy - res["energy"]).reshape(4, NW).max(axis=1)
for n in range(4):
    print(f"band {n + 1}: {band[n, 0] * 1e3:7.2f} – {band[n, -1] * 1e3:7.2f} meV,"
          f" width {np.ptp(band[n]) * 1e3:6.2f} meV;"
          f" largest |closed box − open structure| {diff[n] * 1e3:.3f} meV")
60 resonances of the open structure
band 1:   37.30 –   42.72 meV, width   5.41 meV; largest |closed box − open structure| 0.035 meV
band 2:  147.17 –  170.49 meV, width  23.31 meV; largest |closed box − open structure| 0.115 meV
band 3:  323.44 –  382.15 meV, width  58.71 meV; largest |closed box − open structure| 0.030 meV
band 4:  556.67 –  675.51 meV, width 118.84 meV; largest |closed box − open structure| 2.026 meV
Figure computed by the notebook with open-nemo
Slide 6: the fifteen-well structure, its transmission and its four bands
Slide 6 (PCPBT): the fifteen-well structure with its resonances (left), the transmission (middle) and the resonance energies (right), forming four bands.

The 60 states of the closed box coincide with the 60 resonances to within 0.12 meV in bands 1 to 3 and 2 meV in band 4, whose states leak strongly through the thin outer barriers of the open structure (the printout). From here on the closed box is used: its states are real standing waves whose signs can be read. The four bands span 37.30–42.72, 147.17–170.49, 323.44–382.15 and 556.67–675.51 meV, each band wider than the one below, as on the slide.

2. A continuum box and a discrete box#

The textbook particle in a box of width \(L\), with infinite walls and no structure inside, has the states

\[\psi_n(x) = A\sin\frac{n\pi x}{L}, \qquad E_n = \frac{n^2\hbar^2\pi^2}{2m^*L^2},\]

infinitely many, on the continuous convex parabola \(E(k) = \hbar^2k^2/2m^*\), \(k = n\pi/L\). The density \(|\psi_n|^2 \sim \sin^2(n\pi x/L)\) has \(n\) peaks and \(n - 1\) zeros. The fifteen-well box is a different object, and the slides list the dictionary that the rest of the lecture uses:

  • a quantum well is a (simple) atom;
  • a barrier is the vacuum between the atoms;
  • each atom has its basis states (s, p, d, ...), the single-well states of lecture 8;
  • neighbouring atoms couple, which makes bonding and antibonding combinations.

Here the fifteen-well box (194 nm long with its outer barriers) is compared with a continuum box of the same length, filled with GaAs and with no barriers inside:

Code14 lines · cell 5
L = x[-1] + DX / 2
n = np.arange(1, 81)
e_cont = n**2 * H2M0 * np.pi**2 / (M * L**2)
fig, ax = plt.subplots(figsize=(7.5, 4))
ax.plot(n, e_cont, "-", color=style.CONTEXT, lw=1.5, label=f"continuum box, {L:.0f} nm: E_n ∝ n²")
ax.plot(np.arange(1, len(energy) + 1), energy, "o", color=style.OPEN_NEMO, ms=3.5,
        label="15 wells in the same box")
ax.axhline(V0, color="k", lw=0.6, ls=":")
ax.set(xlabel="state number", ylabel="energy (eV)", ylim=(0, 0.75), xlim=(0, 81),
       title="continuum box against discrete box")
ax.legend(frameon=False, fontsize=8, loc="upper left")
fig.tight_layout()
print(f"continuum box: {np.sum(e_cont < V0)} states below {V0} eV (and infinitely many above)")
print(f"15-well box:   {len(energy)} states below {V0} eV, in 4 bands of {NW}")
continuum box: 68 states below 0.7 eV (and infinitely many above)
15-well box:   60 states below 0.7 eV, in 4 bands of 15
Figure computed by the notebook with open-nemo

The continuum box puts 68 states below 0.7 eV on one parabola; the structured box puts 60 there, a similar number, but grouped into four flat staircases of exactly fifteen states, one per well, separated by gaps. Each band bends over at its top instead of rising ever faster. The slides then ask the question that organizes the lecture: what do these 60 states look like, and how do they compare with the continuum box? The plan follows the slides: (1) the states within one band (the first four, the top four, bonding and antibonding, the middle), (2) the ground state of each band, (3) the first three states of each band, and (4) what this says about Bloch states.

3. The first four states of the first band#

The slides draw ψ of the states of band 1 with the barriers in grey, marking with a dot the peak in each well and the value in each barrier. Every well holds one peak and no zero: an s-like state in each "atom". Over the fifteen wells the peak heights follow a smooth curve, the envelope, and that envelope is the continuum box's state: one peak and no zero for state 1, two peaks and one zero for state 2, three for state 3 and four for state 4 — s-, p-, d- and f-like envelopes.

For fifteen identical wells coupled to their neighbours only, the envelope is the standing wave of a chain of fifteen sites with hard ends: well \(m\) carries the amplitude

\[c_m^{(j)} \propto \sin\frac{j\pi m}{N + 1}, \qquad m = 1 \ldots N, \quad N = 15.\]

The code takes the value of ψ at the centre of each well as its amplitude \(c_m\) and compares it with this formula.

Code43 lines · cell 7
def envelope(j, nwells=NW):
    s = np.sin(j * np.pi * np.arange(1, nwells + 1) / (nwells + 1))
    return s / np.linalg.norm(s)


def amplitudes(p):
    # ψ at the well centres, sign chosen to make the first well positive, unit norm
    c = p[ic] * np.sign(p[ic][0])
    return c / np.linalg.norm(c)


def shade_barriers(a):
    inner = [(c + WELL / 2, c + WELL / 2 + BAR) for c in centre[:-1]]
    for lo, hi in [(0, OUTER), (x[-1] - OUTER, x[-1])] + inner:
        a.axvspan(lo, hi, color=style.CONTEXT, alpha=0.25, lw=0)


def draw_state(a, p, label, env=None):
    p = p * np.sign(p[ic][0]) / np.abs(p).max()
    a.plot(x, p, color=style.OPEN_NEMO, lw=0.9)
    a.plot(centre, p[ic], "s", color=style.sweep(3)[0], ms=3)
    a.plot(x[ib], p[ib], "s", color=style.sweep(3)[2], ms=3)
    if env is not None:
        a.plot(centre, env * p[ic].max() / np.abs(env).max(), "k--", lw=0.8)
    shade_barriers(a)
    a.axhline(0, color="k", lw=0.4)
    a.set(yticks=[], xlim=(0, x[-1]))
    a.set_ylabel(label, fontsize=8)
    a.grid(False)


fig, axes = plt.subplots(4, 1, figsize=(11, 5.6), sharex=True)
print("state  envelope match |c · sin(jπm/16)|   peaks in the envelope")
for j, a in zip(range(4, 0, -1), axes):
    c = amplitudes(states[0, j - 1])
    draw_state(a, states[0, j - 1], f"#{j}, {band[0, j - 1] * 1e3:.2f} meV", envelope(j))
for j in range(1, 5):
    c = amplitudes(states[0, j - 1])
    peaks = int(np.sum(np.diff(np.sign(c)) != 0)) + 1
    print(f"#{j}          {abs(c @ envelope(j)):.5f}                       {peaks}")
axes[-1].set_xlabel("position (nm)")
axes[0].set_title("band 1, states 1–4: ψ (line), well peaks and barrier values (squares), envelope (dashed)")
fig.tight_layout()
state  envelope match |c · sin(jπm/16)|   peaks in the envelope
#1          0.99995                       1
#2          0.99984                       2
#3          0.99968                       3
#4          0.99949                       4
Figure computed by the notebook with open-nemo
Slide 19: the first four states of the first band
Slide 19: the first four states of band 1. Each well holds one peak (an s-like basis state); the envelope has 1, 2, 3 and 4 peaks.

The well amplitudes follow \(\sin(j\pi m/16)\) with overlaps of 0.9995 and better. Each state is a product of two things that the continuum theory does not separate: a local, atomic-like wave function in every well, here the s-like state, and an envelope over the wells that looks like continuum theory. Klimeck calls the first band the s band. Two more observations from the slides: inside the envelope the wave function does not go to zero in the barriers (the squares in the barriers are finite, about 18 % of the neighbouring peaks for state 1, and of the same sign), so neighbouring s-like states overlap and couple strongly: in these low states the s-orbitals are bonding.

4. The top of the band: the expectation is wrong#

If the pattern continued, state 15 would have an envelope with fifteen peaks and fourteen zeros, one zero in every barrier. The slides show what the computation gives: state 15 looks like state 1, with one big envelope peak. "Our expectation on the wave function shape is wrong! Why?"

Code18 lines · cell 9
fig, axes = plt.subplots(2, 1, figsize=(11, 3.2), sharex=True)
for a, j in zip(axes, (15, 1)):
    draw_state(a, states[0, j - 1], f"#{j}, {band[0, j - 1] * 1e3:.2f} meV")
axes[-1].set_xlabel("position (nm)")
axes[0].set_title("band 1: the top state (#15) and the bottom state (#1)")
fig.tight_layout()

c1, c15 = amplitudes(states[0, 0]), amplitudes(states[0, 14])
peak = lambda p: np.array([np.max(p[w] ** 2) for w in well_of])
p1, p15 = peak(states[0, 0]), peak(states[0, 14])
print(f"well peaks of |ψ|², each scaled to its largest: largest difference #15 − #1 = "
      f"{np.abs(p15 / p15.max() - p1 / p1.max()).max():.1%}")
print("sign of ψ in the wells, #1: ", "".join("+" if v > 0 else "−" for v in c1))
print("sign of ψ in the wells, #15:", "".join("+" if v > 0 else "−" for v in c15))
for j in (1, 15):
    p = states[0, j - 1]
    print(f"#{j}: |ψ| at the barrier centres / |ψ| at the well peaks = "
          f"{np.mean(np.abs(p[ib])) / np.mean(np.abs(p[ic])):.4f}")
well peaks of |ψ|², each scaled to its largest: largest difference #15 − #1 = 2.3%
sign of ψ in the wells, #1:  +++++++++++++++
sign of ψ in the wells, #15: +−+−+−+−+−+−+−+
#1: |ψ| at the barrier centres / |ψ| at the well peaks = 0.1841
#15: |ψ| at the barrier centres / |ψ| at the well peaks = 0.0174
Figure computed by the notebook with open-nemo
Slide 27: the first and the last state of the s band
Slide 27: state 15 (top) and state 1 (bottom) of the s band. The envelopes look the same; in state 15 the wave function goes to zero in every barrier.

The well peaks of |ψ|² of state 15 and state 1, each scaled to its largest peak, differ by at most 2.3 %: the envelopes are the same. The difference is in the barriers. In state 1 all wells have the same sign and the wave function at the barrier centres is on average 18.4 % of the peaks; in state 15 neighbouring wells have opposite signs and the wave function passes through zero in each barrier (1.7 % of the peaks at the barrier centres, where the zero nearly sits). In the language of lecture 8: the lower s-orbitals are bonding, the upper s-orbitals antibonding. The fifteen-peak envelope that was expected exists, but it is the sign pattern + − + − ..., which is invisible in |ψ|² and is carried by the basis states; what remains for the envelope is the slow beat \(\sin(\pi m/16)\).

The same happens going down from the top. State 14 has the envelope of state 2, state 13 that of state 3, and in general state \(16 - j\) has the envelope of state \(j\) with alternating signs. For the chain of neighbouring wells this is exact, since \(\sin\frac{(N+1-j)\pi m}{N+1} = (-1)^{m+1}\sin\frac{j\pi m}{N+1}\):

Code8 lines · cell 11
print("pair (j, 16 − j)   well peaks of |ψ|²: largest difference"
      "   inner barriers with a sign change: j, 16 − j")
for j in range(1, 8):
    a, b = states[0, j - 1], states[0, NW - j]
    pa, pb = peak(a) / peak(a).max(), peak(b) / peak(b).max()
    flips = lambda p: int(np.sum(np.sign(p[ic][1:]) != np.sign(p[ic][:-1])))
    print(f"   ({j:2d}, {NW + 1 - j:2d})                        {np.abs(pa - pb).max():5.1%}"
          f"                           {flips(a):2d}, {flips(b):2d}")
pair (j, 16 − j)   well peaks of |ψ|²: largest difference   inner barriers with a sign change: j, 16 − j
   ( 1, 15)                         2.3%                            0, 14
   ( 2, 14)                         6.0%                            1, 13
   ( 3, 13)                         9.3%                            2, 12
   ( 4, 12)                        12.7%                            3, 11
   ( 5, 11)                        13.7%                            4, 10
   ( 6, 10)                        14.1%                            5,  9
   ( 7,  9)                        11.5%                            6,  8

The slides call it "some symmetry here": the peak amplitudes of the pairs are close to identical (within 2.3 % for the outermost pair, up to 14 % for the pairs near the centre of the band; in a chain of identical wells coupled only to their neighbours the symmetry would be exact, and the deviations measure what the chain leaves out: the coupling changes across the band and the two end wells have only one neighbour), and the bonding pattern is complementary. State \(j\) has \(j - 1\) barriers in which the sign changes (antibonding) and \(15 - j\) in which it does not (bonding); state \(16 - j\) has the opposite count. The lowest states are bonded almost everywhere, the highest antibonded almost everywhere. The envelope stays clear in states 1–4 and 12–15, becomes less obvious in states 5 and 11 and is no longer visible to the eye from state 6 to 10, where the bonding pattern is asymmetric and bonding and antibonding barriers alternate in groups.

5. The middle of the band#

"What does the center state look like?" asks the slide, marked Million Dollar Question. For state 8, the envelope formula gives \(\sin(8\pi m/16) = \sin(\pi m/2)\): 1, 0, −1, 0, 1, ... The odd wells carry the electron with alternating signs, the even wells are empty.

Code7 lines · cell 13
fig, ax = plt.subplots(figsize=(11, 1.8))
draw_state(ax, states[0, 7], f"#8, {band[0, 7] * 1e3:.2f} meV")
ax.set(xlabel="position (nm)", title="band 1, state 8: the centre of the band")
fig.tight_layout()
w8 = np.array([np.sum(states[0, 7][w] ** 2) for w in well_of])
print("weight of state 8 in each well:", np.round(w8, 3))
print(f"in the 8 odd wells: {w8[0::2].sum():.4f}, in the 7 even wells: {w8[1::2].sum():.2e}")
weight of state 8 in each well: [0.123 0.001 0.123 0.001 0.124 0.    0.124 0.    0.124 0.    0.124 0.001
 0.123 0.001 0.123]
in the 8 odd wells: 0.9861, in the 7 even wells: 4.05e-03
Figure computed by the notebook with open-nemo
Slide 50: the centre state, maximally decoupled peaks
Slide 50: state 8 has eight isolated peaks, one in every other well; the states around it show complex mixtures of bonding and antibonding features.

Practically all of the state (98.6 %) sits in the eight odd wells (0.4 % in the even ones, the rest in the barriers), with alternating signs, and the even wells between them are nearly empty: the peaks are "maximally decoupled", each separated from the next by an empty well, so that there is no net bonding or antibonding. The states around it mix the two characters.

A single number captures this. The bond order

\[B_j = \sum_{m=1}^{N-1} c_m^{(j)} c_{m+1}^{(j)}\]

(with the normalized well amplitudes \(c_m\)) is positive when neighbouring wells are mostly in phase and negative when they are mostly in antiphase. For a chain with on-site energy \(\varepsilon\) and neighbour coupling \(-\tau\) the energy of a state is \(E_j = \varepsilon - 2\tau B_j\), linear in the bond order: bonding lowers the energy, antibonding raises it.

Code14 lines · cell 15
bond = np.array([np.sum(amplitudes(p)[:-1] * amplitudes(p)[1:]) for p in states[0]])
slope, eps = np.polyfit(bond, band[0], 1)
fig, ax = plt.subplots(figsize=(6.5, 3.6))
ax.plot(bond, band[0] * 1e3, "o", color=style.OPEN_NEMO, ms=5, label="15 states of band 1")
ax.plot(bond, (eps + slope * bond) * 1e3, "-", color=style.CONTEXT, lw=1, label="E = ε − 2τ B")
for j in (1, 8, 15):
    ax.annotate(f"#{j}", (bond[j - 1], band[0, j - 1] * 1e3), textcoords="offset points",
                xytext=(6, -4), fontsize=8)
ax.set(xlabel="bond order B = Σ c_m c_m+1", ylabel="energy (meV)", title="bonding lowers, antibonding raises")
ax.legend(frameon=False, fontsize=8)
fig.tight_layout()
print(f"ε = {eps * 1e3:.2f} meV, τ = {-slope / 2 * 1e3:.3f} meV; "
      f"largest deviation from the line {np.abs(band[0] - eps - slope * bond).max() * 1e3:.3f} meV")
print("bond order of states 1, 8, 15:", np.round(bond[[0, 7, 14]], 3))
ε = 39.95 meV, τ = 1.379 meV; largest deviation from the line 0.057 meV
bond order of states 1, 8, 15: [ 0.981 -0.    -0.981]
Figure computed by the notebook with open-nemo

The fifteen energies lie on one straight line against the bond order (within 0.06 meV), with a coupling of \(\tau = 1.38\) meV between neighbouring wells. State 1 has \(B = 0.98\) (almost fully bonding), state 15 \(B = -0.98\) (almost fully antibonding), and state 8 has \(B = 0\).

6. Electrons at the bottom, holes at the top#

The slides draw the conclusion that answers one of the student questions. At the bottom of a band the states are bonded; this is where electrons sit when the band is nearly empty. At the top of a band the states are antibonded; this is where the missing electrons, the holes, sit when the band is nearly full. Hence the textbook statement: "the conduction band has bonding states, the valence bands are antibonding" — said of the states at the edges where the carriers live.

Slide 53: electrons at the bottom of the band, holes at the top
Slide 53: the lowest four states are bonding (electrons), the highest four antibonding (holes).

The band's dispersion gives the masses. The fifteen states sample the band of the infinite crystal at the wave numbers \(q_j = j\pi/((N + 1)d)\) of the standing waves of section 3, and the chain gives the cosine band

\[E(q) = \varepsilon - 2\tau\cos qd, \qquad \frac{1}{m^*} = \frac{1}{\hbar^2}\frac{d^2E}{dq^2} = \frac{2\tau d^2\cos qd}{\hbar^2}.\]

The curvature is positive at the bottom (\(q \to 0\), an electron of mass \(\hbar^2/2\tau d^2\)), negative and of the same size at the top (\(qd \to \pi\), the negative mass that makes a hole), and zero in the middle (\(qd = \pi/2\)), where the mass is infinite; the state there is the one with "no intuitive pattern". (One version of slide 50 says "zero effective mass"; the later slides correct it to infinite.)

Code18 lines · cell 17
qj = np.arange(1, NW + 1) * np.pi / ((NW + 1) * D)
A = np.column_stack([np.ones(NW), -2 * np.cos(qj * D)])
(eps_c, tau_c), *_ = np.linalg.lstsq(A, band[0], rcond=None)
m_edge = H2M0 / (tau_c * D**2)                         # ħ²/(2τd²) in units of m₀
fig, ax = plt.subplots(figsize=(6.5, 3.6))
qq = np.linspace(0, np.pi / D, 200)
ax.plot(qq * D / np.pi, (eps_c - 2 * tau_c * np.cos(qq * D)) * 1e3, color=style.CONTEXT, lw=1.2,
        label="cosine band ε − 2τ cos qd")
ax.plot(qj * D / np.pi, band[0] * 1e3, "o", color=style.OPEN_NEMO, ms=5, label="15 states at q_j")
ax.text(0.03, eps_c * 1e3 - 2.4, "electrons\n(bonding)", fontsize=8)
ax.text(0.80, eps_c * 1e3 + 1.6, "holes\n(antibonding)", fontsize=8)
ax.set(xlabel="q (π/d)", ylabel="energy (meV)", title="band 1 of the 15-well box")
ax.legend(frameon=False, fontsize=8, loc="center right")
fig.tight_layout()
print(f"ε = {eps_c * 1e3:.2f} meV, τ = {tau_c * 1e3:.3f} meV, "
      f"largest deviation from the cosine {np.abs(A @ [eps_c, tau_c] - band[0]).max() * 1e3:.3f} meV")
print(f"electron mass at the bottom: +{m_edge:.3f} m₀; hole mass at the top: −{m_edge:.3f} m₀ "
      f"(GaAs: {M} m₀)")
ε = 39.95 meV, τ = 1.379 meV, largest deviation from the cosine 0.057 meV
electron mass at the bottom: +0.192 m₀; hole mass at the top: −0.192 m₀ (GaAs: 0.067 m₀)
Figure computed by the notebook with open-nemo

The cosine fits the fifteen states to within 0.06 meV with \(\tau = 1.38\) meV, the coupling found from the bond order. An electron at the bottom of the s band has a mass of 0.192 m₀, almost three times the GaAs mass of the wells: it moves only by tunnelling through barriers that its state barely enters. At the top of the band the mass is −0.192 m₀.

7. The ground state of each band#

The slides now go across the bands. The lowest state of band 2 has, like the lowest state of band 1, an s-like envelope (one big peak over the fifteen wells in |ψ|²), but each well now holds a p-like state, two peaks and one zero. The ground state of band 3 has the d-like basis (three peaks, two zeros per well), that of band 4 the f-like one. Each band's ground state has a different basis, and the overlap between neighbouring wells grows from band to band: "Overlap gets larger!", because, as lecture 8 showed, tunnelling is stronger at higher energy.

Code22 lines · cell 19
fig, axes = plt.subplots(4, 1, figsize=(11, 5.6), sharex=True)
in_bar = box.band_edge > V0 / 2
print("band  basis   envelope match   weight in the barriers   band width (meV)"
      "   τ = width / 4 cos(π/16) (meV)")
for nb, a in zip(range(3, -1, -1), axes):
    p = states[nb, 0]
    a.plot(x, p**2 / (p**2).max(), color=style.sweep(4)[nb], lw=0.8)
    a.fill_between(x, p**2 / (p**2).max(), color=style.sweep(4)[nb], alpha=0.35, lw=0)
    shade_barriers(a)
    a.set(yticks=[], xlim=(0, x[-1]))
    a.set_ylabel(f"band {nb + 1}, #1\n{NAMES[nb]}-like basis", fontsize=8)
    a.grid(False)
for nb in range(4):
    p = states[nb, 0]
    w = np.sqrt(np.array([np.sum(p[wm] ** 2) for wm in well_of]))
    match = abs(w @ envelope(1)) / np.linalg.norm(w)
    print(f"{nb + 1:3d}    {NAMES[nb]}      {match:.5f}           {np.sum(p[in_bar] ** 2):10.1%}"
          f"             {np.ptp(band[nb]) * 1e3:8.2f}"
          f"            {np.ptp(band[nb]) / (4 * np.cos(np.pi / 16)) * 1e3:8.2f}")
axes[-1].set_xlabel("position (nm)")
axes[0].set_title("|ψ|² of the lowest state of each band")
fig.tight_layout()
band  basis   envelope match   weight in the barriers   band width (meV)   τ = width / 4 cos(π/16) (meV)
  1    s      0.99995                 1.5%                 5.41                1.38
  2    p      0.99998                 6.0%                23.31                5.94
  3    d      0.99999                13.7%                58.71               14.96
  4    f      0.99905                23.5%               118.84               30.29
Figure computed by the notebook with open-nemo

All four ground states have the same s-like envelope (the square root of the weight per well matches \(\sin(\pi m/16)\) to 0.999 or better). What changes is the state inside each well, and how much of the electron sits in the barriers: 1.5 % in band 1, 23.5 % in band 4. The band width, which for the chain is \(4\tau\cos(\pi/16)\), grows from 5.4 meV to 118.8 meV. In the language of the previous section, the coupling \(\tau\) between neighbouring wells grows from 1.38 meV in the s band to 30.3 meV in the f band.

8. The first three states of each band, and the Bloch states#

Next the slides check whether the second and third states of each band follow the pattern of band 1. They do: in every band the first state has an s-like envelope, the second a p-like and the third a d-like one; "the only difference in each band is the basis!"

Slide 71: envelopes and basis states of the first three states in each band
Slide 71: the first three states (columns) of each band (rows). The envelopes follow s, p, d in every band; each band has its own basis, s-, p-, d- or f-like.

This is a precise statement that can be tested. Let \(\phi_n(x - x_m)\) be the n-th state of well \(m\) alone (the other fourteen wells filled with barrier material). If the states of band \(n\) are built from this one basis state, every state of the band must lie in the space spanned by the fifteen translated copies \(\phi_n(x - x_m)\), \(m = 1 \ldots 15\), and the coefficients must follow the envelopes. These are the Bloch states of the lecture: the same local basis in every cell, times an envelope with a wave number. In the space of the fifteen copies, \(H\) and the overlap matrix \(S\) are 15 × 15 matrices: a one-orbital tight-binding chain whose eigenvalues should give the band.

Code15 lines · cell 21
# φ_n(x − x_m): the states of well m alone, the other fourteen wells filled with barrier material
iso = [closed_box(NW, filled=[k for k in range(NW) if k != m], num=6) for m in range(NW)]
h = box.hamiltonian.sparse.dense().real
bases = [np.array([iso[m][2][nb] for m in range(NW)]) for nb in range(4)]   # per band: 15 × sites
print("band  well level (meV)  on-site ε: end, inner well (meV)   weight in the span of the 15 copies:"
      " #1     #2     #3     #8     #15    chain: largest |E − E_exact| (meV)")
for nb, basis in enumerate(bases):
    q, _ = np.linalg.qr(basis.T)                        # orthonormal basis of their span
    weight = [np.sum((q.T @ states[nb, j]) ** 2) for j in (0, 1, 2, 7, 14)]
    hb, sb = basis @ h @ basis.T, basis @ basis.T       # the 15-site chain: H and the overlap S
    e_chain = np.sort(np.linalg.eigvals(np.linalg.solve(sb, hb)).real)
    print(f"{nb + 1:3d}     {iso[NW // 2][1][nb] * 1e3:8.2f}"
          f"        {hb[0, 0] * 1e3:8.2f} {hb[7, 7] * 1e3:8.2f}"
          f"                                    " + "  ".join(f"{w:.4f}" for w in weight)
          + f"      {np.abs(e_chain - band[nb]).max() * 1e3:8.3f}")
band  well level (meV)  on-site ε: end, inner well (meV)   weight in the span of the 15 copies: #1     #2     #3     #8     #15    chain: largest |E − E_exact| (meV)
  1        40.15           40.11    40.06                                    0.9997  0.9996  0.9994  0.9987  0.9998         0.175
  2       159.00          158.72   158.45                                    0.9993  0.9986  0.9975  0.9928  0.9992         0.354
  3       350.36          348.82   347.28                                    0.9941  0.9915  0.9876  0.9704  0.9924         2.698
  4       593.86          577.22   560.55                                    0.9427  0.9342  0.9213  0.8485  0.8816        55.484

Every state of band 1 and band 2, at the bottom, in the middle and at the top, lies in the span of the fifteen copies of one single-well state to better than 0.99, every state of band 3 to better than 0.97, and the fifteen-site chain reproduces these bands to 0.18, 0.35 and 2.7 meV (of widths 5.4, 23 and 59 meV). The on-site energies show the "crystal field": a well's level is lowered by the neighbouring wells, slightly less for the end wells, which have one neighbour. Band 4, close to the barrier top, holds only 0.85–0.94 of its weight in the span and the chain misses it by 55 meV: the isolated-well basis is weakest where the coupling is strongest, as in lecture 8. This is what the slides mean by "each band has the same basis states ⇒ Bloch states". They are not artefacts of a periodic potential or of periodic boundary conditions, since this box has neither; they represent the atomic details of the structure, its wells.

The envelopes of the first three states of every band are checked the same way, with the coefficients \(c_m\) of each state on the fifteen copies. In bands 2 and 4, whose basis states are odd, the coefficients of the lowest states alternate in sign from well to well, the mirror-image rule of lecture 8; their magnitudes follow the envelope.

Code11 lines · cell 23
print("band   |c · sin(jπm/16)| for j = 1, 2, 3     sign pattern of c for state #1")
for nb, basis in enumerate(bases):
    sb = basis @ basis.T
    row = []
    for j in range(3):
        c = np.linalg.solve(sb, basis @ states[nb, j])          # coefficients on the 15 copies
        c = c * (-1) ** np.arange(NW) if nb % 2 else c          # undo the alternation of odd bases
        row.append(abs(c @ envelope(j + 1)) / np.linalg.norm(c))
    c1 = np.linalg.solve(sb, basis @ states[nb, 0])
    print(f"{nb + 1:3d}       " + "  ".join(f"{r:.4f}" for r in row) + "          "
          + "".join("+" if v * c1[0] > 0 else "−" for v in c1))
band   |c · sin(jπm/16)| for j = 1, 2, 3     sign pattern of c for state #1
  1       0.9999  0.9998  0.9997          +++++++++++++++
  2       1.0000  0.9999  0.9998          +−+−+−+−+−+−+−+
  3       1.0000  1.0000  1.0000          +++++++++++++++
  4       0.9989  0.9968  0.9941          +−+−+−+−+−+−+−+

In every band the first three states carry the s-, p- and d-like envelopes (overlaps of 0.994 or better). The lowest state of band 1 and band 3 has all coefficients of one sign; the lowest state of band 2 and band 4 alternates, + − + − ..., which places equal lobes face to face across every barrier: it is the bonding combination of the odd p- and f-like basis states, and so it is the lowest. The |ψ|² plots of the slides show both as "one envelope peak".

9. What does all this mean?#

The final slides collect the interpretation. Here the fifteen atoms sit in a row, and together they form one new quantum well. A large number of atoms gives a band structure identical to the periodic-potential (Kronig–Penney) model; even a few atoms form dispersions with a finite number of states in each band. How many atoms does it take? The lowest band of boxes with 1 to 30 wells, against the band of the infinite crystal (its edges from the Bloch Hamiltonian of one period, at \(q = 0\) and \(q = \pi/d\)):

Code27 lines · cell 25
cell = nemo.Heterostructure1D([nemo.Layer(gaas, WELL), nemo.Layer(barrier, BAR)], spacing=DX)
hc = cell.hamiltonian.sparse.dense().real
v = np.zeros_like(hc)
v[-1, 0] = -H2M0 / (M * DX**2)                           # hopping across the cell boundary
edge = [np.linalg.eigvalsh(hc + v * np.exp(1j * q) + v.T * np.exp(-1j * q))[:2] for q in (0.0, np.pi)]
inf_band = np.sort(np.array(edge), axis=0)             # rows: min and max of bands 1 and 2

fig, ax = plt.subplots(figsize=(7.5, 3.8))
for nb in range(2):
    ax.axhspan(inf_band[0, nb] * 1e3, inf_band[1, nb] * 1e3, color=style.CONTEXT, alpha=0.2, lw=0,
               label="infinite crystal" if nb == 0 else None)
print("wells  band 1 (meV)          band 2 (meV)          band 1 width / infinite")
for nwells in (1, 2, 3, 5, 8, 15, 30):
    _, en, _ = closed_box(nwells, num=2 * nwells + 2)
    b1, b2 = en[:nwells], en[nwells:2 * nwells]
    ax.plot(np.full(nwells, nwells), b1 * 1e3, "_", color=style.OPEN_NEMO, ms=9)
    ax.plot(np.full(nwells, nwells), b2 * 1e3, "_", color=style.sweep(4)[1], ms=9)
    print(f"{nwells:4d}   {b1.min() * 1e3:7.2f} – {b1.max() * 1e3:7.2f}"
          f"     {b2.min() * 1e3:7.2f} – {b2.max() * 1e3:7.2f}"
          f"         {np.ptp(b1) / np.ptp(inf_band[:, 0]):.3f}")
ax.set(xscale="log", xlabel="number of wells", ylabel="energy (meV)", ylim=(30, 180),
       title="bands 1 and 2 as the number of wells grows")
ax.set_xticks([1, 2, 3, 5, 8, 15, 30], labels=["1", "2", "3", "5", "8", "15", "30"])
ax.legend(frameon=False, fontsize=8, loc="center right")
fig.tight_layout()
print(f"infinite crystal: band 1 {inf_band[0, 0] * 1e3:.2f} – {inf_band[1, 0] * 1e3:.2f} meV, "
      f"band 2 {inf_band[0, 1] * 1e3:.2f} – {inf_band[1, 1] * 1e3:.2f} meV")
wells  band 1 (meV)          band 2 (meV)          band 1 width / infinite
   1     40.15 –   40.15      159.00 –  159.00         0.000
   2     38.66 –   41.43      152.79 –  164.68         0.502
   3     38.06 –   41.96      150.30 –  167.09         0.708
   5     37.61 –   42.39      148.45 –  169.02         0.866
   8     37.41 –   42.60      147.63 –  169.95         0.940
  15     37.30 –   42.72      147.17 –  170.49         0.981
  30     37.27 –   42.76      147.02 –  170.67         0.995
infinite crystal: band 1 37.25 – 42.77 meV, band 2 146.96 – 170.74 meV
Figure computed by the notebook with open-nemo

Two wells already span 50 % of the infinite crystal's band width, five wells 87 %, fifteen 98 %, thirty 99.5 %: the band fills in from the inside, with exactly as many states as there are wells, and its edges approach those of the infinite crystal as \(\cos(\pi/(N + 1))\). Nothing in the finite system is periodic, yet the band structure is there.

The slides' summary, in the order of the lecture:

  • Each "particle in a box" state at the bottom of each band has an envelope like the analytic solution, s, p, d, ...; these states are all bonding: electron states.
  • The states at the top of each band have the same envelopes in reverse order; they are all antibonding: hole states.
  • The states in the middle of a band are highly mixed in their bonding and antibonding character.
  • Each band has the same basis states in every well: the Bloch states. They are not artefacts of a periodic potential; they represent the atomic details of the structure.
  • Barrier heights and widths regulate the coupling between the atoms, and the bands become wider with increasing energy because the coupling through the barriers grows.

The two systems, continuum and discrete, differ significantly, and the discrete system is much closer to reality: real devices are made of atoms, each with its own basis states. That is the answer to the question on every slide of these two lectures: why atomistic basis sets? The tight-binding lectures that follow replace the wells by atoms and the single-well states by atomic orbitals.

Summary#

  • The fifteen-well box holds 60 states below 0.7 eV, in four bands of exactly fifteen, where a continuum box of the same length has 68 on one parabola; the box states coincide with the transmission resonances.
  • Every state is a local basis state in each well (s-, p-, d- or f-like, one per band) times an envelope over the wells, \(\sin(j\pi m/16)\) for the chain of fifteen wells.
  • State 16 − j has the envelope of state j with alternating signs: the bottom states are bonding, the top states antibonding, and the energy is linear in the bond order, \(E = \varepsilon - 2\tau B\), with \(\tau = 1.38\) meV in band 1.
  • The centre state (#8) lives in every other well; the band's cosine has an inflection there (infinite mass).
  • Electrons at the bottom of a band are bonding with \(m^* = 0.192\,m_0\), holes at the top antibonding with \(-0.192\,m_0\).
  • Each band's states lie in the span of fifteen translated copies of one single-well state, and the 15-site chain reproduces the lower bands: the Bloch states are atomic, not periodic, objects (the isolated-well basis fails near the barrier top, band 4).
  • Two wells give half of the infinite crystal's band width, fifteen 98 %.

Exercises#

  1. Make the barriers 3 nm wide and recompute sections 5 and 6. How do \(\tau\) and the electron mass change, and does the energy stay linear in the bond order?
  2. Put the hard walls right behind 2 nm outer barriers (OUTER = 2.0). How much do the end wells' on-site energies of section 8 change, and what happens to the symmetry between states j and 16 − j?
  3. Change the width of the eighth well to 9 nm. Which state leaves band 1, where does it go, and what does its envelope look like?
  4. Compute the bond order of the four states closest to the middle of band 2 and of band 4, with the coefficients on the fifteen copies of section 8. Where is the bonding end of band 2?
  5. Repeat section 9 for band 4. How many wells does it take for band 4 to reach 90 % of its infinite width, compared with band 1?

Further reading#