“Know how to solve every problem that has been solved.”“What I cannot create, I do not understand.”— Richard Feynman
Time-Dependent DFT
Perturbation Methods
⛓
What you need to know first
12 concepts, 6 layers
The requisite-knowledge inventory for this page, bottom-up: the
primitives at the base, combined upward until you reach what this page
assumes. Skim the layers you already own; start wherever the ground gets unfamiliar.
1 of these are concepts without a dedicated page yet —
the grey chips. Following the linked ones first makes the rest land.
A ground-state DFT calculation
hands you a density standing perfectly still. Spectroscopy asks a different
question: what does that density do when light shakes it? Time-dependent
DFT is the Kohn-Sham trick extended to dynamics — one new object, the
kernel fxc, carries all the new physics — and
Casida's equation is what it
becomes when the shaking is gentle. Five ways in; read the one that lands.
read it as
Ground-state DFT rests on Hohenberg-Kohn: the density determines the
potential, so one function of three variables carries everything the
many-body wavefunction knows about the ground state. Runge and Gross
(1984) proved the moving-picture version: for a given initial state,
the time-dependent density ρ(r,t)
determines the time-dependent potential — the whole movie of the
density fixes the movie of the system. Same bargain as before:
trade the exponentially large wavefunction for the density, and pay
for it with a functional you have to approximate.
The Kohn-Sham move extends the same way. Invent a fictitious system of
non-interacting electrons in
orbitalsφj(r,t), choose its potential so it
reproduces the interacting density at every instant, and you get the
time-dependent Kohn-Sham equations:
Structurally it is the SCF equation with a time derivative where the
orbital energy used to be. The catch hides in
vxc[ρ](r,t): in principle it depends on
the density's entire history, not just its present value. That memory
is where the hard many-body physics went to live.
Everything genuinely new in TDDFT is concentrated in one object. Ask
how the exchange-correlation potential at point r
responds when the density wobbles at point r′ —
a functional
derivative:
fxc(r,r′,t−t′)=δρ(r′,t′)δvxc(r,t).
This is the xc kernel. It rides alongside the Hartree
response 1/∣r−r′∣ (which is exact and
free), and together they say how the effective potential pushes back
when the density moves. Every TDDFT excitation energy differs from a
bare orbital-energy gap only through these two terms — the tables
below measure that difference directly.
In practice almost everyone makes the adiabatic
approximation: evaluate the ground-state functional's
derivative at the instantaneous density and pretend there is no
memory,
fxcA(r,r′)=δρ(r′)δvxc[ρ](r)ρ=ρ0δ(t−t′).
Cheap, frequency-independent, and surprisingly good for valence
excitations. What it throws away is real: a frequency-independent
kernel can shift and mix the single-excitation poles it inherits from
the Kohn-Sham system, but it cannot create new poles — so
states with substantial double-excitation character simply do not
exist in adiabatic TDDFT's spectrum. Memory effects and
double excitations are the standing IOUs of the whole enterprise.
How do you get a spectrum out of the TDKS equations? Two roads, one
answer.
Road 1: real time. Kick the molecule with a spatially
uniform electric-field impulse at t=0, then just run the
TDKS equations forward and record the dipole moment as it rings.
Fourier transform the ring and every peak sits at an excitation
energy, with the peak weight telling you how brightly that state
absorbs. This is what real-time TDDFT codes do, and it is
linear response
performed experimentally on the simulation itself: hit it, listen.
Road 2: frequency domain. Don't propagate anything.
Linearize the TDKS equations around the ground state, project onto
occupied-virtual orbital pairs, and the poles of the response become
the eigenvalues of a matrix —
Casida's equation. One diagonalization, every discrete excitation
at once, machine precision.
Same physics, different linear algebra: road 1 wants many cheap
matrix-vector applications of the dynamics; road 2 wants one expensive
eigendecomposition. The demonstration below runs both on the same
water molecule and watches the FFT peaks land on the Casida roots to
within the FFT's own resolution.
The response-function view. Define χ(ω) as the
density-density response of the interacting system — how much
ρ moves per unit of applied potential at frequency
ω — and χ0(ω) as the same
object for the non-interacting Kohn-Sham system. The KS response is
known explicitly: it has a pole at every occupied-to-virtual gap,
But the KS electrons feel the density move through the Hartree
potential and vxc, and that feedback closes a loop: the
response responds to itself. Summing the loop gives a Dyson-type
equation,
χ(ω)=χ0(ω)+χ0(ω)(vH+fxc)χ(ω),
with vH=1/∣r−r′∣. Read it as a
renormalization machine: χ0 supplies raw poles at the
bare gaps εa−εi, and the kernel
shifts each pole and mixes poles that talk to each
other, producing the true excitation energies. Discretize this
equation in the particle-hole basis and you get exactly the Casida
matrix; the kernel matrix elements are its off-diagonals. The table
below shows the renormalization pole by pole — bare gap, then shifted
root — on real numbers.
The smallest instance of the whole theory. Take H2 in a
minimal basis: one occupied orbital, one virtual, so the particle-hole
space is one-dimensional and every matrix in sight is a
1×1 — a number. Two numbers, in fact:
the bare gap Δ=εu−εg, and
the one kernel matrix element K (the transition density
interacting with itself through Hartree-plus-fxc).
For a local kernel the same K lands in both Casida blocks:
A=Δ+K and B=K. The Casida
eigenvalue is ω2=(A−B)(A+B), and the kernel
cancels out of the first factor:
ω2=(Δ+K−K)(Δ+K+K)=Δ(Δ+2K)=Δ2+2ΔK.
That's adiabatic TDDFT in one line: start from the bare gap squared,
add a correction proportional to gap times kernel. Small
K expands to ω≈Δ+K — the
kernel as first-order perturbation theory on the gap. The Tamm-Dancoff
approximation keeps A alone:
ωTDA=Δ+K exactly, which is why TDA
sits slightly above the full answer. With PySCF's actual numbers for
H2/STO-3G below, the hand formula reproduces the library
solver to six decimal places.
The kernel, measured pole by pole
Here is the claim "every deviation from a bare orbital gap is the kernel's
doing," made checkable. For a pure (semi-local) functional like LDA, the
kernel is local, the same matrix element lands in A and
B, and so A−B collapses to the bare diagonal of
Kohn-Sham gaps — to machine precision. Mix in nonlocal HF exchange
(B3LYP) and the cancellation breaks, because exchange enters the two
blocks with different orbital pairings.
import numpy as npfrom pyscf import gto, scf, tdscfmol = gto.M(atom='O 0 0 0.1173; H 0 0.7572 -0.4692; H 0 -0.7572 -0.4692', basis='6-31g', verbose=0)mf = scf.RKS(mol); mf.xc = 'lda,vwn'; mf.kernel()A, B = tdscf.TDDFT(mf).get_ab() # spin-adapted singlet blocksnocc, nvir = A.shape[0], A.shape[1]n = nocc * nvirA, B = A.reshape(n, n), B.reshape(n, n)eps = mf.mo_energygaps = np.array([eps[nocc + a] - eps[i] for i in range(nocc) for a in range(nvir)])# Local kernel => the SAME element lands in A and in B, so A - B# collapses to the bare diagonal of KS gaps. A hybrid breaks this.print(np.max(np.abs(A - B - np.diag(gaps))))# Full TDDFT roots via the Hermitian rewrite; TDA roots from A alonew, U = np.linalg.eigh(A - B)S = (U * np.sqrt(np.maximum(w, 0))) @ U.Tomega = np.sqrt(np.linalg.eigvalsh(S @ (A + B) @ S))tda = np.linalg.eigvalsh(A)
Read the table one row at a time: each root is labeled by its dominant
parent transition, with the bare gap it started from, the TDA value, and
the full TDDFT value. The kernel pushes every one of these singlets
up from its bare gap, by 0.2 to 0.8 eV — the transition density's
Hartree self-repulsion outweighs the (negative, and in LDA rather weak)
fxc contribution. The 10−15 and
10−14 lines are the receipts: the locality identity holds
exactly, and our four-line Hermitian-rewrite solver agrees with PySCF's
TDDFT to floating-point noise.
The smallest possible spectroscopy
The one-pole formula from framing 5, on real numbers.
H2 in STO-3G has one occupied and one virtual orbital, so
get_ab() returns two numbers and the entire excited-state
calculation fits in a square root:
mol = gto.M(atom='H 0 0 0; H 0 0 0.74', basis='sto-3g', verbose=0)mf = scf.RKS(mol); mf.xc = 'lda,vwn'; mf.kernel()A, B = tdscf.TDDFT(mf).get_ab() # shapes (1,1,1,1): plain numbersD = mf.mo_energy[1] - mf.mo_energy[0] # the bare gapK = float(B[0, 0, 0, 0]) # the one kernel elementomega_hand = np.sqrt(D * (D + 2*K)) # the whole theory, by handtd = tdscf.TDDFT(mf); td.nstates = 1; td.kernel()print(omega_hand, float(td.e[0])) # same number
H2 / STO-3G LDA nocc = 1, nvir = 1 -> A, B are numbers D = eps_u - eps_g = 0.748730 Ha, K = B = 0.223033 Ha, A - D = 0.223033 Ha hand: omega = sqrt(D(D + 2K)) = 0.945822 Ha = 25.737 eV PySCF TDDFT: omega = 0.945822 Ha = 25.737 eV TDA (= A): omega = 0.971762 Ha = 26.443 eV
A−Δ=B to six decimals — the locality identity again,
now visible as two printed numbers being equal. The hand formula
Δ(Δ+2K) and the library solver agree to
every printed digit, and TDA overshoots by 0.7 eV, exactly the
ωTDA=Δ+K vs
ω≈Δ+K−K2/2Δ+⋯ gap you
get by expanding the square root. (Don't quote 25.7 eV to an
experimentalist: minimal-basis H2 is a cartoon. The point is
the structure, and the structure is exact.)
Two roads, one spectrum
Finally, the equivalence of the real-time road and the eigenvalue road,
demonstrated rather than asserted. We linearize the TDKS dynamics in the
particle-hole basis — the generator is built from the same
A and B blocks — kick the water molecule along
z, and march forward in time with the one-step propagator
e−iMδt applied over and over. No diagonalization
anywhere on this road. Then we FFT the induced dipole and ask where the
peaks fall.
from scipy.linalg import expmr_ao = mol.intor('int1e_r') # dipole integrals (3, nao, nao)C = mf.mo_coeffd = np.einsum('pi,pq,qa->ia', C[:, :nocc], r_ao[2], C[:, nocc:]).ravel()M = np.block([[A, B], [-B, -A]]) # the linearized TDKS generatoru = np.concatenate([d, d]).astype(complex) # state right after a z-kickdt, nsteps = 0.05, 40_000 # T = 2000 auU = expm(-1j * M * dt) # one-step propagator, built oncesignal = np.empty(nsteps)for s in range(nsteps): u = U @ u # march; never diagonalize signal[s] = np.real(d @ (u[:n] + u[n:])) # induced dipole <z>(t)signal -= signal.mean()t = np.arange(1, nsteps + 1) * dtspec = np.abs(np.fft.rfft(signal * np.exp(-0.003 * t)))freqs = np.fft.rfftfreq(nsteps, dt) * 2 * np.pi # peaks = excitations
Every FFT peak lands on a Casida root to well within the FFT's resolution
of 0.085 eV. The two roads really do carry the same information — the
choice between them is engineering, not physics. Casida wins for a
handful of discrete states in a small molecule; real-time propagation
wins when the system is large, when you want the whole broadband spectrum
at once, or when the field is strong enough that "linear" stops being
true. A full real-time code propagates the orbitals themselves on a grid
rather than particle-hole amplitudes, but the shape of the calculation —
kick, march, FFT — is precisely this one.
Try First
Each prompt asks a checkable question about the working code or math
above — predict an output, derive a sign, state an invariant, find a
bug. Commit to an answer before clicking "reveal." That commitment is
the whole point: if your answer matched, you understand the piece you
were looking at; if it didn't, that's the part worth re-reading.
predict
In the pole-by-pole table, the kernel pushed all five singlet roots
up from their bare gaps. Predict the lowest triplet of
the same molecule with the same functional: above or below the 7.176 eV
bare HOMO-LUMO gap? Commit to a direction and a reason before revealing.
answer
Below. Computed with the same setup (td.singlet = False),
the lowest triplet lands at 6.871 eV — 0.3 eV
under the bare gap, while the singlet from the same parent
transition sits 0.38 eV over it at 7.559 eV.
The reason is which pieces of the kernel survive spin adaptation. The
singlet channel feels Hartree plus fxc: the transition
density's Coulomb self-repulsion is positive and dominant, so singlets
go up. In the triplet channel the Hartree term cancels between the
spin components and only fxc — negative — remains, so
triplets go down. Same χ0, same bare gaps, opposite
shifts: the singlet-triplet splitting is manufactured entirely by the
kernel.
Contrast with TDHF on the Casida
page: there the H2 singlet fell from a 22.7 eV bare gap
to 15.0 eV, because nonlocal exchange supplies a large electron-hole
attraction −(ij∣ab) directly inside A. LDA's
local, adiabatic kernel has no comparable term — which is also why
semi-local TDDFT famously fails to bind excitons in solids. The
direction of the kernel's shift is a fingerprint of the
approximation you chose.
why does this work
The bare response χ0 is spin-blind: an
α electron and a β electron in the
same closed-shell orbital have identical energies, so every
particle-hole gap εa−εi is doubly
degenerate. Yet the TDDFT spectrum has distinct singlets and triplets.
Where does the splitting come from, mechanically?
answer
From the kernel, and only from the kernel. Write the response in the
two-component spin basis
(δρα,δρβ). The bare
χ0 is proportional to the identity in that space —
spin-blind, as stated. The coupling is not:
the Hartree interaction is spin-independent (charge talks to charge),
while fxc has distinct same-spin and opposite-spin
components fxc↑↑ and
fxc↑↓.
Diagonalizing the 2×2 spin structure gives symmetric and antisymmetric
density combinations: δρα+δρβ
(the singlet channel, coupling
vH+21(fxc↑↑+fxc↑↓))
and δρα−δρβ
(the triplet channel, coupling
21(fxc↑↑−fxc↑↓)
— the Hartree term cancels because a spin wobble moves no net charge).
Degenerate bare poles, two different kernels, two different shifted
spectra. If you set the kernel to zero, singlets and triplets collapse
back onto the same bare gaps.
predict
The Casida table lists S1 at 7.559 eV, but the FFT table from the
z-kick has no peak anywhere near 7.5 eV — its first line is 9.404 eV.
Did the propagation miss a root? Decide whether this is a bug before
revealing.
answer
Not a bug — a selection rule. The kick was polarized along
z (water's C2 symmetry axis). S1 is the
HOMO→LUMO transition 1b1 → 4a1, whose transition
density is odd under the reflection that flips the out-of-plane axis —
its dipole points perpendicular to z, and its
z-component vanishes by symmetry. A z-kick
simply cannot deposit any amplitude in that mode: the initial vector
u = [d; d] is built from the z-dipole matrix
elements, and its overlap with the S1 eigenvector is zero.
Kick along x (swap r_ao[2] for
r_ao[0]) and the 7.56 eV peak appears — and the 9.4 eV
line vanishes in turn. A real absorption spectrum averages the three
polarizations. Which roots are bright, and exactly how bright, is the
subject of oscillator strengths — the last ingredient Casida's
equation delivers.
Where this goes
This page is the bridge, and both ends of it are on this site. Behind:
ground-state DFT supplies the
orbitals and gaps,
functional derivatives define the kernel, and
linear response theory
is the poke-and-listen logic both roads share. Ahead:
Casida's equation takes the
frequency-domain road seriously — spin adaptation, the Hermitian rewrite,
triplet instabilities, oscillator strengths — and
Liouville-Lanczos
handles the regime where even building A and B is
too expensive and the spectrum must come from matrix-vector products
alone.