A visualization of Perdew's Jacob's ladder of density functional theory (DFT), representing a hierarchy of increasingly sophisticated approximations to the exchange-correlation energy (E_xc). The ladder climbs from the Hartree approximation (no exchange-correlation) through local density approximations to accurate but expensive double-hybrid functionals one rung below chemical accuracy, with each rung adding new physical ingredients to improve accuracy at the cost of computational complexity.
#import "@preview/cetz:0.5.3": canvas, draw
#import draw: circle, content, line, rect
#set page(width: auto, height: auto, margin: 8pt, fill: none)
#set text(size: 14pt)
#canvas({
let rung-sep = 2.2 // Vertical separation between rungs
let width = 12.4 // Width of each rung
let height = 1.5 // Height of each rung
let circle-r = 0.8 // Radius of symbol circles
let rung-stroke = rgb("888") + 0.4pt
// Each rung: fill, name and example functionals, ingredient symbol, ingredient name
for (idx, (color, label, symbol, ingredient)) in (
(rgb("b4a7d6"), [0: *Hartree World*], none, none),
(rgb("a4c2f4"), [1: *Local Density Approx. (LDA)*\ VWN, PW92], $rho(bold(r))$, [density]),
(
rgb("f9cb9c"),
[2: *Generalized Gradient Approx. (GGA)*\ PBE, BLYP],
$nabla rho(bold(r))$,
[\+ density gradient],
),
(
rgb("ffe599"),
[3: *Meta-GGA*\ (r/r$""^2$)SCAN],
[$\ nabla^(2) rho(bold(r))$ \ $tau(bold(r))$],
[\+ Laplacian, kinetic energy density],
),
(
rgb("b6d7a8"),
[4: *Occupied Hybrid Methods* \ B3LYP, CAM-B3LYP, M06-2X],
${phi_i^"occ"}$,
[\+ occupied orbitals],
),
(
rgb("ea9999"),
[5: *Virtual Double-Hybrids* \ B2PLYP],
${phi_i^"virt"}$,
[\+ virtual orbitals],
),
(rgb("ffb7c5"), [*Chemical accuracy*], none, none),
).enumerate() {
let y = idx * rung-sep
rect((-width / 2, y), (width / 2, y + height), fill: color, stroke: rung-stroke, name: "rung")
let symbol-center = (rel: (1.15, 0), to: "rung.west") // Keep the symbols near the left edge
// Left-align text next to the symbol circle
content((rel: (circle-r + 0.2, 0), to: symbol-center), align(horizon, label), anchor: "west")
if symbol != none {
circle(symbol-center, radius: circle-r, fill: color, stroke: rung-stroke)
content(symbol-center, align(center, symbol))
}
if ingredient != none {
// Name the new ingredient right-aligned on the label's second line
content((rel: (-0.3, -0.33), to: "rung.east"), emph(ingredient), anchor: "east")
}
}
// Ladder rails run from the ground to the top of the last rung
for x in (-width / 2, width / 2) { line((x, 0), ((x, 0), "|-", "rung.north"), stroke: 0.7pt) }
})