Skip to content

lmf,lmfa,lmchk

⚠️ TOML migration (2026-05)lmf, lmfa, lmchk now read ctrlg.<sname>.toml only. The ctrl.<sname> examples below are legacy syntax kept as developer reference; convert with Legacy2toml.py <sname> before invoking these binaries. See TOML migration for the full guide and migrated Samples/.

We need an input file ctrlg.<sname>.toml (legacy: ctrl.<sname>).
<sname> is the positional argument passed to the binary (e.g. lmf si reads ctrlg.si.toml); the rest of this page uses <sname> as a placeholder for whatever material extension the user chose at Legacy2toml.py / ctrlgenToml.py time.

lmfa: spherical atom calculations

Example:`

lmfa si

It finishes instantaneously.

lmfa si |grep conf

shows electronic configurations. It gives electron densities of spherical atoms contained in the primitive cell specified by . With the superposition of the densities From which, we construct initial electronic density for lmf. In addition,lmfa generates

lmchk: Check crystal symmetry.

lmchk gives useful information of space group symmetry recognized by lmf. In addition, it determines MT radius.The space-group operations are explained at SYMGRP.

MT radius determined by lmchk

The ideal choice of sphere radii best approximates a potential that is spherical within the MT spheres and flat outside. Program lmchk has implemented one algorithm that makes a reasonable initial choice for MT radii. The algorithm works by computing the (electrostatic) potential obtained from overlapping free-atom densities along all connecting vectors between a given site and its relatively near neighbors. The MT radius is taken as the first potential maximum along any ray. This choice is a pretty reasonable estimate for the potential being approximately spherical inside. Also, note that for a completely symmetric bond, the potential maximum will fall exactly midway between the bond, so for that case the two sphere radii will exactly touch and have equal potentials. To tell lmchk to find these radii, invoke lmchk as lmchk --getwsr. This is performed automatically in ctrlgenToml.py (and the legacy ctrlgenM1.py).

  • In addition, ctrlgenToml.py enforces a limit on the maximum radius for alkali atoms, to avoid the linear-dependency problem between APWs and MTOs.

  • When we treat molecules (especially dimers), we have to use very small size of MT radius. T.Kotani checked PMT works well even for such systems. However, we need examination a little more.

lmf: Solve one-body problem.

This is for band calculation in LDA/GGA and LDA+U. In addition, we can add the potential term for QSGW via sigm.<sname>.

Example:

mpirun -np 4 lmf si [options] > llmf

This is a case with ctrlg.si.toml.

options

  • quit option at some point. --quit=band, --quit=ldau... We need to do 'grep cmdopt SRC//.f90|grep quit' to know details.
  • --tdos total dos calculation. But we usually use `job_tdos'
  • --ctrlg:<dotted.path>=<value> : Runtime override of a key in ctrlg.<sname>.toml. The path uses dotted TOML syntax (e.g. --ctrlg:bz.nkabc=[8,8,8], --ctrlg:ham.scaledsigma=0.8, --ctrlg:ham.phispinsym=true, --ctrlg:verbose=50, --ctrlg:spec.1.r=2.5 for the 1st [[spec]]). Substituted into the in-memory TOML before parsing; the file on disk is untouched. Each applied override is logged on rank 0. Older syntaxes (-vfoo=val, -v[<path>]=val, --[<path>]=val, --toml.<path>=val, --pr=N, --time=N,M, --phispinsym) abort with a one-line migration hint.

We have some kinds of options for electron density plot, boltztrap and so on. (not yet described).

Input files

(<sname> is the positional argument of lmf, e.g. si for lmf si reading ctrlg.si.toml.)

  • syml.<sname> symmetry line for band plot (usually job_band calls lmf internally)
  • sigm.<sname> a part of QSGW calculation
  • atmpnu.{1,2,3}.<sname> generated by lmfa (when [ham] readp = true)

Output files

  • rst.<sname> restart file, containing density and related information. Together with ctrlg.<sname>.toml, atmpnu*, sigm*, and rst* we can resume an lmf calculation. (dmat* is used for LDA+U.)

  • save.<sname> Minimal iteration history for lmf / lmfa / lmchk, with total energies for each lmf SCF step.

  • __mix.<sname> mixing file for electron density. When you stop iteration at the middle, you may need to delete this. mixm retains prior iterations of sets of input and output moments. Used by the Anderson or Broyden mixing scheme to accelerate convergence towards self-consistency. Usually you should delete these when starting a new calculation (such as changing the lattice constant) so it doesn't get used in subsequent runs.

** Main Source** : SRC/main/lmf.f90

ctrlg.<sname>.toml — current input format (2026-05+)

lmf, lmfa, lmchk read TOML only since 2026-05. The single file ctrlg.<sname>.toml carries everything that used to live in ctrl.<sname> plus the GW driver and product-basis sections that used to live in GWinput, including the per-atom product-basis tables that close the file. Run Legacy2toml.py <sname> inside any old working directory to generate it.

The [product_basis] tables nlx / valence / core are for the GW path (consumed by hbasfp0 / hvccfp0 / etc. when generating the mixed product basis). They are written by gwinit (through ctrlgenToml.py or Legacy2toml.py) and do not normally need hand editing; the cut-offs pb_tolerance / pb_lcutmx above them are what you tune. (Before 2026-09 the tables were a separate PB.<sname>.toml.)

File structure (sections)

toml
# Top-level scalars
symgrp  = "find"        # space-group spec: 'find' = auto-detect
verbose = 35            # console verbosity
time    = [0, 0]        # CPU timing log: [depth, on-the-fly]

[struc]   alat / plat                              (nspec / nbas auto-derived from arrays)
[[site]]  atom / pos / xpos / af / relax           (one table per atom)
[[spec]]  atom / z / r / rsmh / eh / lmx / ...     (one table per species)
[bz]      nkabc / metal / tetra / npts / ...
[iter]    nit / mix / b / conv / convc / umix / tolu
[ham]     nspin / rel / so / phispinsym / xcfun / gmax / pwmode / pwemax / oveps / ...
[esm]     boundary / origin / shiftmode / zb / potential / field   (slabs only)
[gw]      n1n2n3 / QpGcut_psi / HistBin_dw / iSigMode / niw / esmr / GaussSmear / ...
          QforEPS / QforGW (multi-line q lists)
[mlo]     mlo_method / mlo_delta / mlo_w / mlo_nkabc (required for job_mlo) / mlo_lm (formerly Worb)
[blocks]  QPNT, QforEPSL, hrotr (raw multi-line blocks with no better home)
[product_basis]   pb_tolerance / pb_lcutmx + nlx / valence / core   (always the last section)

Worked example: bcc-Cu (FCC, 1 atom, non-magnetic)

The full ctrlg.cu.toml from Samples/EPS/EPS_Cu/ is shown below. Inline # comments document each key's role; copy-paste the file as a starting point for FCC monatomic metals and adjust [spec], [bz], [ham] to your case.

toml
# Top-level scalars
symgrp  = "find"  # 'find' = auto-detect space group from lattice + species
verbose = 35      # 31 default, 35 verbose, 41+ debug
time    = [0, 0]  # CPU timing log: [depth, on-the-fly]

[struc]
alat  = 6.798     # lattice constant (a.u.)
plat  = [[0.0, 0.5, 0.5],   # primitive vectors in units of alat
         [0.5, 0.0, 0.5],
         [0.5, 0.5, 0.0]]

[[site]]
atom = "Cu"
pos  = [0.0, 0.0, 0.0]

[[spec]]
atom   = "Cu"
z      = 29
r      = 2.33    # MT radius (a.u.)
rsmh   = [1.17, 1.17, 1.17, 1.17]   # smoothing radii per l
eh     = [-1.0, -1.0, -1.0, -1.0]   # tail energies
rsmh2  = [1.17, 1.17, 1.17]         # second basis group
eh2    = [-2.0, -2.0, -2.0]
lmx    = 3       # basis l-cutoff
lmxa   = 4       # augmentation l-cutoff
nmcore = 1       # 1: spin-averaged core; 0: spin-polarized core
kmxa   = 5       # radial expansion order at tail sites

[bz]
nkabc  = [12, 12, 12]   # k-mesh divisions; 1 entry => isotropic
metal  = 3              # 0 insulator, 3 tetra+broadening (safe metal)
savdos = true           # write dos.tot.* file
npts   = 2001
dosmax = 1.5

[iter]
nit   = 30        # max self-consistency iterations
mix   = "A2"      # B3 = Broyden hist=3 (default); A2 = Anderson hist=2
conv  = 1e-05     # max dE between iterations (Ry)
convc = 1e-05     # max d(rho_out - rho_in) (Ry)
b     = 0.2       # mixing ratio

[ham]
nspin       = 1   # 1 nonmag, 2 spin-polarized (then spec.mmom seeds)
rel         = true
so          = 0   # 0 none, 1 L.S, 2 Lz.Sz
gmax        = 12.0   # real-space mesh G-cutoff (Ry); alt: ftmesh
frzwf       = false
xcfun       = 1   # 1=VWN, 2=Barth-Hedin, 103=PBE-GGA
forces      = 0
scaledsigma = 1.0   # QSGW mixing: 1.0 full, 0.8 = QSGW80
oveps       = 0.0
pwmode      = 1   # 0=MTO 1=PMT 2=APW 11=PMT(|q+G|, default) 12=LAPW
pwemax      = 3.0  # APW cutoff (Ry)

# === GW driver (used by lmf --jobgw=N and gwsc) ===
[gw]
n1n2n3        = [10, 10, 10]   # GW BZ mesh (typically smaller than [bz].nkabc)
QpGcut_psi    = 3.0     # |q+G| cutoff for eigenfunctions
QpGcut_cou    = 2.0     # |q+G| cutoff for Coulomb / W
unit_2pioa    = false   # false: a.u.;  true: 2*pi/alat
HistBin_dw    = 1e-05   # bin width on real-axis at omega=0
HistBin_ratio = 1.03
iSigMode      = 3       # self-energy mode (3 = standard QSGW)
niw           = 10      # # of imag-axis frequencies
delta         = -1e-06
deltaw        = 0.02
esmr          = 0.003   # hsfp0 smearing
GaussSmear    = true
QforEPS = """           # q points for eps (a.u. if QforEPSau = true)
 0 0 0.00050
 0 0 0.00100
 0 0 0.00200
"""
QforGW = """            # q points for the one-shot GW driver (gw_lmfh)
 0.0 0.0 0.0
 0.1 0.0 0.0
"""

# === MLO (muffin-tin based localized orbitals; see manual/mlo) ===
[mlo]
mlo_method = 4          # theta = sigma((eps - ecut_j)/mlo_w), ecut_j = max(CBM + mlo_delta, eps^MTO_j)
mlo_delta  = 2.0        # (eV) how far above the band edge the model must be accurate
mlo_w      = 2.0        # (eV) width of the fall-off; the knob if the residual is too large
mlo_lm     = """        # which lm channels of which atom make the model (1=s, 2-4=p, 5-9=d, 10-16=f)
  1 Cu   5 6 7 8 9
"""

[product_basis]
pb_tolerance = [0.001]  # drop near-linear-dep products (default 1e-3)
pb_lcutmx    = [4]      # max l-cutoff per atom
# ----------------------------------------------------------------
# nlx [iatom, l, nnvv, nnc] ... (per-atom tables written by gwinit; see manual/gwsc)
nlx = [
  [1, 0, 2, 3],
  [1, 1, 2, 2],
  [1, 2, 2, 0],
  [1, 3, 2, 0],
  [1, 4, 2, 0],
]
# ----------------------------------------------------------------
valence = [
  [1, 0, 1, 1, 1],   # 4s_phi
  [1, 0, 2, 0, 0],   # 4s_phidot
  # ...
]
# ----------------------------------------------------------------
core = [
  [1, 0, 1, 0, 0, 0, 0],   # 1S
  # ...
]

(QforEPS / QforGW, the q-point lists, sit at the end of [gw] as multi-line strings; the example above shows them.) That's the entire input.

Layout convention of the generated files (ctrlgenToml.py, gwinit, Legacy2toml.py and the formatter pylib/toml_tidy.py all produce it): a blank line separates only the big headings — the # === X === comment runs and single [section] headers — while everything inside a section (one [[site]] or [[spec]] table from the next, a multi-line block from its neighbours, the three product-basis tables) is divided by a # ---- rule instead. The example above is abridged; real files carry the # === headers and rules. A [blocks] section only appears for the few legacy <...> tags that have no better home (QPNT, QforEPSL, hrotr), kept as multi-line strings and parsed opaquely by the GW driver; when present it sits between [mlo] and [product_basis], which always closes the file (toml_tidy.py enforces the order [gw] [mlo] [blocks] [product_basis]).

Per-physics deltas (from the Cu starting point)

  • Spin-polarized metal (Fe, Ni, FeCo): set [ham].nspin = 2 and add mmom = [0, 0, 2.5] (or per-l guess) to each [[spec]]. Start from a clean directory: lmf keeps its mixing history in __mixm.<sname>, and a history left by a run that ended non-magnetic drags the new run onto the non-magnetic solution at the first Broyden step (Fe: 2.13 → 0.02 μB). Since 2026-09-18 lmf deletes __mixm.<sname> at start (the hidden --keepmixm keeps it), so only the density rst.<sname> carries over; if you change nspin on top of an existing rst, delete rst.<sname> first. The default mix = "B3", b = 0.2 is fine.
  • SOC (HAM_SO): set [ham].so = 1 (full L·S) or 2 (Lz·Sz only), with [ham].nspin = 2. See Samples/MLOsamples/FeSoc/.
  • Insulator / semiconductor (Si, GaAs): [bz].metal = 0 and [bz].tetra = true; smaller [bz].nkabc; [ham].pwemax ~3 is enough.
  • LDA+U: add idu = [0, 0, 2, 2], uh = [0, 0, 0.1, 0.632], jh = [0, 0, 0, 0.055] to [[spec]]. dmatu.<sname> is read separately if present.
  • Atomic-position relaxation: [dyn].mode = 4 (CG) or 6 (Broyden), set [[site]].relax = [1, 1, 1] per atom.
  • GW BZ mesh: keep [gw].n1n2n3[bz].nkabc (often 1/2 or 2/3 of it) — n1n2n3 dominates GW wall-time.

Run-time -v overrides

The legacy -v<NAME>=<VAL> (where <NAME> was a %const symbol baked into ctrl.<sname>) is replaced by bracketed dotted-path syntax processed in-memory by m_toml_override.f90:

bash
# OLD (legacy ctrl + %const)
lmf si -vnk=8 -vmetal=3 -vnspin=2 -vso=0

# NEW (ctrlg.toml + path syntax)
lmf si --ctrlg:bz.nkabc=[8,8,8] --ctrlg:bz.metal=3 --ctrlg:ham.nspin=2 --ctrlg:ham.so=0

The bracketed key is the dotted TOML path ([section.key] or [section.subkey]); the right-hand side parses as TOML ([8,8,8] for an integer vector, 1 for an int, 1.0 for a float, "r4z r3d r2x" for a string). No on-disk rewrite of the .toml file takes place.

Legacy ctrl.<sname> ↔ TOML path map

Most legacy Category_Token keys map 1:1 onto [section.key] after lower-casing. A few are renamed or restructured:

legacy Category_TokenTOML locationnote
STRUC_ALAT / STRUC_PLAT[struc].alat / .plat
SITE_ATOM=, POS=, XPOS=[[site]] atom = ...; pos = [...] (or xpos)one [[site]] table per atom
SPEC_ATOM=, Z=, R=, RSMH=, EH=, ...[[spec]] atom = ...; z = ...; r = ...; rsmh = [...]one [[spec]] table per species; R/W= and R/A= kept as "r/a" quoted-key
BZ_NKABC / BZ_METAL / BZ_TETRA[bz].nkabc / .metal / .tetra
HAM_NSPIN / HAM_SO / HAM_XCFUN / HAM_GMAX / HAM_PWMODE / HAM_PWEMAX[ham].nspin etc.
HAM_FORCES / HAM_OVEPS / HAM_FRZWF / HAM_REL[ham].forces etc.
HAM_ScaledSigma[ham].scaledsigmalowercase
HAM_READP / HAM_PNUFIX / HAM_V0FIX[ham].readp etc.
esm_input.dat (separate positional file)[esm] sectionretired 2026-09-16; not read — ctrlg_absorb.py <sname> converts it, see ESM
ITER_NIT / ITER_MIX / ITER_CONV / ITER_CONVC / ITER_UMIX / ITER_TOLU[iter].nit / .mix / ...
SYMGRP / SYMGRPAFtop-level symgrp = "..." (and symgrp_af)not nested in a section
EWALD_TOL[ewald].tolrarely touched
DYN_MODE / DYN_NIT / DYN_HESS / ...[dyn].mode etc.
IO_VERBOS / IO_TIMtop-level verbose / timepromoted out of [io] (section dropped)
<Worb>...</Worb> block[mlo].mlo_lm = """ ... """multi-line string
<QforEPS>...</QforEPS> block[gw].QforEPS = """ ... """ (likewise QforGW)
n1n2n3 (GWinput)[gw].n1n2n3 = [k1,k2,k3]int vector
HistBin_dw / HistBin_ratio / niw / delta / esmr / GaussSmear (GWinput)[gw].HistBin_dw etc.unchanged names, lowercased
product-basis cut-offs (tolerance, lcutmx from <PRODUCT_BASIS>)[product_basis].pb_tolerance / .pb_lcutmx
product-basis per-atom tables (nlx, valence, core)[product_basis].nlx / .valence / .core (end of the file; a separate PB.<sname>.toml before 2026-09)

The full schema lives in SRC/exec/ctrl_schema.py (the conversion source of truth). Annotations / inline comments are applied by SRC/exec/toml_comments.py.


ESM (Effective Screening Medium)

A slab with a vacuum layer is not a periodic crystal, but a plane-wave / smooth-density code solves Poisson's equation as if it were. ESM (Otani & Sugino, PRB 73, 115407 (2006); implemented here by M. Obata, Kanazawa Univ.) replaces the periodic Green function of the electrostatics with one that carries the boundary condition you actually want — vacuum, or a metal electrode — on each side of the slab. ESM combined with QSGW is used in PRB 101, 205120 (2020).

Turn it on for every slab with a vacuum layer. Without it the G=0 component of the Coulomb potential is fixed by the periodic convention instead of by the vacuum level, and the whole eigenvalue spectrum shifts. The shift is not small: on the Samples/MLOsamples/FeMgO slab (30.5 a.u. of vacuum) it is 4.4 eV, while the total energy, Vesav and the magnetic moment all agree to 8–13 digits, so nothing looks wrong until you compare Fermi energies. Two directories that differ only in whether ESM was on will produce band plots on different energy zeros.

The [esm] section

toml
[esm]
boundary  = "vac/slab/vac"  # vacuum(-z)/slab/vacuum(+z)
origin    = -8.63717        # (a.u.) z-translation of the density
shiftmode = 0               # 0: origin is absolute, 1: in units of the cell length
zb        = [23.907104, -23.907104]   # (a.u.) boundaries z1esm, z2esm
potential = [0.0, 0.0]      # (Ry) on the +z / -z sides
field     = [0.0, 0.0]      # (Ry/a.u.) on the +z / -z sides

No [esm] section at all means ESM is off. That is the right thing for a bulk crystal and the wrong thing for a slab, so lmf prints a warning when c is more than 3× the longer of a, b and no [esm] is present.

ctrlgenToml.py writes a commented-out [esm] template (with the # === ESM heading and one line per key) into every new file, right after [ham]; for a slab, uncomment it and set the numbers with care. A bulk crystal leaves it commented — no [esm] section means ESM off.

keymeaninglegacy esm_input.dat
boundarywhich boundary condition on each side (table below)line 1, jesm
originz-translation applied to the density before solving. The code uses -origin internally, so this is the same number as line 2 of the old fileline 2, tresm
shiftmode0: origin is in a.u.; 1: in units of the cell lengthline 2, jtresm
zbthe two boundary planes z1esm, z2esm in a.u. Omit to get ±alat·plat[2][2]/2line 3
potentialfixed potential on the +z / -z side (Ry). Used by metal/... and the :v-e / :e-v formsline 4
fieldfixed electric field on the +z / -z side (Ry/a.u.). Used by the :field formline 5

boundary values

valuesystemjesm
"off" (or the section absent)ESM disabled — plain periodic0
"vac/slab/vac"vacuum on both sides1
"metal/slab/metal"metal electrode on both sides2
"vac/slab/metal"vacuum on −z, metal on +z3
"metal/slab/vac"metal on −z, vacuum on +z4
"vac/slab/vac:field"vacuum both sides, field imposed5
"metal/slab/metal:v-e"potential on −z, field on +z6
"metal/slab/metal:e-v"field on −z, potential on +z7
"periodic:esm"same result as off, computed through the ESM path10

A bare integer is also accepted, so mechanically converted files keep working; the strings are preferred because 1 and 3 are not distinguishable by eye.

To apply an electric field to a slab, use "vac/slab/vac:field" with field = [E, -E], or hold the two electrodes at fixed potentials with "metal/slab/metal" and potential = [V1, V2].

Migration from esm_input.dat

Before 2026-09-16, ESM was configured by a separate positional file esm_input.dat — six lines of bare numbers with no keys. It had two problems: you could not tell what the numbers meant without reading esmsmves.f90, and a missing file disabled ESM silently (lmf printed one line and carried on). Copying a sample directory without that one file therefore changed the physics without any error.

The Fortran reads ctrlg.<sname>.toml and nothing else (since 2026-09-17; for one day in between lmf converted the file itself). A leftover esm_input.dat makes lmf / lmfa / lmchk abort with a message naming the converter — abort rather than ignore, so a slab never runs without ESM by accident:

bash
ctrlg_absorb.py <sname>      # esm_input.dat -> [esm] in ctrlg.<sname>.toml
                             # (and PB.<sname>.toml -> [product_basis], if present)
situationwhat ctrlg_absorb.py does
ctrlg.<sname>.toml already has [esm]the TOML wins. esm_input.dat is moved to esm_input.dat.bk, whose header records that its settings were not used
no [esm] in the TOMLthe file is converted, the [esm] block is inserted (with comments, before the GW sections), and the original is moved to esm_input.dat.bk with a header saying where it went

Legacy2toml.py performs the same conversion when it migrates a legacy directory.

Worked example — Fe/MgO slab

Samples/MLOsamples/FeMgO (c/a = 8.50, 30.5 a.u. of vacuum, 7 empty spheres filling it):

toml
[esm]
boundary  = "vac/slab/vac"
origin    = -8.63717
shiftmode = 0
zb        = [23.907104, -23.907104]   # alat*plat[2][2]/2 = 23.903861; set by hand here
potential = [0.0, 0.0]
field     = [0.0, 0.0]

With and without this section, on the same rst.<sname>:

E_F (Ry)Vesav (eV)val*vef (Ry)
[esm] present−0.38286150−2.12295183−257.64
[esm] absent−0.05833040−2.12295183−253.66

Vesav agrees to 8 digits, so the density and the electrostatics are the same — only the zero of energy moves, by 0.3245 Ry = 4.4155 eV. Check llmf_ef (or any lmf log) for which one you got:

effective screening medium method jesm=  1        <- ESM on
system : vaccum(-z)/slab/vaccum(+z)

esmsmves: ESM is off (no [esm] section in ctrlg.<sname>.toml)   <- ESM off

Where it is implemented

SRC/subroutines/esmsmves.f90 (the solver; called from smves) and SRC/subroutines/m_lmfinit.f90::readesm (reads [esm], runs the migration).


LDA+U (TOML)

LDA+U is selected per species by writing the idu, uh, jh vectors into each [[spec]] table. Indices [s, p, d, f]:

toml
[[spec]]
atom = "Er"
z    = 68
r    = 3.00
# ... rsmh, eh, ... ...
idu  = [0, 0, 2, 2]          # 0 = none, 1 = AMF, 2 = FLL.  +10 disables when sigm.* exists
uh   = [0.0, 0.0, 0.10, 0.632]    # Hubbard U (Ry)
jh   = [0.0, 0.0, 0.00, 0.055]    # exchange J (Ry)

Mode codes (idu[l]):

  • 0 — no U on this l-channel
  • 1AMF (Around-Mean-Field), Petukhov, PRB 67, 153106 (2003)
  • 2FLL (Fully Localized Limit), Liechtenstein, PRB 52, R5467 (1995)
  • 12 / 21 / ... — same code +10 means "skip LDA+U when sigm.<sname> exists" (so a QSGW run with sigm falls back to plain QSGW).

dmatu.<sname> (density matrix) is read & written automatically — it is the LDA+U analogue of rst.<sname>. A first-shot LDA run without U populates it. You can override the initial occupation by hand-writing occnum.<sname> (one line of 2l+1 numbers per spin) — see the legacy LDA+U notes for the ErAs example and the spin-configuration hazard.

Mixing of the dmat happens independently of the charge with linear mixing:

toml
[iter]
umix = 0.2          # dmat mixing beta (0..1)
tolu = 0.0          # rms tol where dmat mixing stops (0 = always mix)

Check the dmat once with lmf <sname> --quit=dmat — it stops after the initial setup and prints the matrix without writing any restart files.

Core hole (TOML)

Partial core-hole occupancy implements Slater transition-state ideas (useful for XAS / unbinding 4f). Set per species:

toml
[[spec]]
atom    = "Nd"
z       = 60
r       = 3.00
p       = [0.0, 0.0, 0.0, 5.2]    # treat 4f as core, 5f as valence
c_hole  = "4f"                     # core channel to perturb
c_hq    = [-11.0]                  # excess electron charge in that channel
# c_hq    = [-7.0, 7.0]            # optional 2nd entry = spin moment

Charge bookkeeping:

Q(spin1) = full_core_count + c_hq[1]/2 + c_hq[2]/2
Q(spin2) = full_core_count + c_hq[1]/2 - c_hq[2]/2

Negative c_hq[1] removes electrons (a hole); the optional c_hq[2] polarises the core (used e.g. for the Gd 4f trick — c_hq = [-7, 7] freezes 7-up / 0-down in the 4f core while 5f remains valence).

Confirm neutrality with lmfa <sname> | grep -i 'add core hole'. See the legacy core-hole walkthrough for the full Gd / Nd / CrN case study.

Local orbitals (TOML)

The local-orbital channel pz is the analog of the continuously-variable principal quantum number p. Both are per-species, per-l vectors in [[spec]]:

toml
[[spec]]
atom = "Ga"
# p[0..3] = s,p,d,f valence principal quantum numbers (continuous);
#          fractional part 0.5 = mid-band, ->0 = bottom, ->1 = top.
p   = [0.0, 0.0, 4.0, 0.0]       # 4d "valence-like"
# pz[0..3] = semicore (lower n) or high-lying (higher n) local-orbital prinq;
#           fractional part ~0.9 = semicore, ~0.3 = high-lying.
pz  = [0.0, 0.0, 3.9, 0.0]       # 3d treated as semicore local orbital
# add 10 to pz[l] to attach a smooth-Hankel tail (extended local orbital).

Notes:

  • Integer part of pzp controls the principal quantum number used for the radial function (semicore → int(pz) = int(p) − 1, high-lying → int(pz) = int(p) + 1).
  • Fractional part: 0.9 for semicore, 0.3 for high-lying is the common choice; smaller fractional ⇒ lower linearization energy.
  • pz[l] + 10 (i.e. write pz = [0, 0, 13.9, 0]) attaches a smooth-Hankel tail (extended local orbital). Use this when the deep state spills into the interstitial.
  • Verify the configuration with lmfa <sname> | grep -i conf — the line shows which states are treated as core / valence / lo.

Common pitfalls:

  • Conventional (non-extended) local orbitals on semicore states rely on the valence envelope for representation outside the MT sphere — keep at least one rsmh for that l small (~1) with eh rather negative (~-1).
  • Extended-lo matching can fail ("mtchre: failed to match phi'/phi") when the fractional part of pz is too close to 1.0 — reduce it (e.g. 0.98 → 0.85).
  • The p with the higher principal quantum number is automatically frozen — only the deepest state is allowed to float (controlled by idmod).

See the legacy local-orbital notes for the historical sm-Hankel mtchre discussion.

SYMGRP / symgrp — space-group specification

In TOML the space-group spec is the top-level symgrp string:

toml
symgrp     = "find"           # auto-detect from lattice + species (default)
symgrp_af  = "R4z*I"          # extra generator for AF symmetry (optional)

symgrp either takes the literal string "find" (auto-detect) or a space-separated list of generators. The generators are the same as the legacy SYMGRP token:

  • R<n>X, R<n>Y, R<n>Z, R<n>Dn-fold rotation around X, Y, Z, (1,1,1).
  • M<axis> — mirror.
  • I — inversion.
  • <axis> = X | Y | Z | D | (nx,ny,nz) — pick a Cartesian axis or an explicit direction.
  • Products with *, e.g. I*R4X.
  • Translations: r6z:(0,0,0.4778973) (Cartesian) or r6z::(0,0,1/3) (fractional, multiples of plat).

Example (cubic):

toml
symgrp = "R4X MX R3D"        # 4-fold around X, mirror in X, 3-fold around (1,1,1) ⇒ 48 symops

Mix-and-find:

toml
symgrp = "R4X find"          # force 4-fold around X then let lmf find the rest

Disable symmetry entirely:

toml
symgrp = "e"

lmchk prints the recognised symops at the top of its console output — use it to verify the symmetry was parsed as intended. The inversion is implicit in the DFT path when the potential is local; pay attention to the inversion-related notes in the console banner.

Q: Should the Harris-Foulkes and Hohenberg-Kohn Sham functionals agree at self-consistency?

(due to Mark van Schilfgaarde) A: Yes. If they do not, either you have not reached self-consistency, or a tolerance is set too loosely in the evaluation of the matrix elements. A likely culprit is that the mesh of points for the interstitial integrals is not fine enough. Here is part of an output where mesh of 14x14x14 divisions were used for the interstitial density.

 GVLIST: gmax = 4.702 a.u. created 973 vectors of 2744 (35%)
         mesh has 14 x 14 x 14 divisions; length 0.588, 0.588, 0.668
 SGVSYM: 170 symmetry stars found for 973 reciprocal lattice vectors
...

 sugcut:  make orbital-dependent reciprocal vector cutoffs for tol= 1.00E-05
 spec      l    rsm    eh     gmax    last term    cutoff
  Te       0*   1.30  -0.10   5.220    9.30E-05     973*
  Te       1*   1.30  -0.10   5.597    4.36E-04     973*
  Te       2    1.30  -0.10   5.976    2.04E-03     973*
  Te       0*   1.40  -1.00   4.847    2.11E-05     973*
  Te       1    1.40  -1.00   5.182    9.90E-05     973*
  E        0*   1.50  -0.30   4.524    1.06E-05     847
  E        1    1.50  -0.30   4.823    2.01E-05     973*

The table reflects how well each of the basis orbitals is converged in a PW expansion, which is used to make matrix elements of the interstitial potential. Only the E s orbital is converged below the specified tolerance (10-5 ). Convergence in the Te d orbital is particularly poor; however, the Te d is only minimally part of the bonding, and its poor convergence doesn't affect the energy much. In this case (3 Te atoms), the HF and HK total energies differ by ~10-4 Ry. Below is a table showing the convergence in HF energy as a function of the number of divisions, and also the difference between HK and HF energies.

  n       ehf         ehf-ehk
  14 -14561.140624    0.000089
  15 -14561.133966    0.000017
  16 -14561.132309    0.000005
  20 -14561.131170    0.000000

Legacy reference

The bulk of historical Category_Token reference, old physics-notes (APW test, sm-Hankel mtchre discussion, old SPEC notes, old tetrahedron memo) has been moved to a dedicated page:

That page is the canonical place to look up the meaning of a legacy key, then translate to TOML via the Legacy ↔ TOML map above.