Chapter 4
20 min read
Section 35 of 70

Density Functional Theory

Quantum Mechanics for Solids

Learning Objectives

Section 4.4 left us face-to-face with the most embarrassing fact in electronic-structure theory: the many-body wavefunction Ψ(r1,r2,,rN)\Psi(\mathbf{r}_1, \mathbf{r}_2, \ldots, \mathbf{r}_N) is impossible to store, let alone solve, for any system you actually care about. Even a humble water molecule needs a function of 30 coordinates; a CdSe quantum dot of 100 atoms involves hundreds. The universe simply does not have enough atoms to write Ψ\Psi down on a grid.

And yet VASP routinely simulates such systems on a laptop. The reason is a mathematical sleight of hand so audacious that two of its inventors won a Nobel Prize for it: throw away Ψ\Psi and keep only the electron density n(r)n(\mathbf{r}) — a humble function of three variables. This section explains why that move is allowed, what it costs, and what it does not give you.

By the end of this section you should be able to:

  1. State the Hohenberg–Kohn theorems in your own words and explain why theorem 1 is so surprising.
  2. Write the total energy as a functional E[n]=T[n]+Vext[n]+Vee[n]E[n] = T[n] + V_{\text{ext}}[n] + V_{ee}[n] and identify which piece is universal and which is system-specific.
  3. Apply the variational principle (HK2) to a one-parameter trial density and find the minimum by hand.
  4. Implement the original Thomas–Fermi DFT for the H atom in NumPy and quantify how badly it does compared with the exact answer.
  5. Articulate, precisely, what is unknown about F[n]F[n] and why that motivates the Kohn–Sham construction in Section 4.6.
  6. Locate the electron density in a real VASP run — CHGCAR, CHG, partial densities — and read off basic properties from it.

Where Section 4.4 Left Us Stranded

For a non-relativistic crystal, the electronic Schrödinger equation is, in atomic units,

H^Ψ=[12ii2  +  ivext(ri)  +  12ij1rirj]Ψ=EΨ\hat{H}\,\Psi = \left[ -\tfrac{1}{2}\sum_{i} \nabla_i^2 \;+\; \sum_{i} v_{\text{ext}}(\mathbf{r}_i) \;+\; \tfrac{1}{2}\sum_{i \neq j} \frac{1}{|\mathbf{r}_i - \mathbf{r}_j|} \right] \Psi = E\,\Psi

Three terms: kinetic energy of electrons, attraction to nuclei, and electron–electron repulsion. Innocent enough on paper. The catastrophe is the third term: it couples every pair of electrons, which means Ψ\Psi cannot be written as a product of one-electron functions. StoringΨ\Psi on a 100-point grid for a 50-electron system needs 10015010300100^{150} \approx 10^{300} numbers. The observable universe contains about 108010^{80} protons.

This wall — the “exponential wall” of many-body quantum mechanics — is real and unyielding. No amount of cluster time will make a brute-force solution feasible for anything bigger than a small molecule. We must change the question we ask of nature.

The Wild Idea: Forget Ψ, Keep n(r)

Notice something subtle about the Hamiltonian. The kinetic operator and the electron–electron repulsion look the same for every system: a chunk of copper, a benzene ring, a Mn:CdSe quantum dot, the inside of a neutron star. Only the external potential vext(r)v_{\text{ext}}(\mathbf{r}) — the Coulomb attraction of this particular set of nuclei at these particular positions — tells one material from another.

So the question is: do we really need the full Ψ\Psi, or is some smaller object enough to reconstruct everything we want?

The boldest possible answer was given by Pierre Hohenberg and Walter Kohn in 1964: the electron density is enough. Not the wavefunction. Not the density matrix. Just the scalar field n(r)n(\mathbf{r}) — how many electrons per cubic bohr, at every point in space.

Three coordinates instead of 3N3N. For our 50-atom CdSe slab that is the difference between a function on a 3D grid (millions of values, fits in RAM) and a function on a 450-dimensional grid (does not exist).

Wavefunction, Density, and Kohn-Sham Orbitals

DFT becomes less mysterious once the three central objects are kept separate. The exact many-body wavefunction is the formal object, the density is the physical object Hohenberg and Kohn elevate, and the Kohn–Sham orbitals are the computational device VASP actually manipulates.

ObjectDimensionStatusVASP fileMain use
Many-body wavefunction Ψ(r₁, …, r_N)3N variablesExact formal object; impossible to store for solidsNot storedDefines the full quantum problem
Electron density n(r)3 variablesPhysical observable; integrates to NELECTCHGCAR, CHG, PARCHGCharge, bonding, density differences, DFT energy
Kohn-Sham orbitals φ_i(r)3 variables eachAuxiliary orbitals chosen to reproduce n(r)WAVECAR, PROCAR-style projectionsKinetic energy, bands, DOS, partial charges
Kohn–Sham orbitals are not the exact many-body wavefunction. They are a clever non-interacting scaffold whose density matches the interacting density. Treating their eigenvalues as measured quasiparticle energies is useful in practice, but it is not what the Hohenberg–Kohn theorem proves.

What Exactly Is the Electron Density?

Given any (normalised) many-body wavefunction Ψ(r1,,rN)\Psi(\mathbf{r}_1, \ldots, \mathbf{r}_N), the electron density is

n(r)=NΨ(r,r2,,rN)2dr2drNn(\mathbf{r}) = N \int |\Psi(\mathbf{r}, \mathbf{r}_2, \ldots, \mathbf{r}_N)|^2 \, d\mathbf{r}_2 \cdots d\mathbf{r}_N

Operationally: pin one electron at r\mathbf{r}, integrate out the other N1N-1 coordinates, and multiply by NN for the indistinguishability of identical particles. The result satisfies two simple sum rules every working DFT user invokes daily:

  • Normalisation: n(r)dr=N\int n(\mathbf{r}) \, d\mathbf{r} = N (total electron count).
  • Cusps at nuclei: nˉrr0=2Zαnˉ(0)\left.\frac{\partial \bar{n}}{\partial r}\right|_{r \to 0} = -2 Z_\alpha\,\bar{n}(0) (Kato's cusp condition; the density tells you both where the nuclei are and what charge they carry).

That second bullet is already a hint: the density is not just a blob of charge. It encodes precise structural information.


Hohenberg–Kohn Theorem 1: Density Determines Everything

HK1 (1964): For a non-degenerate ground state, the external potential vext(r)v_{\text{ext}}(\mathbf{r}) is uniquely determined — up to an irrelevant additive constant — by the ground-state density n0(r)n_0(\mathbf{r}).

Read that twice. The density tells you the potential. Knowing the potential, you know the entire Hamiltonian (the kinetic and repulsion pieces are universal). Knowing the Hamiltonian, you can in principle solve for the wavefunction and any other observable. Therefore, in a precise mathematical sense,

n0(r)    vext(r)    H^    Ψ    everything.\boxed{\quad n_0(\mathbf{r}) \;\Longleftrightarrow\; v_{\text{ext}}(\mathbf{r}) \;\Longleftrightarrow\; \hat{H} \;\Longleftrightarrow\; \Psi \;\Longleftrightarrow\; \text{everything}.\quad}

The proof is a one-page reductio ad absurdum: assume two different potentials v1,v2v_1, v_2 share the same ground-state density, apply the Rayleigh–Ritz variational principle to each, and add the two strict inequalities. The contradiction E0<E0E_0 < E_0 falls out immediately.

HK1 does not tell you how to extract vextv_{\text{ext}} from nn — it only certifies that the map exists and is one-to-one. A 21st-century analogy: HK1 is the existence theorem, Kohn–Sham (next section) gives the algorithm.

Interactive: The Density ↔ Potential Map

Drag the red ions and watch the orange external potential and the cyan electron density shift together. They are two sides of the same coin: HK1 says the cyan curve uniquely determines the orange one. Add or remove ions and the bijection still holds — the density even encodes how many nuclei there are and what charges they carry, through cusps you can spot by eye.

Reading the density backwards: peaks pinpoint nuclei, peak heights scale with ZZ, and the area under the curve equals the total electron count. A trained DFT eye reads a CHGCAR slice the way a doctor reads a chest X-ray.

Hohenberg–Kohn Theorem 2: The Variational Principle

HK2 (1964): There exists a universal energy functional Ev[n]E_v[n] such that, for any trial density n~(r)\tilde{n}(\mathbf{r}) integrating to NN,

Ev[n~]    Ev[n0]  =  Eground,E_v[\tilde{n}] \;\geq\; E_v[n_0] \;=\; E_{\text{ground}},

with equality if and only if n~(r)=n0(r)\tilde{n}(\mathbf{r}) = n_0(\mathbf{r}). In other words, the ground-state energy is the global minimum of an energy functional — a function whose argument is itself a function. This is the analogue of the Rayleigh–Ritz variational principle, but lifted from the space of wavefunctions (size 3N\infty^{3N}) to the space of densities (size 3\infty^{3}).

HK2 is what makes DFT computable. Pick any physically admissible trial density, plug it into Ev[n]E_v[n], and you get an upper bound on the true ground-state energy, provided the trial density is physically admissible: non-negative, normalised to the correct NN, and representable by at least one antisymmetric NN-electron state. Improve the density — the bound improves. Find the minimum — you have the answer.

The representability caveat matters. Not every smooth-looking function that integrates to NN can be the density of a legitimate fermionic ground state. In practical Kohn–Sham DFT, the orbital construction gives us admissible densities automatically because n(r)=ifiϕi(r)2n(\mathbf{r}) = \sum_i f_i |\phi_i(\mathbf{r})|^2 with occupation numbers fif_i.

The Universal Functional F[n]

Following Hohenberg and Kohn, decompose the total energy as

Ev[n]  =  F[n]  +  vext(r)n(r)dr.E_v[n] \;=\; F[n] \;+\; \int v_{\text{ext}}(\mathbf{r})\,n(\mathbf{r})\,d\mathbf{r}.

The second term is system-specific but trivial: just the electrostatic energy of the density in the field of the (known) nuclei. The first term F[n]F[n] contains the kinetic energy T[n]T[n] and the electron–electron interaction Vee[n]V_{ee}[n]. Crucially, F[n]F[n] is the same functional for every Coulombic system: copper, benzene, CdSe quantum dot, the corona of the sun. Once we know FF, every electronic-structure problem in the universe becomes a one-line minimisation:

Eground=minn{F[n]+vextndr}.\boxed{\quad E_{\text{ground}} = \min_{n} \left\{ F[n] + \int v_{\text{ext}}\,n\, d\mathbf{r}\right\}.\quad}

F[n]F[n] is the holy grail. If we knew it exactly, we could compute the exact ground-state energy and density of any non-relativistic Coulombic matter from a single three-dimensional integral. A 1960s “theory of everything” for chemistry and condensed-matter physics.

The Catch: Nobody Knows F[n]

And here is the punchline. Hohenberg and Kohn proved F[n]F[n] exists. They did not write it down. Sixty years and a Nobel Prize later, the exact form of F[n]F[n] is still unknown. We have very good approximations — some of them excellent for solids — but not the truth.

The structure of the unknown is this. Split F[n]F[n] into pieces we know and pieces we don't:

F[n]  =  Ts[n]independent-particle kinetic  +  12 ⁣ ⁣n(r)n(r)rrdrdrHartree, J[n]  +  Exc[n]exchange-correlation.F[n] \;=\; \underbrace{T_s[n]}_{\text{independent-particle kinetic}} \;+\; \underbrace{\tfrac{1}{2}\!\!\iint \frac{n(\mathbf{r})\,n(\mathbf{r}')}{|\mathbf{r}-\mathbf{r}'|}\,d\mathbf{r}\,d\mathbf{r}'}_{\text{Hartree, } J[n]} \;+\; \underbrace{E_{xc}[n]}_{\text{exchange-correlation}}.

The Hartree term is an explicit density functional. TsT_s is explicit once we introduce Kohn–Sham orbitals, but it is not known as a simple closed-form function of n(r)n(\mathbf{r}) alone. The third piece, Exc[n]E_{xc}[n], contains both leftovers: the difference between the true kinetic energy and TsT_s, plus the difference between the true electron–electron interaction and the classical Hartree self-repulsion. Modelling ExcE_{xc} is the entire art of modern DFT.

Section 4.7 is dedicated to approximations of ExcE_{xc}: LDA, GGA (PBE in particular), and meta-GGA. Section 5.10 covers the more expensive hybrids and many-body corrections. For now, accept the existence of ExcE_{xc} and move on.

First Concrete Functional: Thomas–Fermi

Long before HK proved their theorems, Llewellyn Thomas and Enrico Fermi (independently, 1927) wrote down the first explicit density functional. Their approximation:

  • Borrow the kinetic-energy density of a uniform electron gas (Section 4.1), evaluated at the local density n(r)n(\mathbf{r}).
  • Drop exchange and correlation entirely.
  • Treat the Coulomb interaction classically (just J[n]J[n]).

The kinetic functional is

TTF[n]=CFn(r)5/3dr,CF=310(3π2)2/32.871.T_{\text{TF}}[n] = C_F \int n(\mathbf{r})^{5/3}\, d\mathbf{r}, \qquad C_F = \tfrac{3}{10}\,(3\pi^2)^{2/3} \approx 2.871.

For our Thomas–Fermi-style one-electron toy model of hydrogen, the Hartree term J[n]J[n] is meaningless (there is no second electron to repel against), so the energy reduces to

E[n]=TTF[n]+Vext[n]=CFn5/3drZn(r)rdr.E[n] = T_{\text{TF}}[n] + V_{\text{ext}}[n] = C_F \int n^{5/3}\,d\mathbf{r} - Z\int \frac{n(\mathbf{r})}{r}\, d\mathbf{r}.

Pick a one-parameter family of trial densities — say spherical Gaussians of width α\alpha

nα(r)=1(πα2)3/2er2/α2,n_\alpha(r) = \frac{1}{(\pi\alpha^2)^{3/2}}\,e^{-r^2/\alpha^2},

and compute the energy as a function of α\alpha. The integrals close in elementary form:

TTF(α)=CF(3/5)3/2πα2,Vext(α)=2Zπα.T_{\text{TF}}(\alpha) = \frac{C_F (3/5)^{3/2}}{\pi\alpha^2}, \qquad V_{\text{ext}}(\alpha) = -\frac{2 Z}{\sqrt{\pi}\,\alpha}.

Setting dE/dα=0dE/d\alpha = 0 for Z=1Z = 1 gives α0.753a0\alpha^\star \approx 0.753\,a_0 with E0.749HaE^\star \approx -0.749\,\text{Ha}. Compare the exact answer for a hydrogen atom: Eexact=0.500HaE_{\text{exact}} = -0.500\,\text{Ha}. This TF-style density-only model over-binds the electron by 50%. The functional is qualitatively right (a sane minimum exists, the density peaks at the nucleus, units are bohr and hartree) and quantitatively wrong (a critical 0.25 Ha off).

Below the “over-binding” complaint lies the deepest fact of DFT: an approximation to the kinetic functional is just as important as an approximation to ExcE_{xc}. Thomas–Fermi treats the electron as if it were dissolved into an infinite gas. Real electrons obey the Pauli principle one orbital at a time. That observation is what motivates Kohn–Sham.

Interactive: Variational Principle in Action

Slide α\alpha below and watch the trial Gaussian on the left widen or narrow. The right panel decomposes the energy: a violet kinetic curve (penalises sharp densities), an orange external curve (rewards densities concentrated at the nucleus), and a cyan total. The yellow star marks the variational minimum — the “best” Thomas–Fermi answer for this trial family.

Why does the kinetic curve fall as 1/α²? Heisenberg. Confining an electron to a Gaussian of width α\alpha sets its momentum spread to Δp1/α\Delta p \sim 1/\alpha, so the kinetic energy p2/(2m)p^2/(2m) goes as 1/α21/\alpha^2. Squeezing the cloud costs kinetic energy.
Why does the external curve fall as −1/α? The Coulomb potential of a single point charge looks the same on every length scale up to a single factor; integrating it against a Gaussian of width α\alpha gives an answer proportional to 1/α1/\alpha. A more compact density sees a stronger nuclear attraction.

Code Walk-Through: A Working Density-Only Model in 30 Lines

Time to make the picture concrete. The script below evaluates the Thomas–Fermi-style total energy for a Gaussian trial density at 17 widths α\alpha, picks the smallest one, and prints the comparison with the exact H atom. This is the variational skeleton of a DFT calculation — choose an allowed density, evaluate an energy functional, improve the density — but it is not yet a Kohn–Sham self-consistent field calculation. Click any line on the right to see what is in memory at that point.

Thomas–Fermi DFT for the H Atom — Interactive Trace
🐍thomas_fermi_h.py
1import numpy as np

NumPy gives us np.exp, np.pi, np.linspace, and np.trapezoid — everything we need to evaluate radial integrals like ∫ g(r) · 4π r² dr on a uniform grid. We do not need scipy because the integrals are well behaved and a fine trapezoidal rule reaches < 10⁻⁴ accuracy.

EXECUTION STATE
numpy = Numerical-computing library (ndarray, linear algebra, math constants)
as np = Standard alias used throughout the script
3Comment: Thomas–Fermi kinetic constant

Reminds us we are in Hartree atomic units (ℏ = m_e = e = 1). All energies will come out in hartrees (1 Ha ≈ 27.211 eV) and all lengths in bohr (a₀ ≈ 0.529 Å).

4C_F = (3/10) · (3π²)^(2/3)

The Thomas–Fermi kinetic-energy density of a uniform electron gas is t_TF[n] = C_F · n^(5/3), with C_F = (3/10)(3π²)^(2/3). Computed once at module load. This single constant carries the entire 'kinetic energy of a sea of free fermions' physics from Section 4.1.

EXECUTION STATE
📚 np.pi = NumPy's pre-defined constant 3.141592653589793
→ 3 * np.pi**2 = 29.608813...
→ (3π²)^(2/3) = 9.570313... (cube root of 29.61² = 876.68)
C_F = 2.871234
→ physical role = Slope of T[n]/V vs n^(5/3) for a uniform electron gas. Larger n → much larger kinetic energy (electrons must occupy higher k-states).
6Comment: trial density family

We restrict ourselves to spherically symmetric Gaussian densities, parameterised by a single width α. Why a Gaussian? Because (a) the analytical integrals all close in elementary form and (b) it is the simplest shape that has the right qualitative behaviour: peaked at the nucleus, exponential tail. The variational space is 1-dimensional, so the optimisation reduces to a single slider.

7def density(r, alpha, N=1.0) → ndarray

Returns the value of n(r) at every radius r supplied. The prefactor (N / (π α²)^(3/2)) makes ∫ n(r) d³r = N exactly. Setting N = 1 means we are describing a single-electron system (the H atom). Increase N for He, Li, etc.

EXECUTION STATE
⬇ input: r (ndarray) = Radial distance(s) from the nucleus, in bohr. Can be a scalar or an array — NumPy broadcasts.
⬇ input: alpha (float) = Width of the Gaussian. Small α = sharp, narrow density; large α = diffuse cloud.
⬇ input: N (float, default 1.0) = Total electron count. Sets the normalisation ∫ n d³r = N.
⬆ returns = ndarray of n(r) values, units of electrons / bohr³.
8Docstring: explicit formula

Documents the Gaussian we are using. Equivalent to n(r) = (N / σ³) · π^(-3/2) · exp(-r²/α²) with σ = α√π. Maximum density n(0) = N / (πα²)^(3/2): for α = 1 a₀, that is about 0.18 e⁻/a₀³ (compare to the true H atom maximum of 1/π ≈ 0.32 e⁻/a₀³).

9return (N / (np.pi * alpha**2)**1.5) * np.exp(-r**2 / alpha**2)

Evaluates the Gaussian elementwise. np.exp is vectorised, so passing an array of 4000 r values gives back an array of 4000 densities in microseconds.

EXECUTION STATE
📚 np.exp(x) = Elementwise exponential. Returns an ndarray of the same shape as x.
→ at α = 1, r = 0 = n(0) = 1 / π^(3/2) ≈ 0.1796 e⁻/a₀³
→ at α = 1, r = 1 = n(1) = 0.1796 · e⁻¹ ≈ 0.0661 e⁻/a₀³
→ at α = 1, r = 3 = n(3) ≈ 0.1796 · e⁻⁹ ≈ 2.2 × 10⁻⁵ — tail dies fast
11Comment: radial integration helper

Spherically symmetric integrals reduce from ∫ d³r to 4π ∫₀^∞ r² dr, so we write a single helper that takes a radial integrand g(r) and returns the volume integral. We will reuse it for normalisation, kinetic, external-energy, and any other one-body integral.

12def radial_integral(g, alpha, n_pts=4000) → float

Higher-order function: takes another function g as argument. The grid stretches to 30·α (well past where the Gaussian is numerically zero) and uses 4000 trapezoidal panels — overkill for accuracy but fast enough.

EXECUTION STATE
⬇ input: g (callable) = Function r → g(r) returning a scalar or ndarray. Will be multiplied by 4π r² inside.
⬇ input: alpha (float) = Width parameter, only used to choose the integration range and grid spacing — keeps the rule self-tuning.
⬇ input: n_pts (int, default 4000) = Number of trapezoidal panels. 4000 → relative error < 10⁻⁵ on every integral here.
⬆ returns = Scalar value of ∫₀^{30α} g(r) · 4π r² dr.
13r = np.linspace(1e-10, 30 * alpha, n_pts)

Builds the radial grid. We start at 10⁻¹⁰ (not 0) to avoid a 1/r singularity in the external-potential integrand. End at 30·α: by then the Gaussian factor exp(-900) is below floating-point precision.

EXECUTION STATE
📚 np.linspace(start, stop, n) = Returns n evenly spaced floats from start to stop INCLUSIVE. Spacing = (stop - start)/(n - 1).
⬇ arg 1: start = 1e-10 = Tiny positive number; avoids r = 0 where 1/r blows up in V_ext.
⬇ arg 2: stop = 30*alpha = Far beyond the support of the Gaussian. At α = 1 → r_max = 30 a₀.
⬇ arg 3: n_pts = 4000 = Number of grid points. Spacing dr = (30α - 1e-10)/3999 ≈ 7.5 × 10⁻³ a₀ for α = 1.
⬆ result: r = ndarray of shape (4000,), values from 1e-10 to 30α. Example [0]: 1e-10; [1999]: ≈15α; [3999]: 30α
14return np.trapezoid(g(r) * 4.0 * np.pi * r**2, r)

Evaluates the integrand at every grid point, then applies the trapezoidal rule. The factor 4π r² turns a radial integral into a full volume integral by spherical-symmetry argument.

EXECUTION STATE
📚 np.trapezoid(y, x) = Composite trapezoidal rule: Σᵢ ½ (y[i] + y[i+1]) · (x[i+1] - x[i]). Replaces the deprecated np.trapz.
⬇ arg 1: y = g(r) * 4πr² = Integrand sampled on the grid. ndarray of shape (4000,).
⬇ arg 2: x = r = Abscissae (the same grid). NumPy uses the irregular spacing safely if needed.
⬆ result = Scalar approximation of ∫₀^{30α} g(r) · 4πr² dr.
16Comment: DFT energy components

Each functional we are about to define is a real-valued map taking a density (parameterised by α here) to an energy in hartrees. In a full DFT calculation there would be more pieces (Hartree, exchange, correlation), but for one electron all of those vanish — there is no other electron to repel from!

17def kinetic_TF(alpha, N=1.0) → float

Thomas–Fermi kinetic functional T_TF[n] = C_F ∫ n^(5/3) d³r. Depends only on the local value of n — no derivatives, no orbitals, just the density to the 5/3 power. This is the simplest density functional that has ever been written down (Thomas 1927, Fermi 1927).

EXECUTION STATE
⬇ input: alpha = Width parameter selecting the trial density.
⬇ input: N (default 1.0) = Total electron count. T_TF scales as N^(5/3).
⬆ returns = Scalar kinetic energy in hartrees.
18return C_F * radial_integral(lambda r: density(r, alpha, N)**(5.0/3.0), alpha)

Builds an inline λ that returns n(r)^(5/3) at any radius, hands it to radial_integral. The constant C_F is multiplied in afterwards. By the analytical Gaussian formula, T_TF should equal C_F · (3/5)^(3/2) / (πα²) for N = 1 — a useful sanity check.

EXECUTION STATE
→ at α = 1.0 = T_TF = C_F · (3/5)^(3/2) / π = 2.8712 · 0.4648 / π = 0.4248 Ha
→ at α = 0.7530 = T_TF = 0.4248 / 0.7530² ≈ 0.7494 Ha (variational minimum)
→ at α = 2.0 = T_TF = 0.4248 / 4.0 ≈ 0.1062 Ha — diffuse density costs little kinetic energy
20def external_energy(alpha, Z=1.0, N=1.0) → float

Electron–nucleus attraction V_ext[n] = -Z ∫ n(r)/r d³r. The 1/r factor cancels one power of r from the volume element 4πr² dr, leaving a finite integrand at the nucleus. With our Gaussian density and analytical integration this becomes -2 Z N / (√π · α).

EXECUTION STATE
⬇ input: alpha = Width — narrower density piles charge near the nucleus → more negative V_ext.
⬇ input: Z (default 1.0) = Nuclear charge. For H, Z = 1; for He, Z = 2; etc.
⬇ input: N (default 1.0) = Electron count. V_ext scales linearly in N.
⬆ returns = Scalar potential energy (negative for an attractive nucleus).
21return -Z * radial_integral(lambda r: density(r, alpha, N) / r, alpha)

Same machinery: λ produces n(r)/r, the helper integrates with the spherical 4πr² weight, the leading -Z applies the sign and nuclear charge.

EXECUTION STATE
→ at α = 1.0 = V_ext = -2/√π ≈ -1.1284 Ha
→ at α = 0.7530 = V_ext = -1.1284 / 0.7530 ≈ -1.4988 Ha
→ at α = 2.0 = V_ext = -1.1284 / 2.0 ≈ -0.5642 Ha — diffuse density loses attraction
23def total_energy(alpha) → float

E[n] = T_TF[n] + V_ext[n] for our one-electron toy. No Hartree, no exchange, no correlation — those terms are zero or unnecessary here. The total is what we minimise.

EXECUTION STATE
⬇ input: alpha = Variational parameter, 0.4 to 2.5.
⬆ returns = Scalar total energy of the Gaussian trial density at this α.
24return kinetic_TF(alpha) + external_energy(alpha)

Just an addition of two previously computed scalars. The competition between a 1/α² penalty and a -1/α reward gives a single minimum that the next loop will find.

EXECUTION STATE
→ at α = 0.4 = E = 2.6548 - 2.8209 = -0.1661 Ha
→ at α = 0.7530 = E = 0.7494 - 1.4988 = -0.7494 Ha (★ minimum ★)
→ at α = 1.0 = E = 0.4248 - 1.1284 = -0.7036 Ha
→ at α = 2.0 = E = 0.1062 - 0.5642 = -0.4580 Ha
26Comment: variational scan

Hohenberg–Kohn 2 says E[n] ≥ E_ground for any valid trial density n: non-negative, normalised to N, and representable by some antisymmetric N-electron state. Our Gaussian family satisfies the basic normalisation and positivity requirements, so we sweep α, evaluate E, and pick the smallest. This is the simplest possible variational DFT calculation: there is only one parameter to converge.

27alphas = np.linspace(0.4, 2.0, 17)

17 grid points spanning a sensible range of widths. Coarse on purpose — we just want to see the U-shape, not the 5-decimal minimum.

EXECUTION STATE
📚 np.linspace(start, stop, n) = Inclusive range, n evenly spaced values.
⬇ args = start = 0.4, stop = 2.0, n = 17 → spacing = 0.1
⬆ result: alphas = [0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0]
28print(" alpha T_TF V_ext E_total")

Header for the scan table. Just text; no computation.

29for a in alphas:

Iterates over every width and prints a row. 17 iterations, each costing a few hundred microseconds.

LOOP TRACE · 8 iterations
a = 0.40
T_TF, V_ext, E = 2.6548, -2.8209, -0.1661
a = 0.60
T_TF, V_ext, E = 1.1799, -1.8806, -0.7007
a = 0.70
T_TF, V_ext, E = 0.8669, -1.6120, -0.7451
a = 0.80
T_TF, V_ext, E = 0.6637, -1.4105, -0.7468
a = 0.90
T_TF, V_ext, E = 0.5244, -1.2538, -0.7294
a = 1.00
T_TF, V_ext, E = 0.4248, -1.1284, -0.7036
a = 1.50
T_TF, V_ext, E = 0.1888, -0.7522, -0.5635
a = 2.00
T_TF, V_ext, E = 0.1062, -0.5642, -0.4580
30print(f" {a:5.3f} {kinetic_TF(a):7.4f} {external_energy(a):7.4f} {total_energy(a):7.4f}")

f-string formatting with field widths: '5.3f' = 5 chars wide, 3 decimal places; '7.4f' = 7 wide, 4 decimal. Calls each functional once per α.

EXECUTION STATE
→ output structure = Three numeric columns aligned with the header. Eyeballing the third column shows the U-shape minimum near α = 0.75.
32best = alphas[np.argmin([total_energy(a) for a in alphas])]

List comprehension produces the 17 energies, np.argmin returns the index of the minimum, and we use that index to grab the corresponding α. Note that this just picks the best grid point — the true minimum at 0.7529 falls between 0.70 and 0.80.

EXECUTION STATE
📚 np.argmin(arr) = Returns the integer index of the smallest element. For ties, returns the first.
→ list of energies = [-0.166, -0.448, -0.701, -0.745, -0.747, -0.729, -0.704, -0.673, -0.640, -0.608, -0.577, -0.547, -0.519, -0.494, -0.470, -0.447, -0.426]
→ np.argmin → = 4 (the 5th entry, value -0.7468)
→ best α = alphas[4] = 0.80 (closest grid point to the true 0.7529)
33print(f"\nBest alpha on grid: {best:.3f}, E = {total_energy(best):.4f} Ha")

Reports the grid winner and its energy. A finer grid or scipy.optimize.minimize_scalar would push α to ≈ 0.7529 and E to ≈ -0.7494 Ha.

EXECUTION STATE
→ printed output = Best alpha on grid: 0.800, E = -0.7468 Ha
34print(f"Exact H 1s energy : -0.5000 Ha (TF-style model over-binds)")

The exact ground-state energy of the hydrogen atom is -1/2 Ha = -0.5000 Ha (and the exact density is n(r) = e^{-2r}/π, which is an exponential — not a Gaussian). Our TF estimate of -0.7494 Ha is too low by 50%. The trial-density family is partly to blame, but the dominant error is that T_TF treats every electron as if it lived in a uniform gas, ignoring the fact that there is exactly one electron concentrated at one nucleus. That is why every modern DFT code uses the Kohn–Sham construction in the next section.

EXECUTION STATE
→ printed output = Exact H 1s energy : -0.5000 Ha (TF-style model over-binds)
8 lines without explanation
1import numpy as np
2
3# Thomas-Fermi kinetic-energy constant (Hartree atomic units)
4C_F = (3.0 / 10.0) * (3.0 * np.pi**2)**(2.0 / 3.0)
5
6# Trial electron density: spherical Gaussian, total charge N around Z=1 nucleus
7def density(r, alpha, N=1.0):
8    """n(r) = (N / (pi*alpha^2)^(3/2)) * exp(-r^2 / alpha^2)."""
9    return (N / (np.pi * alpha**2)**1.5) * np.exp(-r**2 / alpha**2)
10
11# Radial integration helper: integrand g(r) over 0..r_max, 4*pi*r^2 included
12def radial_integral(g, alpha, n_pts=4000):
13    r = np.linspace(1e-10, 30 * alpha, n_pts)
14    return np.trapezoid(g(r) * 4.0 * np.pi * r**2, r)
15
16# DFT energy components for the trial density
17def kinetic_TF(alpha, N=1.0):
18    return C_F * radial_integral(lambda r: density(r, alpha, N)**(5.0/3.0), alpha)
19
20def external_energy(alpha, Z=1.0, N=1.0):
21    return -Z * radial_integral(lambda r: density(r, alpha, N) / r, alpha)
22
23def total_energy(alpha):
24    return kinetic_TF(alpha) + external_energy(alpha)
25
26# Variational scan: which alpha minimises E[n_alpha]?
27alphas = np.linspace(0.4, 2.0, 17)
28print("  alpha     T_TF       V_ext       E_total")
29for a in alphas:
30    print(f"  {a:5.3f}   {kinetic_TF(a):7.4f}   {external_energy(a):7.4f}   {total_energy(a):7.4f}")
31
32best = alphas[np.argmin([total_energy(a) for a in alphas])]
33print(f"\nBest alpha on grid: {best:.3f}, E = {total_energy(best):.4f} Ha")
34print(f"Exact H 1s energy : -0.5000 Ha   (TF-style model over-binds)")

Run the script and you will see:

📝text
1alpha     T_TF       V_ext       E_total
2  0.400    2.6548    -2.8209    -0.1661
3  0.500    1.6993    -2.2568    -0.5575
4  0.600    1.1799    -1.8806    -0.7007
5  0.700    0.8669    -1.6120    -0.7451
6  0.800    0.6637    -1.4105    -0.7468
7  0.900    0.5244    -1.2538    -0.7294
8  1.000    0.4248    -1.1284    -0.7036
9  ...
10  2.000    0.1062    -0.5642    -0.4580
11
12Best alpha on grid: 0.800, E = -0.7468 Ha
13Exact H 1s energy : -0.5000 Ha   (TF-style model over-binds)
Refine with scipy.optimize.minimize_scalar(total_energy, bounds=(0.4, 2.0), method='bounded') and the optimum sharpens to α=0.7529\alpha^\star = 0.7529 with E=0.7494E^\star = -0.7494 Ha — matching the analytical answer derived above to four decimal places.

Why Thomas–Fermi Fails (and Why That Matters)

Thomas–Fermi's 50% error on hydrogen is not a quirk; it is the symptom of two structural problems that Kohn and Sham would fix 12 years later.

DefectWhy it hurtsModern fix
Local kinetic functionalTreats every chunk of density as if it were a uniform gas. Ignores shell structure, nodes, atomic orbitals.Kohn–Sham orbitals carry the kinetic energy exactly; only V_xc is approximated.
No exchangeElectrons of the same spin avoid each other (Pauli). TF doesn’t know.Approximate E_xc[n]: LDA, GGA (PBE), meta-GGA, hybrids.
No correlationElectrons of opposite spin still repel and dance around each other.Correlation is bundled into E_xc.
No moleculesTeller’s theorem (1962): TF cannot bind a single molecule. H₂ falls apart.Pure orbital-based DFT (Kohn–Sham) binds correctly from day one.
The first row is the most important. TF asks density to do the kinetic-energy job alone; it can't. Kohn and Sham's 1965 insight was: introduce a fictitious system of non-interacting electrons whose density matches the real density, evaluate the kinetic energy of that system exactly using its orbitals, and bury the (small) remaining error into ExcE_{xc}. That is the entire trick of modern DFT and the subject of the next section.

VASP Connection: Where the Density Lives

VASP is, at its core, a machine for minimising Ev[n]E_v[n] with a particular choice of Exc[n]E_{xc}[n] over a plane-wave basis. The density is a first-class citizen of every output file.

1. CHGCAR — the converged charge density

After every self-consistent run VASP writes the density n(r)n(\mathbf{r}) on a real-space grid into CHGCAR. The format is plain text: a header copied from POSCAR (lattice + atoms), then a block of floating-point numbers giving nn at every grid point. The grid is set by NGXF, NGYF, NGZF in the OUTCAR and is typically twice the wavefunction grid.

bash
1# Quickly inspect a CHGCAR
2head -10 CHGCAR                # POSCAR-style header
3sed -n '/^ *[0-9]\+ [0-9]\+ [0-9]\+$/,$p' CHGCAR | head  # find the grid line, dump first values
4
5# Check normalisation (should equal NELECT)
6python -c "
7import numpy as np
8from pymatgen.io.vasp import Chgcar
9chg = Chgcar.from_file('CHGCAR')
10print('integral n =', chg.data['total'].sum() * chg.structure.volume / chg.data['total'].size)
11"

2. PARCHG — partial densities (one band, one k-point, ...)

Set LPARD = .TRUE. in INCAR and ask for a specific band/k-point/spin range; VASP prints a PARCHG file in the same format. This is how you visualise the HOMO of a molecule, the wavefunction of a defect state, or the localisation of a Mn d orbital inside a CdSe matrix — pictures we will need in Chapter 7.

3. CHG — the running density (for restarts)

CHG is the same data as CHGCAR but truncated to fewer significant figures. VASP can read it back at the start of a new run via ICHARG = 1 (read from file) or ICHARG = 11 (read and freeze for non-self-consistent post-processing such as band structures and DOS).

📄ini
1# INCAR — controlling what density VASP writes and reads
2LCHARG = .TRUE.    # write CHGCAR/CHG at the end (default)
3LWAVE  = .FALSE.   # don’t write WAVECAR — saves disk
4ICHARG = 2         # build the initial density from atomic charges (default for fresh runs)
5                   # set to 1 to read CHGCAR; 11 for non-SCF DOS / band-structure runs
6LPARD  = .FALSE.   # set to .TRUE. and add EINT/IBAND/KPUSE for partial densities

4. Sanity checks for any CHGCAR

A useful habit is to treat every charge-density file as data that should pass basic conservation checks before you interpret pictures from it.

  • Integrate the total density and compare it with NELECT. A mismatch usually means you parsed the grid or volume factor incorrectly.
  • Plot a planar average nˉ(z)=A1n(x,y,z)dxdy\bar{n}(z) = A^{-1}\int n(x,y,z)\,dx\,dy for slabs, interfaces, and surfaces. It reveals charge spill-out and vacuum-region artefacts faster than a 3D isosurface.
  • For charged cells or defect calculations, compare CHGCAR files with the same grid and structure before subtracting them. Density differences are meaningful only when the underlying real-space grids align.

5. Reading the density at the cusps

Kato's cusp condition lets you read off nuclear positions and charges directly from the density: every nucleus is a sharp peak, and the slope of the spherically averaged density at r0r \to 0 equals 2Z-2 Z. In a plane-wave code this cusp is only approximate (the basis cannot resolve a true cusp), but pseudopotential-augmented PAW datasets reconstruct it via partial-wave projections. We will return to this in Section 4.8.

For Mn:CdSe in Chapter 7 you will compute partial charge densities of Mn 3d orbitals to visualise where the spin-polarised electrons sit. Every one of those pictures is just a slice through a CHGCAR-style array on a real-space grid — the same three-coordinate object Hohenberg and Kohn promised was enough.

Summary

  1. The many-body wavefunction Ψ(r1,,rN)\Psi(\mathbf{r}_1, \ldots, \mathbf{r}_N) lives in 3N3N dimensions and is hopeless to store directly. The electron density n(r)n(\mathbf{r}) lives in just three.
  2. HK1: the ground-state density uniquely determines the external potential (and therefore the entire Hamiltonian and every observable). The map is bijective — no two different potentials can give the same density.
  3. HK2: there is a universal energy functional Ev[n]E_v[n] minimised by the true ground-state density. Every trial density gives an upper bound.
  4. The unknown piece is F[n]=T[n]+Vee[n]F[n] = T[n] + V_{ee}[n], conventionally decomposed as F[n]=Ts[n]+J[n]+Exc[n]F[n] = T_s[n] + J[n] + E_{xc}[n]. The Hartree term is explicit in the density; TsT_s is explicit through Kohn–Sham orbitals; and Exc[n]E_{xc}[n] absorbs the remaining kinetic and interaction errors.
  5. Thomas–Fermi (1927) gave the first concrete F[n]F[n]. It is qualitatively right but quantitatively poor — it over-binds H by 50% and cannot bind molecules at all. The fix is to handle the kinetic energy via orbitals (Kohn–Sham, Section 4.6) and bury the remaining many-body errors in ExcE_{xc}.
  6. In VASP the density lives in CHGCAR, PARCHG, and CHG. Every output file in electronic-structure post-processing is a derivative of the same three-dimensional object Hohenberg and Kohn proved was sufficient.

Next section we turn the existence theorem into an algorithm. Kohn–Sham introduce a fictitious non-interacting system whose orbitals carry the kinetic energy exactly, leaving only a (small) exchange–correlation correction to approximate. That single construction is the engine of every DFT calculation VASP has ever run — including the Mn:CdSe quantum dots waiting for us in Chapter 7.

Loading comments...