Skip to main content

The Stress Tensor in Plane-Wave DFT

The stress tensor is what you compute when the unit cell itself is a variable. It tells you which way the cell wants to deform to lower the total energy — essential for finding equilibrium lattice constants, computing equations of state, and running variable-cell molecular dynamics. In plane-wave DFT it has a particularly clean analytic form thanks to the Nielsen-Martin formalism, which derives every contribution as a strain derivative of the corresponding energy term.

Definition and units

The stress tensor σαβ\sigma_{\alpha\beta} is the negative gradient of the total energy with respect to a uniform strain tensor uαβu_{\alpha\beta} applied to the cell, divided by the cell volume:

σαβ=1ΩEtotuαβ\sigma_{\alpha\beta} = -\frac{1}{\Omega}\, \frac{\partial E_\mathrm{tot}}{\partial u_{\alpha\beta}}

Indices α,β{x,y,z}\alpha, \beta \in \{x, y, z\}. Symmetry of the stress tensor follows from conservation of angular momentum: σαβ=σβα\sigma_{\alpha\beta} = \sigma_{\beta\alpha}, giving 6 independent components (three diagonal, three off-diagonal). In KRONOS the natural unit is Ry/bohr³; the pressure (hydrostatic part) is

P=13tr(σ)14710.507GPa×P[Ry/bohr3]P = -\tfrac{1}{3}\,\mathrm{tr}(\sigma) \approx 14710.507\, \mathrm{GPa} \times P[\mathrm{Ry/bohr^3}]

A positive pressure means the cell wants to expand; a negative pressure means it wants to contract.

Strain as a deformation of the cell

A uniform strain uαβu_{\alpha\beta} maps the position r\mathbf{r} to r=(I+u)r\mathbf{r}' = (\mathbb{I} + u)\,\mathbf{r}. The cell vectors ai\mathbf{a}_i become ai=(I+u)ai\mathbf{a}_i' = (\mathbb{I} + u)\,\mathbf{a}_i, and the reciprocal vectors G\mathbf{G} transform as G=(I+u)TG(IuT)G\mathbf{G}' = (\mathbb{I} + u)^{-T}\,\mathbf{G} \approx (\mathbb{I} - u^T)\,\mathbf{G} to first order in uu. The cell volume changes as Ω=Ωdet(I+u)Ω(1+tru)\Omega' = \Omega \det(\mathbb{I} + u) \approx \Omega (1 + \mathrm{tr}\,u).

Every energy contribution that depends on cell shape — and that's all of them — produces a stress term when differentiated with respect to uu.

Decomposition: term by term

The DFT total energy in plane-wave form is

Etot=Ekin+EH+Exc+Eloc+ENL+EEwaldE_\mathrm{tot} = E_\mathrm{kin} + E_\mathrm{H} + E_\mathrm{xc} + E_\mathrm{loc} + E_\mathrm{NL} + E_\mathrm{Ewald}

Each piece contributes a piece of the stress.

Kinetic stress — from Tnk(G)=k+G2T_{n\mathbf{k}}(\mathbf{G}) = |\mathbf{k} + \mathbf{G}|^2 (Rydberg) with G\mathbf{G} depending on strain:

σαβkin=2ΩnkwkfnkG(k+G)α(k+G)βψnk(G)2\sigma_{\alpha\beta}^\mathrm{kin} = \frac{2}{\Omega} \sum_{n\mathbf{k}} w_\mathbf{k} f_{n\mathbf{k}} \sum_\mathbf{G} (k+G)_\alpha (k+G)_\beta\, |\psi_{n\mathbf{k}}(\mathbf{G})|^2

Hartree stress — from Ω1GVH(G)n(G)\Omega^{-1}\sum_\mathbf{G} V_\mathrm{H}(\mathbf{G}) n^*(\mathbf{G}):

σαβH=8πΩG0n(G)2G2[2GαGβG2δαβ]\sigma_{\alpha\beta}^\mathrm{H} = \frac{8\pi}{\Omega} \sum_{\mathbf{G} \ne 0} \frac{|n(\mathbf{G})|^2}{G^2} \left[ \frac{2 G_\alpha G_\beta}{G^2} - \delta_{\alpha\beta} \right]

The negative isotropic part reflects that uniform charge density wants to expand (Coulomb repulsion).

Exchange-correlation stress — depends on whether the functional is LDA or GGA. For LDA only the volume-change-of-density term survives:

σαβxc,LDA=δαβ1Ω[ϵxc(n)vxc(n)]n(r)d3r\sigma_{\alpha\beta}^\mathrm{xc,LDA} = \delta_{\alpha\beta}\, \frac{1}{\Omega}\, \int [ \epsilon_\mathrm{xc}(n) - v_\mathrm{xc}(n) ]\, n(\mathbf{r})\, d^3 r

For GGA, an additional term from n\nabla n enters; KRONOS computes this via the gradient of the density and the vσv_\sigma derivative returned by libxc.

Local pseudopotential stress — from the strain derivative of Vloca(G)V_\mathrm{loc}^a(\mathbf{G}) and the structure factor:

σαβloc=1ΩaGRe[n(G)eiGτa][Vloca(G)δαβ2GαGβdVloca(G)d(G2)]\sigma_{\alpha\beta}^\mathrm{loc} = \frac{1}{\Omega} \sum_a \sum_\mathbf{G} \mathrm{Re}[n^*(\mathbf{G}) e^{i\mathbf{G}\cdot\boldsymbol\tau_a}] \left[ V_\mathrm{loc}^a(\mathbf{G})\, \delta_{\alpha\beta} - 2 G_\alpha G_\beta\, \frac{d V_\mathrm{loc}^a(G)}{d(G^2)} \right]

The Coulomb tail of VlocV_\mathrm{loc} contributes an analytic correction (the same subtraction trick used in the local PP energy).

Nonlocal pseudopotential stress — Kleinman-Bylander projectors βia(k+G)\beta_i^a(\mathbf{k}+\mathbf{G}) depend on k+G|\mathbf{k}+\mathbf{G}|, which changes under strain. The strain derivative passes through the radial Bessel transform.

Ewald stress — Nielsen-Martin showed how to compute the strain derivative of the Ewald sum analytically, with both real-space and reciprocal-space pieces. The reciprocal piece has the same GαGβ/G2G_\alpha G_\beta / G^2 structure as the Hartree stress. KRONOS implements the closed-form expressions in src/potential/stress.cpp::ewald_stress().

Pressure and the equation of state

The hydrostatic pressure P=13tr(σ)P = -\tfrac{1}{3}\,\mathrm{tr}(\sigma) is what enters the enthalpy H=E+PVH = E + PV minimized by vc-relax runs. At zero target pressure, vc-relax converges to a cell where σαβ=0\sigma_{\alpha\beta} = 0 for all components. For non-zero target pressure (press_target in YAML, in GPa), KRONOS adds PtargetIP_\mathrm{target}\, \mathbb{I} to the stress and minimizes the enthalpy:

σαβeff=σαβ+Ptargetδαβ\sigma_{\alpha\beta}^\mathrm{eff} = \sigma_{\alpha\beta} + P_\mathrm{target}\,\delta_{\alpha\beta}

Driving this to zero gives the cell at the target external pressure.

Anisotropic stress and crystal symmetry

The full 3×33\times 3 tensor reveals shape-changing forces missed by a scalar pressure. A cubic crystal at equilibrium has σαβ=P3δαβ\sigma_{\alpha\beta} = \frac{P}{3}\,\delta_{\alpha\beta} purely. A tetragonal crystal forced into a cubic cell would show σxx=σyyσzz\sigma_{xx} = \sigma_{yy} \ne \sigma_{zz}. Off-diagonal σαβ\sigma_{\alpha\beta} would force a monoclinic distortion. KRONOS preserves space-group symmetry by symmetrizing the stress tensor with the same spglib operations used for forces:

σαβsym=1GRGRαγRβδσγδ\sigma^\mathrm{sym}_{\alpha\beta} = \frac{1}{|G|} \sum_{R \in G} R_{\alpha\gamma} R_{\beta\delta}\, \sigma_{\gamma\delta}

over the point group GG of the cell. This eliminates symmetry-breaking floating-point noise and ensures vc-relax converges along symmetry-preserving paths.

Variable-cell relaxation in KRONOS

vc-relax optimizes both atomic positions and cell vectors simultaneously, using a (3N+6)(3N + 6)-dimensional BFGS quasi-Newton step (3 atomic-position dimensions plus 6 unique strain components). At each step:

  1. Run SCF to convergence on the current cell.
  2. Compute forces and the full stress tensor.
  3. Symmetrize both.
  4. Compute the enthalpy gradient and BFGS step.
  5. Apply the strain to the cell; move atoms.
  6. Repeat until maxFa<tolF\max|\mathbf{F}_a| < \mathrm{tol}_\mathrm{F} AND maxσαβ+Ptargetδαβ<tolσ\max|\sigma_{\alpha\beta} + P_\mathrm{target}\,\delta_{\alpha\beta}| < \mathrm{tol}_\sigma.

Implementation: src/solver/vc_relax.cpp.

How KRONOS implements this

The stress calculation lives in src/potential/stress.cpp. Each contribution (kinetic, Hartree, XC, local PP, nonlocal PP, Ewald) is computed by a dedicated function and accumulated into the 6-component Voigt-style tensor. The total stress is exposed via StressResult::tensor() (3×3 matrix) and StressResult::pressure_gpa() (scalar).

KRONOS has unit-test coverage for each component on a Si bulk cell, asserting agreement with QE stress to within 105Ry/bohr310^{-5}\,\mathrm{Ry/bohr^3}.

References

  • Nielsen, O. H. & Martin, R. M. "Quantum-mechanical theory of stress and force", Phys. Rev. B 32, 3780 (1985).
  • Nielsen, O. H. & Martin, R. M. "Stresses in semiconductors: Ab initio calculations on Si, Ge, and GaAs", Phys. Rev. B 32, 3792 (1985).
  • Dal Corso, A. "Density-functional perturbation theory with ultrasoft pseudopotentials", Phys. Rev. B 64, 235118 (2001) — stress with USPP/PAW.
  • Wentzcovitch, R. M. "Invariant molecular-dynamics approach to structural phase transitions", Phys. Rev. B 44, 2358 (1991) — variable-cell MD.
  • Martin, R. M. Electronic Structure, Ch. 9.