mag4.wien2k
WIEN2k input generation: configN.inst + configN.struct per four-state
spin configuration.
Layer: WIEN2k-specific (one of the two DFT back-ends; see also vasp.py).
In each configN/ directory mag4 writes:
POSCAR– same VASP file used by--code vasp(kept for cross-checking; also accepted as input by WIEN2k’sxyz2struct).configN.inst– produced by piping theu/d/nspin pattern into WIEN2k’sinstgen -askscript. Named after the directory so thecase == basename(pwd)convention works out of the box.configN.struct– written directly by Python (noxyz2structneeded). Every atom is emitted as inequivalent (MULT=1) with a unique label of the form<element><n>("Cs1","V 9","I17"…) so WIEN2k cannot merge atoms via symmetry analysis. Only the identity symmetry op is written. This guarantees the atom order inconfigN.structmatches the order assumed byconfigN.inst.
Mapping convention
Each entry of the spin pattern maps as follows:
+1 (or any positive value) → ``u``
-1 (or any negative value) → ``d``
0 (non-magnetic atom) → ``n``
So a MAGMOM line -7 2*7 -7 3*7 4*0 becomes d u u d u u u n n n n.
Module Attributes
Ångström → Bohr conversion factor used by WIEN2k struct files. |
|
The 73 symmorphic space groups (no glide planes / no screw axes). |
Functions
|
Magnetic space group (Shubnikov/BNS) of a spin-decorated configuration. |
|
Run spglib on the spin-decorated configuration and pack the result. |
|
Per-unique-config list of u/d/n letters in POSCAR order. |
Locate the WIEN2k |
|
|
Translate a flat list of MAGMOM values to the |
|
Run |
|
Format an atom label per WIEN2k case.struct convention. |
|
For every unique configuration, write a |
|
Write |
|
Write |
|
Write a complete WIEN2k |
|
Write a WIEN2k |
|
Write a minimal |
|
Write |
Classes
|
Symmetry analysis of a single spin-decorated configuration. |
|
Magnetic (Shubnikov) space group of one spin-decorated configuration. |
- mag4.wien2k.ANG_TO_BOHR: float = 1.8897261339212517
Ångström → Bohr conversion factor used by WIEN2k struct files.
- mag4.wien2k.SYMMORPHIC_SG_NUMBERS: frozenset = frozenset({1, 2, 3, 5, 6, 8, 10, 12, 16, 21, 22, 23, 25, 35, 38, 42, 44, 47, 65, 69, 71, 75, 79, 81, 82, 83, 87, 89, 97, 99, 107, 111, 115, 119, 121, 123, 139, 143, 146, 147, 148, 149, 150, 155, 156, 157, 160, 162, 164, 166, 168, 174, 175, 177, 183, 187, 189, 191, 195, 196, 197, 200, 202, 204, 207, 209, 211, 215, 216, 217, 221, 225, 229})
The 73 symmorphic space groups (no glide planes / no screw axes). Used by the
--no-reducebranch inwrite_symmetric_case_files()to decide whether to refine orbit groupings (_cell_compatible_symmetry + _relabel_…) or to fall back to “every atom MULT=1” (_ungrouped_symmetry).For symmorphic parents, the refined point group at origin is closed under composition modulo the supercell lattice, so the union-find in _cell_compatible_symmetry produces correct supercell-as-P-Bravais orbits. For non-symmorphic parents the parent’s intrinsic glide / screw translations alias with supercell-induced internal translations and the union-find over-merges (e.g. MULT=16 in a Pmna 2×2×1 supercell where Pmna’s max Wyckoff multiplicity is 8).
- mag4.wien2k.magmom_to_udn(values)[source]
Translate a flat list of MAGMOM values to the
u/d/nletters.- Parameters:
values (sequence of float) – One value per atom in POSCAR order. Sign carries the spin direction; zero means non-magnetic.
- Returns:
One letter per atom:
"u"for positive,"d"for negative,"n"for zero.- Return type:
Examples
>>> magmom_to_udn([-7, 7, 7, -7, 7, 7, 7, 0, 0, 0, 0]) ['d', 'u', 'u', 'd', 'u', 'u', 'u', 'n', 'n', 'n', 'n']
- mag4.wien2k.build_udn_lines(unique_groups, crystal, spin_magnitude=1.0)[source]
Per-unique-config list of u/d/n letters in POSCAR order.
Returns a list of length
len(unique_groups); each element is the list of u/d/n letters for one configuration. Order matchesmag4.vasp.build_magmom_lines().- Return type:
- Parameters:
unique_groups (List[List[FourStateConfig]])
crystal (CrystalData)
spin_magnitude (float)
- mag4.wien2k.wien2k_label(element_symbol, idx)[source]
Format an atom label per WIEN2k case.struct convention.
Two-letter element: e.g.
"Cs1"→ cols 1-2 ="Cs".One-letter element:
"V 1"(letter + space) → cols 1-2 ="V ".
The convention matters because instgen reads the element from the first two characters of each
RMT=line incase.struct.
- mag4.wien2k.write_stub_struct(crystal, path)[source]
Write a minimal
case.structgood enough for instgen.Only the per-atom
RMT=line is emitted (one per atom in POSCAR order) because that is the only thing instgen parses. Usewrite_struct_file()to produce a full, ready-to-use struct file.- Return type:
- Parameters:
crystal (CrystalData)
path (str)
- class mag4.wien2k.ConfigSymmetry(spacegroup_number, spacegroup_symbol, rotations, translations, origin_shift, new_to_old, orbits, frac_coords_new, mapping_to_primitive=<factory>)[source]
Bases:
objectSymmetry analysis of a single spin-decorated configuration.
The cell is kept verbatim from the input
CrystalData; only the atom ordering (within the cell) and the symmetry-op list are derived.- Parameters:
- spacegroup_number, spacegroup_symbol
Space group reported by spglib for the spin-decorated structure.
- rotations, translations
Symmetry operations in the input cell basis, ready to be written verbatim into a WIEN2k struct file (
rotationsis integer; the translations are in fractional coordinates).
- origin_shift
Origin shift that spglib would apply to put the structure into the standard setting. Kept for diagnostics; not applied to atom positions here — we keep input positions so the rotations/translations in the input basis act directly.
- new_to_old
new_to_old[i]is the original POSCAR index of the atom that now sits at positioniin the symmetrised order. Length = number of atoms.
- orbits
List of Wyckoff orbits in the new order: each orbit is a list of consecutive new-order indices that share a symmetry equivalent class.
len(orbits)is the number of inequivalent sites (== WIEN2k’sNEQUIV).
- frac_coords_new
Fractional coordinates in the new order (shape
(n_atoms, 3)).
- mapping_to_primitive: List[int]
For each atom in the new order, the index of the corresponding atom in spglib’s primitive cell. Used by the WIEN2k struct writer to fold orbits by lattice-centering equivalence (only one rep per primitive index is emitted under an F/B/C-centred letter, matching WIEN2k’s “list one of four / one of two” convention).
- class mag4.wien2k.MagneticGroupInfo(uni_number, bns_number, og_number, msg_type, parent_number, parent_symbol, n_unitary, n_primed, mpg_symbol='', mpg_kind='')[source]
Bases:
objectMagnetic (Shubnikov) space group of one spin-decorated configuration.
spglib classifies the configuration (collinear moments included, so the PRIMED operations — unitary op × time reversal — are counted) into one of the 1651 magnetic space-group types. spglib provides the standard numbers but not the symbol string; the BNS number is the citable label (symbol lookup: Bilbao MGENPOS / ISO-MAG).
msg_typeis the Shubnikov type: 1 = colorless (no primed ops), 2 = grey (contains pure time reversal — only for zero-moment structures), 3 = black-white (half the point operations primed), 4 = black-white with anti-translations (a translation × T maps the sublattices).- Parameters:
- point_group()[source]
Magnetic point group with its kind, e.g.
mmm1' (grey).Dropping the translations from the magnetic space group gives the magnetic point group exactly: an anti-translation (type IV) becomes pure time reversal 1’, so the point group is GREY
G1'; a type-III group keeps half its point operations primed and is written in the ShubnikovG(H)notation (parent, unitary subgroup); a type-I group is the ordinary (colourless) symbol.- Return type:
- mag4.wien2k.analyze_config_magnetic_group(crystal, group, *, spin_magnitude=1.0, symprec=0.001)[source]
Magnetic space group (Shubnikov/BNS) of a spin-decorated configuration.
Unlike
analyze_config_symmetry()— which colours up/down spins as different species and therefore sees only the UNITARY part of the magnetic group — this passes the collinear moments to spglib’s magnetic dataset, so operations combined with time reversal (primed) are included. ReturnsNonewhen spglib is too old (< 2.0) or fails; callers should then simply omit the magnetic-group line.- Return type:
- Parameters:
crystal (CrystalData)
group (List[FourStateConfig])
spin_magnitude (float)
symprec (float)
- mag4.wien2k.analyze_config_symmetry(crystal, group, *, spin_magnitude=1.0, symprec=0.001)[source]
Run spglib on the spin-decorated configuration and pack the result.
Atoms in
CrystalDataare coloured according to their spin (see_spglib_atom_types()), so the detected space group is the magnetic space group of the configuration projected onto the user’s cell — equivalent to “highest symmetry compatible with this cell”.The returned
ConfigSymmetrycarries:the rotations/translations in the input cell basis (so we can write them straight into a WIEN2k struct file);
the permutation that groups atoms by their Wyckoff orbit, with orbits ordered by the index of their representative — this becomes the new atom order on disk.
On any spglib error or empty dataset we fall back to a P1 (identity-only)
ConfigSymmetryso the rest of the pipeline can proceed unchanged.- Return type:
- Parameters:
crystal (CrystalData)
group (List[FourStateConfig])
spin_magnitude (float)
symprec (float)
- mag4.wien2k.write_struct_file(crystal, path, *, title=None, rmt=2.0, npt=781, r0=None, calc_mode='RELA', lattice=None)[source]
Write a complete WIEN2k
case.structfrom aCrystalData.Every atom is emitted as a separate inequivalent site (
MULT=1) with a unique label of the form<element><n>("Cs1","V 9","I17"…). Only the identity symmetry operation is written, so WIEN2k will not merge or reorder atoms. This guarantees that the atom order inconfigN.structmatches the order assumed byconfigN.inst.See
write_struct_file_symmetric()for the spin-aware variant that uses real-space symmetry (default in the CLI; this function is kept as a fallback behind--no-symmetrize-struct).- Parameters:
crystal (
CrystalData) – The (super-)cell as produced bymag4.supercell.path (
str) – Where to write the struct file (full path including filename).title (
Optional[str]) – Free-text title written on line 1. Defaults to a mag4-tagged note.rmt (
Union[float,Dict[str,float]]) – Muffin-tin radius in bohr. Either a single value applied to every element (default 2.0) or a dict{element_symbol: value}.npt (
int) – Number of radial mesh points (default 781; must be odd).r0 (
Union[float,Dict[str,float],None]) – First radial mesh point in bohr.None(default) → picked per-Z via_default_r0(); a single float applies to all elements; a dict allows per-element overrides.calc_mode (
str) –"RELA"(relativistic, default) or"NREL"(non-relativistic).lattice (
Optional[str]) – WIEN2k single-letter lattice code. Auto-detected from the cell angles whenNone.
- Return type:
Notes
The per-atom header line follows the format declared in the WIEN2k user guide:
(A10, 5X, I5, 5X, F10.8, 5X, F10.5, 5X, F10.5)forname, NPT, R0, RMT, Zrespectively. The 5X gaps carry decorative text (" NPT="," R0="," RMT="," Z:") for readability — WIEN2k skips them when parsing.
- mag4.wien2k.write_struct_file_symmetric(crystal, config_sym, path, *, title=None, rmt=2.0, npt=781, r0=None, calc_mode='RELA', lattice=None, labels=None)[source]
Write a WIEN2k
case.structthat exposes the configuration’s detected space-group symmetry.One inequivalent block is emitted per Wyckoff orbit (
MULT= orbit size), with the orbit’s representative listed on the leadingATOMline and the remaining members on continuation lines between theMULT=line and the per-orbitNPT/R0/RMTline. Each orbit gets a unique<element><n>label so WIEN2k cannot merge orbits that happen to share an element. The trailing symmetry block lists every rotation/translation reported by spglib in the input cell basis.Atom positions are written in the order encoded by
config_sym.frac_coords_new— i.e. spglib’s equivalence classes grouped together, with orbits ordered by their representative index.
- mag4.wien2k.write_case_struct_files(crystal, n_configs, parent_dir, *, rmt=2.0, npt=781, r0=None)[source]
Write
configN.structinto everyconfigN/subdirectory.The cell and atom list are identical across configurations; only the spin pattern (in
configN.inst) differs. We therefore write the same struct content N times, naming each file after its directory.
- mag4.wien2k.write_symmetric_case_files(unique_groups, crystal, parent_dir, *, instgen_path=None, spin_magnitude=1.0, symprec=0.001, rmt=2.0, npt=781, r0=None, reduce_cell=False)[source]
Write
configN.structandconfigN.instper config with a shared, symmetry-derived atom order.For each configuration:
Run
analyze_config_symmetry()once on the spin-decorated cell.Write
configN.structviawrite_struct_file_symmetric()— one block per Wyckoff orbit, full symmetry-op tail, unique per-orbit labels.Drive instgen with one
u/d/nanswer per orbit (the spin of the orbit’s representative) and save the resultingconfigN.inst.
Because both files are produced from the same
ConfigSymmetry, their atom orders are guaranteed to agree without any post hoc reordering.Returns a dict with four keys:
"struct"(list of struct paths),"inst"(list of inst paths),"sym"(list ofConfigSymmetryresults, one per config — handy for tests), and"crystals"(the per-config reducedCrystalDataused to write each struct — used by the report writer to record per-config cell metadata for mag4-extract’s cell-size rescaling).When
reduce_cellis true (--reduce; the default is off, so every config keeps the one working supercell and shares identical numerics) each config is rewritten in its colored-structure primitive cell viamag4.geometry.reduce_to_primitive()— multiplicities then match the parent SG’s standard Wyckoff table, and downstream DFT runs are correspondingly cheaper for high-symmetry configs.
- mag4.wien2k.write_job_scripts(parent_dir, *, functional=None, kspacing=None, element=None, ldaul=None, ldauu=None, ldauj=None)[source]
Write
job.initandjob.runintoparent_dirand chmod +x them.Both scripts iterate over the sibling
config*/directories viaforeach; they belong at the compound level, not inside each configN/. Existing files are overwritten so re-runningmag4-magneticis safe. The template follows P. Blaha’s recommended workflow:setrmt(so the muffin-tin radii mag4 writes into the struct files are placeholders),init_lapw -sp -prec 2n -noreduc -nohdlo -nokshift(-nokshiftis always present, so the k-mesh is unshifted by default), and an interactive check when sgroup proposes an origin-shifted struct (accept only if lattice type and atom count are unchanged — sgroup may e.g. reduce P to CXY, which would silently change the cell the report’s energy formulas refer to).kspacing(Å⁻¹, VASP convention; defaults to mag4’s 0.3) is converted to bohr⁻¹ and inserted asinit_lapw -numk -1 <spacing>so the WIEN2k k-mesh matches the VASP one. Whenfunctional == "PBE+U"andldauuis given, theinit_orb -orbheredoc is generated active with<element> <l> <U> <J>fromelement/ldaul/ldauu/ldauj, andjob.runcallsrunspwith-orb; otherwise the block stays commented out as a template.ldauu/ldaujare taken in eV (VASP convention — the very same values the INCAR’sLDAUU/LDAUJreceive) and divided byRY_TO_EVon the way out, becauseinit_orbreads U and J in Rydberg.ldaulis a quantum number and is passed through unchanged. A comment above the heredoc echoes both the eV input and the Ry output so the conversion is checkable in the generated script.
- mag4.wien2k.find_instgen()[source]
Locate the WIEN2k
instgenscript.Lookup order:
$WIEN2k_INSTGENenvironment variable, if set.instgenon$PATH.instgen_lapwon$PATH(the canonical WIEN2k name).$WIENROOT/instgen_lapw.~/bin/instgen.
Returns the absolute path or
Noneif not found.
- mag4.wien2k.run_instgen(udn_letters, crystal, instgen_path)[source]
Run
instgen -askonce and return the producedcase.insttext.Internally uses a temporary directory containing a stub
case.struct, pipes theu/d/nletters as answers, runs instgen, reads back the resultingcase.instand cleans up.- Raises:
RuntimeError – If instgen exits non-zero or fails to produce
case.inst.- Return type:
- Parameters:
crystal (CrystalData)
instgen_path (str)
- mag4.wien2k.write_case_inst_files(unique_groups, crystal, parent_dir, instgen_path=None, spin_magnitude=1.0)[source]
For every unique configuration, write a
configN.instfile inconfigN/.The output file is named after the directory (
config1.instinsideconfig1/, etc.) so that WIEN2k’s standardcase == basename(pwd)convention works directly on the user’s HPC machine.- Parameters:
unique_groups (
List[List[FourStateConfig]]) – Same conventions asmag4.vasp.build_magmom_lines().crystal (
CrystalData) – Same conventions asmag4.vasp.build_magmom_lines().spin_magnitude (
float) – Same conventions asmag4.vasp.build_magmom_lines().parent_dir (str) – Compound (or run) directory hosting the
configN/subdirectories.instgen_path (str, optional) – Path to the
instgenscript. Auto-detected viafind_instgen()if omitted.
- Returns:
Paths of the written
configN.instfiles, in config order.- Return type: