Questaal Home
Navigation

The Wannier-90 interface

Summary

lmf --w90 — Wannier functions via the Wannier90 library

Thu 23 Jul 18:40:35 BST 2026

Computes the overlap matrices M_mn^{k,b} and the projections A_mn^{k} in the FP-LMTO basis and drives the Wannier90 library to produce maximally-localised Wannier functions.

Use

lmf --nosym --w90~proj=1,0~proj=1,1~win=-15,2.8~nb=4~quit <ext>
OptionTypeDefaultMeaning
proj=ib,lint,intTrial orbitals: all 2l+1 partial waves of angular momentum l at site ib. Repeatable.
proj=ib,l,mint,int,intAs above but a single m, in Questaal’s real-harmonic order ilm = l²+l+m+1. For l=2: m = -2,-1,0,+1,+2 = xy, yz, 3z²-r², zx, x²-y², so with cubic axes t₂g is m = -2,-1,+1 and e_g is m = 0,+2.
nb=#intndhamPass only the lowest # bands as num_bands. Fewer bands makes disentanglement much cheaper.
win=#,#real,realwhole spectrumOuter energy window for disentanglement, eV (Wannier90 dis_win_min/dis_win_max).
froz=[#,]#real[,real]noneInner (frozen) window, eV (Wannier90 dis_froz_max, plus dis_froz_min when two values are given): froz=max or froz=min,max. States within it are kept exactly. num_wann must be at least the number of frozen states at every k.
spin=#int1Spin channel to wannierise. One Wannier calculation per run; rerun for the other.
niter=#int100Wannier90 num_iter.
dniter=#int200Wannier90 dis_num_iter.
l3mx=#int6Truncation of the Rayleigh expansion of exp(-i b·r) in the spheres. Convergence is governed by \|b\|·rmt (not lmxa); 6 is generous.
gmax=#realHAM_GMAXG cutoff for the envelope plane-wave expansion, a.u.
dumpflagoffHave Wannier90 write w90.mmn_dump, w90.amn_dump, w90.eig_dump.
checkflagoffVerify the parity invariant while assembling Omega, and report the closure sum_n \|M_mn\|² band by band.
bzeroflagoffAssemble M at b=0 and report max\|M-I\|, then stop (see below).
randflagoffReplace the projections by random ones.
quitflagoffStop after the Wannier functions are made.

num_wann is not an option: it is the length of the projector list.

Notes

  • LMTO basis only.
  • nspc = 1. Spinor/noncollinear is refused.
  • Full BZ required; run with --nosym.
  • Atom-centred projections only.
  • Local orbitals are not handled (the (phi,phidot) pair is taken as complete).

Implementation: src/fp/w90fp.F, called from bndfp.f. Wannier90 is an optional dependency in the manner of libxc/spglib: configure with wannier90[=PATH] (a wannier90 checkout or install prefix, or set WANNIER90_LIB/WANNIER90_INC); without it --w90 reports that lmf was built without the library.

Overlap matrices:

M_mn^{k,b} = <u_mk | u_n,k+b> = M_I + sum_a ( M1_a - M2_a )
  • M_I — the smooth envelope integrated over the whole cell. In G space the operator collapses to a shift, so this is a diagonal sum over G, with no interstitial overlap matrix and no linear solve. Doing it in G space rather than on a real-space mesh is necessary, not merely faster: the product of two functions cut off at gmax has content to 2*gmax, which the mesh cannot represent, and the aliased part folds onto the G=0 component being computed.
  • M1_a, M2_a — true partial waves and their smooth counterparts inside each augmentation sphere, via a Rayleigh expansion of exp(-i b·r), contracted with Gaunt coefficients.

Projections:

The projections use the partial waves themselves as trial orbitals, so the angular integral is delta_LL' and no Gaunt contraction arises:

A_mn = [ conjg(aus_1) + conjg(aus_2)*<phidot|phidot> ] / sqrt(1 + <phidot|phidot>)

Both are phase-free in the sense that no exp(i k·tau) is folded into aus; positions are absolute, which is why M carries an explicit exp(-i 2 pi b·tau_a) and A carries none.

Reference comparisons

  1. Wannier90 tutorials/tutorial02/lead.win

Atom centred s,p given, but use a random initial projection (and more iterations):

ham gmax=5.0
bz nkabc=4
iter conv=1e-7
spec
 atom=Pb z=82 r=3.3
 rsmh= 1.811 2.068 2.2 2.2 eh= -0.1 -0.1 -0.1 -0.1 rsmh2= 1.811 2.068 2.2 eh2= -0.9 -0.9 -0.9
struc nbas=1 alat=4.67775 plat=-1 0 1 0 1 1 -1 1 0
site atom=Pb pos=0 0 0
lmf --nosym --w90~proj=1,0~proj=1,1~nb=8~rand~dump~niter=1000~quit ctrl.pb
  1. Wannier90 tutorials/tutorial03/silicon.win

Frozen window to match the QE run.

bz nkabc=4
ham gmax=8.0
iter nit=25 conv=1e-7
site
  atom=Si xpos=-0.25 0.75 -0.25
  atom=Si xpos=0 0 0
spec atom=Si z=14 r=2.2
  rsmh= 1.492 1.492 1.492 1.492 eh= -0.1 -0.1 -0.1 -0.1 rsmh2= 1.492 1.492 1.492 eh2= -0.9 -0.9 -0.9
struc nbas=2 alat=5.100 plat=-1 0 1 0 1 1 -1 1 0
lmf --nosym --w90~proj=1,0~proj=1,1~nb=12~froz=2.768~dump~quit ctrl.si
  1. Wannier90 tutorials/tutorial04/copper.win

Can’t project on cell-centred s functions; reduce to 5 d-orbitals:

ham autobas[mto=4 lmto=5] gmax=7.0
bz nkabc=4
iter conv=1e-7
spec
  atom=Cu z=29 r=2.412
  rsmh= 1.608 1.608 1 1.608 eh= -0.1 -0.1 -0.1 -0.1 rsmh2= 1.608 1.608 1 eh2= -0.9 -0.9 -0.9
struc nbas=1 alat=3.411 plat=-1 0 1 0 1 1 -1 1 0
site atom=Cu pos=0 0 0
lmf --nosym --w90~proj=1,2~dump~niter=100~quit ctrl.cu
  1. SrTiO3

Require to window disentanglement and provide a frozen (inner) window for e_g states, these are given in eV to options ~win (outer) and ~froz (inner).

ham autobas[mto=14 eh=-0.5] gmax=7.0
bz nkabc=4
iter conv=1e-7 nit=25
struc nbas=5 alat=7.3692 plat=1 0 0 0 1 0 0 0 1
spec
  atom=Sr z=38 r=3.300000 lmx=3 lmxa=5
  atom=Ti z=22 r=2.089716 lmx=3 lmxa=5
  atom=O  z= 8 r=1.594872 lmx=3 lmxa=5
site
  atom=Sr pos= 0.0  0.0  0.0
  atom=Ti pos= 0.5  0.5  0.5
  atom=O  pos= 0.0  0.5  0.5
  atom=O  pos= 0.5  0.0  0.5
  atom=O  pos= 0.5  0.5  0.0
lmf --nosymm --w90~proj=2,2~win=0.0,10.0~froz=0.0,3.0~dump~quit ctrl.sto

yields:

 w90fp: spin 1  Wannier centres (Ang) and spreads (Ang^2)
    1    1.949806    1.949806    1.949806      1.719016
    2    1.949806    1.949806    1.949806      1.719027
    3    1.949806    1.949806    1.949806      1.439655
    4    1.949806    1.949806    1.949806      1.719020
    5    1.949806    1.949806    1.949806      1.439833

Plotting

with wannier90

  • rename w90.win_dump (# rename "_dump" "" *dump)
  • add a suitable path to the “w90.win” file:

      bands_plot = .true.
      begin kpoint_path
             X 0.5 0.0 0.0   G 0.0 0.0 0.0
             G 0.0 0.0 0.0   M 0.5 0.5 0.0
             M 0.5 0.5 0.0   R 0.5 0.5 0.5
             R 0.5 0.5 0.5   G 0.0 0.0 0.0
      end kpoint_path
    
  • run the standalone W90 executable (it should reproduce the spreads, etc):
  • wannier90.x w90
  • obtain the used set of used k-points:

      awk '{if(NR>1)print $1,$2,$3}' w90_band.kpt >qp.sto
    
  • run lmf in band mode:

      mpirun -- lmf --band~qp --rs=1,0 ctrl.sto
    
  • some data manipulation is needed to overlay the bands (see STO WF)