Command-line reference

The package installs five commands via [project.scripts]. mag4-magnetic --help (and the others) show every option organised in titled groups; this page documents the concepts and the most-used flags.

Command

Underlying module

mag4-magnetic

mag4.cli.fourstate.main()

mag4-extract

mag4.cli.extract.main()

mag4-magnon

mag4.cli.magnon.main()

mag4-angles

mag4.cli.bond_angles.main()

mag4-moments

mag4.cli.extract_moments.main()

mag4-magnetic

Generation pipeline: parse CIF/POSCAR, detect J shells, build the isolation-aware supercell, deduplicate the spin configurations under the magnetic grey group (crystal symmetry + time reversal), then write per-config input directories for the chosen DFT code(s).

Mode A — from a CIF (recommended):

mag4-magnetic --cif POSCAR_alpha-Gd2S3.cif --element Gd
mag4-magnetic --cif POSCAR_alpha-Gd2S3.cif --element Gd \
    --cutoff 7.0 --supercell 2 1 1

Mode B — from a POSCAR + manual couplings:

mag4-magnetic --poscar POSCAR --species 1 \
    --couplings "J1:3.94,J2:5.88"

Method selection (--method)

--method

What is generated

four-state (default)

the targeted uu/dd/ud/du configurations per bond and the per-bond difference formulas (divisor \(4M\))

energy-mapping

every inequivalent collinear order of the supercell, for a global least-squares fit; --jring adds the four-spin ring-exchange column

16-state

the 16 plaquette flips (symmetry-reduced) for the exact parity projection of \(J_\mathrm{ring}\) alone

mag4-extract auto-detects the method from the report, so the post-processing command is identical in all three cases.

Reference bath (--ref-*, mutually exclusive)

The probed atoms are flipped over a fixed spin background (default: FM, all +1). --ref-couplings "J1:AFM" builds an antiferromagnetic bath by signed 2-colouring (recommended for strong antiferromagnets — the SCF converges to the intended state far more readily); --ref-kvector "1/2 1/2 0" derives it from a propagation vector; --ref-magmom "32*0 1 1 1 -1 64*0" takes it verbatim as the supercell MAGMOM string (POSCAR atom order, n*v repetitions, non-magnetic zeros validated).

Diagnostics

  • --jring / --jprime (four-state) — print how much the ring term and beyond-cutoff shells leak into each extracted J, ending with a corrected-J formula. Both checks are free (no extra DFT, no change to the generated inputs) and therefore run by default: the J′ scan reaches the larger of 2×``–cutoff`` and the shortest lattice translation (--jprime R overrides), and the ring check silently skips lattices with no square plaquette. Opt out with --no-jring / --no-jprime.

  • --check-degeneracy (all methods) — keep the configurations that only time reversal proves degenerate as separate DFT runs; mag4-extract verifies \(|\Delta E|\) per pair.

  • Every configuration is labelled with its space group and its magnetic (Shubnikov) group — BNS number, type, magnetic point group.

DFT-code selection (--code)

--code

Files written in each configN/

vasp (default)

POSCAR + INCAR + KPOINTS

wien2k

POSCAR + configN.inst + configN.struct in each configN/, plus job.init and job.run driver scripts at the compound (parent) directory. The WIEN2k case == basename(pwd) convention applies.

both

All of the above

For WIEN2k modes, case.inst is generated by piping the spin pattern (translated to u/d/n) into the WIEN2k instgen -ask script. The script is auto-detected via $WIEN2k_INSTGEN, $PATH, $WIENROOT/instgen_lapw, then ~/bin/instgen. Override with --instgen PATH if needed.

Symmetric struct generation (default)

By default, configN.struct is written using spglib so each spin configuration carries the highest space-group symmetry compatible with the cell that mag4-magnetic built. Atoms are coloured by spin direction (magnetic up, magnetic down, non-magnetic = bare element) and the detected orbits become one inequivalent block per Wyckoff site (MULT > 1 where applicable), with the full rotation/translation table written into the trailing symmetry block. Every orbit still receives a unique <element><n> label so WIEN2k does not merge chemically-similar but inequivalent sites.

Because the same spglib analysis is used to generate configN.inst, the per-orbit u/d/n answers fed to instgen are in lockstep with the struct file — no reordering needed on disk.

Pass --no-symmetrize-struct to fall back to the legacy “every atom inequivalent, identity-only symmetry block” output (useful if a particular configuration trips up spglib). The --symprec E flag controls the distance tolerance handed to spglib (default 1e-3 Å).

Per-config cell reduction (--reduce, opt-in)

By default every configN.struct keeps mag4’s one working supercell, so all configs share strictly identical cell and numerics — the safer choice recommended by the WIEN2k authors, and the one that makes a direct reduce-vs-no-reduce comparison possible.

With --reduce, each configN.struct is instead rewritten in the standardized conventional cell of its spin-decorated structure so the multiplicities written match the parent space group’s standard Wyckoff table. For NiO config4 (the dd of the axial J) the 16-atom 1×1×2 working supercell collapses to the 8-atom Pm-3m cubic primitive with MULT=[1, 3, 3, 1] and lattice letter P; the all-FM config1 collapses to the Fm-3m cubic conventional cell with lattice letter F and MULT=[1, 1] — per the WIEN2k user’s guide §4.3, only one of every four F-centred atoms is listed in the struct, the others being generated by the F lattice letter.

The WIEN2k lattice letter is taken from the SG symbol’s first character with two conventional remappings:

  • international I (body-centred) → WIEN2k B

  • international A / B / C (base-centred) → WIEN2k CYZ / CXZ / CXY

For an orbit on a centred lattice mag4 emits only one atom per centring coset (using spglib’s mapping_to_primitive to identify them), so MULT in the struct file is the orbit size divided by the centring factor (4 for F, 2 for B / CXY / CYZ / CXZ, 3 for R, 1 for P / H). init_lapw’s sgroup / symmetry pipeline accepts the struct without rewriting the Bravais lattice (which used to mismatch the listed ops). Configs whose colored structure has no extra symmetry beyond the working supercell stay at the supercell size.

four_state_report.dat now records a per-config Cell: a=… | b=… | c=… | | n_atoms=N | | SG=#N (symbol) line under each Config #N block. mag4-extract reads those values and rescales each contributing config’s total energy to the least-common-multiple (LCM) atom count of the four configs of each J before applying the four-state formula:

E_X(in N_LCM cell) = E_X(in N_X primitive) × (N_LCM / N_X)
J = ( E_uu' + E_dd' − E_ud' − E_du' ) / 4    ← E' are rescaled values

This is exact because DFT total energy is extensive — scaling a primitive cell to a k-multiplied supercell scales the total energy by the same factor k. The J values come out identical to what you would get if every config had been computed in a single common cell.

When mag4-extract detects mixed cell sizes it announces:

INFO: Per-config cell metadata found: 5 configs span 3 distinct
      atom counts [2, 8, 16] — energies will be rescaled to per-J
      LCM cells.

--no-reduce names the default explicitly (every config in the one working supercell, no rescaling involved).

Driver scripts job.init / job.run

Together with the per-config inputs, mag4-magnetic drops two tcsh helper scripts at the compound (parent) directory — siblings of config1/, config2/, … — so the post-mag4 workflow on the WIEN2k machine is just:

cd MyCompound/
./job.init        # setrmt + init_lapw -sp -prec 2n -noreduc -nohdlo -nokshift
# create a .machines file for parallel execution, then:
./job.run         # runsp -p -ec 1e-6 -cc 1e-5 in each configN/, then 'save'

The scripts follow P. Blaha’s recommended workflow:

  • setrmt sets the real muffin-tin radii (the values mag4 writes into the struct files are placeholders); tune per element there, e.g. setrmt -a Cu:2.1,O:1.7.

  • init_lapw carries -numk -1 <spacing> with --kspacing × 0.529177 (Å⁻¹ → bohr⁻¹), so the WIEN2k k-mesh matches the VASP one.

  • When sgroup proposes an origin-shifted struct (init_lapw exit status 3), the script pauses for an interactive check — accept only if the lattice type and atom count are unchanged (sgroup may e.g. reduce P → CXY, which would change the cell the report’s energy formulas refer to).

  • With --functional PBE+U, the init_orb -orb heredoc is generated active with element U J filled from --ldaul/--ldauu/--ldauj, and job.run’s runsp carries -orb. init_orb reads U and J in Rydberg, so the eV flag values are divided by 13.605693122994 (--ldauu 6 --ldauj 0.50.44099 / 0.03675); a comment above the heredoc echoes both the eV input and the Ry output. is a quantum number and is passed through unchanged, and the VASP INCAR path keeps LDAUU/LDAUJ in eV.

Both scripts are written chmod +x on POSIX. The remaining project-specific flags (-ec, -cc, the save name, …) are inlined verbatim with comments — review in place before launching. Pass --no-job-scripts to skip them.

The translation is sign-based per atom in POSCAR order:

MAGMOM = -7 2*7 -7 3*7 4*0     →     d u u d u u u n n n n

(+u, d, 0n).

Geometry-aware J shells (--ligand)

By default J shells are grouped only by M–M distance. This lumps together pairs that share a distance but route super-exchange through different bridging geometries — e.g. on CuO the d ≈ 2.9 Å shell contains both edge-sharing pairs with two Cu–O–Cu bridges at ~96° and non-bridged pairs at the same distance. Pass --ligand X to split such shells into sub-shells (J1a, J1b, …) using the bridging-angle fingerprint produced by mag4.analysis.bond_angles:

mag4-magnetic --cif CuO.cif --element Cu --cutoff 6.0 --ligand O

Companion knobs:

  • --bond-cutoff R — max M–L distance (Å) for a ligand to count as bridging (default 2.5).

  • --angle-tol DEG — tolerance for grouping M–L–M angles and M–L–L–M dihedrals into the same fingerprint (default 1.0).

  • --ll-cutoff R — max L–L distance (Å) for an M–L–L–M super-super-exchange path (default 3.0). Used only for pairs with no direct M–L–M bridge; 0 disables the fallback.

  • --signed-dihedral — keep the IUPAC sign of M–L–L–M dihedrals in [-180°, +180°]. Off by default (dihedrals are folded to |θ| [0°, 180°] so chiral mirror-image paths merge — the right choice for plain Heisenberg J). Switch on when Dzyaloshinskii–Moriya / antisymmetric exchange matters.

A pair’s fingerprint is a 4-tuple (n_bridges, sorted bridge-angle bins, n_dihedrals, sorted dihedral bins). Pairs with a direct M–L–M bridge keep the dihedral slot empty so they are not over-split. Pairs with no direct bridge fall back to their M–L–L–M dihedral fingerprint.

When --ligand is supplied the magnetic-sublattice symmetry operations are additionally filtered to keep only those that preserve each pair’s fingerprint, so mag4.spinconfig.find_unique_configs() does not merge configurations from physically distinct sub-shells. Expect more unique configurations than the same run without --ligand.

mag4-extract

Post-processing CLI: walks the configN/ subdirectories of a compound directory, checks every DFT calculation converged, parses the total energies (TOTEN for VASP, :ENE for WIEN2k), and applies the extraction recorded by mag4-magnetic in four_state_report.dat — four-state difference formulas, energy-mapping least squares (with error bars, --couplings / --drop-couplings model restriction, --check-mag magnetic-state gating), or the 16-state ring projection; the method is auto-detected.

Built-in checks printed on every run: per-config convergence, band gap / metallicity (WIEN2k reads the global :GAP (global) line), converged moment vs Sz, and — after --check-degeneracy — the time-reversal degeneracy \(|\Delta E|\) table. The complete screen output is persisted to <compound>/mag4_extract.out.

cd MyCompound/                     # contains configN/ + four_state_report.dat
mag4-extract --code vasp                       # JS² in eV / meV
mag4-extract --code vasp   --spin 3.5          # also adds J in meV and K
mag4-extract --code wien2k --spin 3.5
# WIEN2k campaigns that save several runs side by side (save_lapw):
mag4-extract --code wien2k --scffile pbe       # reads configN/pbe.scf
mag4-extract --code wien2k --scffile r2scan    # reads configN/r2scan.scf

The same J table is also written to <compound>/j_values.dat.

For WIEN2k, mag4-extract also prints a per-config verification table with the last :DIS (charge distance) and :ENE (total energy in Ry) it parsed, so the user can confirm the SCF converged to the desired tolerance.

Convergence rules (coarse, code-agnostic):

Code

File scanned

Convergence flag

vasp

configN/OUTCAR

OUTCAR ends with Voluntary context switches: AND no WARNING: NELM was reached warning

wien2k

configN/configN.scf

At least one :ENE is present AND it falls inside the last :ITE…: iteration block

Tighter convergence (EDIFF / EDIFFG / :CONV thresholds) is not enforced — the right value is project-specific. Diagnostics (NELM hit, file truncated, last :CONV value, …) are surfaced in the per-config notes so the user can make the call.

Exit codes:

  • 0 — every J shell in the report was successfully computed.

  • 1 — at least one J shell could not be computed (one of its 4 contributing configs is missing or did not converge).

  • 2 — hard error (compound dir not found, report file missing, …).

mag4-magnon

Multi-sublattice linear spin-wave theory, T_c (MF + Tyablikov RPA), optional magnon dispersion. Give the couplings by exactly one of:

  • --JS2 "J1:0.26,…" — the fitted \(JS^2\) values, exactly as mag4-extract prints them (native input, used as-is);

  • --J "J1:1.04,…" — the bare \(J = JS^2/S^2\) (the J(meV) column); multiplied by \(S^2\) internally, conversion logged;

  • --from-extract DIR — read j_values.dat directly (couplings and spin; non-OK rows skipped; shell labels verified against the CIF).

mag4-magnon --cif Gd2O2S.cif --element Gd \
    --JS2 "J1:0.26,J2:0.26,J3:0.12,J4:0.01,J5:0.39" --spin 3.5 \
    --plot --kpath "Gamma M K Gamma A L H"

# straight from mag4-extract, ring exchange folded into effective
# couplings (LSWT mapping, provenance recorded in the report):
mag4-magnon --cif La2CuO4.cif --element Cu --from-extract La2CuO4/ --jring

Two guards keep the temperatures honest: the Mermin–Wagner dimensionality check (a network that is not 3D yields an energy scale, not a Néel/Curie temperature; a coupling counts as zero only when the fit cannot resolve it from zero — \(|JS^2| < 2\sigma\) of its error bar or below the fit RMS — with --j-significance as manual override) and the flat-axis q₀ diagnostic (ordering-vector components along dispersion-flat axes are reported as undetermined).

mag4-angles

For each detected J shell, compute every M-L-M angle of bridging ligands. The --ligand option accepts a comma-separated list (e.g. S,O).

mag4-angles --cif Gd2S3.cif --element Gd --ligand S
mag4-angles --cif Gd2S3.cif --element Gd  # auto-detect ligands

mag4-moments

Read converged magnetic moments from a tree of WIEN2k calculation directories.

mag4-moments                       # interactive
mag4-moments 9 16                  # atoms 9-16, auto-detect dirs
mag4-moments 9 16 AF-J1ud AF-J2dd  # explicit directories