This site is version 0.0.1. Most of the code on this site is drafted by an agent and needs review. I apologize for the AI-speak, we are working on rewriting it!
viv-lang.org

The band structure of silicon

Compute silicon's Kohn-Sham band structure along L - Gamma - X with vp.dft.pw, a plane-wave density-functional code written in Viv (dft/: LDA, GTH pseudopotentials, LOBPCG for the eigenvalues). The run converges the crystal's density self-consistently on a k-point mesh, then computes the bands at 61 points of the path. The result shows silicon's indirect gap: the valence band peaks at Gamma and the conduction band bottoms out most of the way to X.

The calculation

The si deck sets a 10 hartree plane-wave cutoff, a 4 x 4 x 4 k-mesh, the lattice constant 10.26 bohr and 8 bands. The band energies come back in eV, measured from the top of the valence band.

import numpy as np
import vipyr as vp
from vipyr.figure import figure

r = vp.dft.pw(material="si")
evb, x = np.asarray(r.evb), np.asarray(r.pathx)
print("SCF iterations: %d, last density change %.1e" % (r.iter, r.drho))
print("bands: %d path points x %d bands" % evb.shape)
iL, iG, iX = 0, len(x) // 2, len(x) - 1
for name, i in (("L", iL), ("Gamma", iG), ("X", iX)):
    print(
        "%-5s " % name
        + " ".join("%7.3f" % (e + 0.0) for e in np.round(evb[i], 3))
    )
SCF iterations: 11, last density change 4.5e-10
bands: 61 path points x 8 bands
L      -9.644  -7.020  -1.210  -1.210   1.425   3.326   3.326   7.502
Gamma -11.984   0.000   0.000   0.000   2.537   2.537   2.537   3.123
X      -7.837  -7.837  -2.877  -2.877   0.614   0.614   9.959   9.959

Bands along L - Gamma - X

Four valence bands (8 electrons in the two-atom cell) and the lowest two conduction bands. The solver carries 8 bands but converges only those it needs; the top two are left out of the plot, as they are of the check below. The conduction-band minimum is on the Gamma - X line, the valence maximum at Gamma, so the smallest gap is indirect. LDA puts it at about 0.5 eV; the measured gap is 1.17 eV, and the underestimate is the known failure of LDA for band gaps, not of the solver.

nv = 4
vbm = evb[:, :nv].max()
cb = evb[:, nv]
icb = int(np.argmin(cb))
print(
    "valence maximum %.4f eV at path point %d (Gamma)"
    % (vbm, int(np.argmax(evb[:, nv - 1])))
)
print(
    "conduction minimum %.4f eV at %.0f%% of the way from Gamma to X"
    % (cb[icb], 100 * (icb - iG) / (iX - iG))
)
print(
    "indirect gap %.4f eV, the program's gap %.4f eV; direct gap at Gamma "
    "%.4f eV" % (cb[icb] - vbm, r.gap, cb[iG] - evb[iG, nv - 1])
)

fig = figure("Silicon, LDA band structure", "", "$E - E_{\\mathrm{VBM}}$ (eV)")
for b in range(6):
    lab = "valence" if b < nv else "conduction"
    fig.plot(x, evb[:, b], lab)
fig.style("valence", "s1 nomarker")
fig.style("conduction", "s2 nomarker")
for name, i in (("L", iL), ("Gamma", iG), ("X", iX)):
    fig.xtick(name, x[i])
fig.vline("Gamma", x[iG])
fig.hline("valence maximum", 0.0)
fig.scatter([x[icb]], [cb[icb]], "conduction minimum")
fig.style("conduction minimum", "s3 ring")
valence maximum 0.0000 eV at path point 30 (Gamma)
conduction minimum 0.4745 eV at 83% of the way from Gamma to X
indirect gap 0.4745 eV, the program's gap 0.4745 eV; direct gap at Gamma 2.5366 eV
Silicon, LDA band structurevalenceconductionconduction minimum−10−505LGammaXE−EVBM (eV)

How it's checked

check() runs dft/si_it_check.viv against the result: every band at every point of the path (the lowest six) within 10−5 eV of an independent dense NumPy implementation (dft/ref, which builds and diagonalizes the full Hamiltonian at each k), and the total energy within 10−7 hartree.

print("check():", r.check().passed)
check(): True

Credits

  • The GTH pseudopotential parameters are CP2K's GTH_POTENTIALS table as PySCF ships it (Goedecker, Teter and Hutter 1996; Hartwigsen, Goedecker and Hutter 1998); only the numbers are used, no CP2K or PySCF code.

Source

gallery/science/plot_silicon_bands.py, run as written when these pages were built. The output and the figures above are from that run.

The Viv program it calls is posts/2026-09-25-silicon-bands-from-the-crystal-up.viv: its atlas, the defs and the calls between them, or open it in the workbench.