home

Kohn Sham Cycle

This diagram illustrates the Kohn-Sham cycle in Density Functional Theory (DFT), a computational quantum mechanical modeling method. The process starts with an initial guess for the electron density, which is used to calculate the effective potential. This potential is then used in the Kohn-Sham Hamiltonian, which is solved to obtain the wavefunctions. These wavefunctions are used to compute a new electron density. If convergence criteria are met, the final electron density is used to calculate the total energy functional. If not, the new electron density is used for the next iteration of the cycle.


Kohn Sham Cycle

Download

PNG PDF SVG

Code

kohn-sham-cycle.typ (140 lines)

#import "@preview/cetz:0.5.2": canvas, draw
#import draw: content, line, on-layer, rect

#set page(width: auto, height: auto, margin: 8pt, fill: none)
#set text(size: 12pt)

#canvas({
  rect(
    (-4, -6),
    (4, 3.25),
    frame: "rect",
    stroke: (dash: "dashed"),
    fill: none,
    width: 22em,
    height: 12em,
    name: "enclosure",
    radius: 5pt,
  )

  // Enclosure label
  on-layer(1, content(
    "enclosure.north",
    text(weight: "bold", size: 16pt)[Kohn-Sham method],
    frame: "rect",
    stroke: .5pt,
    fill: rgb("#cdd3da"),
    padding: 3pt,
  ))

  let box-style = (
    frame: "rect",
    stroke: .5pt,
    fill: rgb("#DCDCDC"),
    padding: 8pt,
    width: 15em,
  )

  let arrow-style = (
    mark: (end: "stealth", fill: black, scale: .5),
    stroke: 1pt,
  )

  // Initial density box
  content(
    (rel: (0, 1.25), to: "enclosure.north"),
    [Supply initial density guess\ $rho_"init" (arrow(r))$ to Kohn Sham equations],
    ..box-style,
    fill: rgb("#c6aa0c").lighten(60%),
    width: 20em,
    name: "initial",
    padding: (3pt, 2em, 0),
    radius: 1em,
  )

  let chain = (
    (
      name: "potential",
      offset: -2,
      body: [$v_("ext,s") (arrow(r))=v_H (arrow(r)) + v_"xc" (arrow(r)) + v_"ext" (arrow(r))$],
    ),
    (
      name: "hamiltonian",
      offset: -1.25,
      body: [$hat(H)_"KS"=-frac(planck^2, 2m)arrow(nabla)^2 + v_("ext,s") (arrow(r))$],
    ),
    (
      name: "schrodinger-eq",
      offset: -1.25,
      body: [$hat(H)_"KS" phi_i (arrow(r))= E_i phi_i (arrow(r))$],
    ),
    (
      name: "density",
      offset: -1.25,
      body: [$rho (arrow(r))=sum_(i=1)^n f_i |phi_i (arrow(r_i))|^2$],
    ),
    (name: "criterion", offset: -1.25, body: [Convergence criterion satisfied?]),
  )
  let parent = "initial"
  for box in chain {
    content(
      (rel: (0, box.offset), to: parent + ".south"),
      box.body,
      ..box-style,
      name: box.name,
    )
    parent = box.name
  }

  // Final energy box
  content(
    (0, -7.5),
    [Use $rho_"final" (arrow(r))$ to minimize total energy functional\
      $E_(V_"ext")[rho] = T_(e,s)[phi_i {rho}] + V_(e e,H) [rho] + E_"xc" [rho] + V_"eI" [rho]$],
    ..box-style,
    fill: rgb("#54aef8").lighten(30%),
    width: 20em,
    name: "energy",
    padding: (4pt, 2em, 1pt),
  )

  for (start, end) in (
    ("initial", "potential"),
    ("potential", "hamiltonian"),
    ("hamiltonian", "schrodinger-eq"),
    ("schrodinger-eq", "density"),
    ("density", "criterion"),
  ) { line(start, end, ..arrow-style) }
  line("criterion", "energy", ..arrow-style, name: "converged-yes")

  // Yes/No labels
  content(
    (rel: (0.1, 0), to: "converged-yes.60%"),
    [Yes],
    frame: "rect",
    stroke: none,
    anchor: "west",
    padding: (
      3pt,
      2pt,
    ),
  )

  // No feedback loop
  line(
    "criterion",
    (3.6, -5),
    (3.6, 2),
    "potential",
    ..arrow-style,
    name: "converged-no",
  )
  content(
    "converged-no.13%",
    [No],
    frame: none,
    anchor: "north-east",
    padding: (-1pt, 2pt),
  )
})