mag4.energy_mapping
Energy-mapping (linear least-squares) configuration generator.
Layer: common — an alternative to the four-state method for extracting
Heisenberg J from DFT total energies. Where the four-state method targets a
handful of uu/dd/ud/du configurations per bond, energy-mapping enumerates
every symmetry-/coefficient-inequivalent collinear order of a given
(super)cell and later fits
E(config) = E0 + Σ_k J_k · c_k(config)
by a single linear least-squares solve over all configurations (see
mag4-extract --method energy-mapping, Phase 3).
This module produces, for one (super)cell, the list of inequivalent orders and
their integer coupling coefficients c_k (the design-matrix rows). The
±1 Ising enumeration and the coefficient counting mirror the standalone
ising_magnetic.py precursor, re-expressed on mag4’s CrystalData.
Module Attributes
Above this magnetic-atom count the 2^N enumeration is rejected outright (overridable per call). |
Functions
|
Wrap each record as a one-member group for the VASP/WIEN2k writers. |
|
Coupling coefficients of each spin order's energy. |
|
Ring coefficient = |
|
Return the |
|
Enumerate the inequivalent collinear magnetic orders of |
|
Parse the design-matrix report written by |
|
Pick the coupling shell that forms the square lattice for the ring term. |
|
Write the design-matrix report consumed by |
- mag4.energy_mapping.DEFAULT_MAX_ATOMS = 20
Above this magnetic-atom count the 2^N enumeration is rejected outright (overridable per call). 2^20 ≈ 1e6 orders is already minutes of work.
- mag4.energy_mapping.config_energy_coefficients(atoms, lat_mat, couplings, spin_vectors, *, tol=0.0005, distmax=None)[source]
Coupling coefficients of each spin order’s energy.
For every spin vector (
±1per magnetic atom, inatomsorder) returns({Jname: c_k}, |Sz|)withc_k = Σ_{⟨ij⟩∈k} s_i s_jsummed over the unique bonds of shellkin the cell — i.e. the design-matrix row, so thatE[config] = E0 + Σ_k c_k · (J_k · S²). This is what lets one verify that a four-state combination isolates a singleJ(the other couplings’ coefficients cancel). Bonds are counted once via the same cell↔image folding as_coefficients().
- mag4.energy_mapping.count_ring(plaquettes, spin_map)[source]
Ring coefficient =
Σ s_i s_j s_k s_lover the (4×-redundant) squares, divided by 4.
- mag4.energy_mapping.select_ring_plaquettes(couplings, cell_atoms, image_atoms, prefer_label=None, prefer_dist=None, tol_pos=0.15)[source]
Pick the coupling shell that forms the square lattice for the ring term.
The shortest M–M distance is not necessarily the square edge (e.g. SrFeO₂’s shortest Fe–Fe is a linear c-axis contact that forms no square). If the user pins a shell (
prefer_label/prefer_dist) it is used; otherwise every shell is tried from shortest to longest and the first that closes into squares is returned. Returns(plaquettes, n_unique, n_folded, dist)or(None, 0, 0, None).
- mag4.energy_mapping.enumerate_orders(crystal, couplings, tol=0.0005, distmax=None, *, max_atoms=20, ring=False, ring_coupling=None, ring_dist=None, ring_tol=0.15)[source]
Enumerate the inequivalent collinear magnetic orders of
crystal.Every
2^N±1assignment over theNmagnetic atoms is grouped by its coupling-coefficient signature(c_1, …, c_n, |Sz|); configurations sharing a signature are energy-degenerate in the model, so one representative ordering is kept per signature.With
ring=Truea four-spin cyclic (ring) exchange coefficient is also computed per order and a"Jring"column appended (seeselect_ring_plaquettes()); the square-lattice shell is auto-detected unless pinned withring_coupling/ring_dist.Returns
(records, labels, ring_distance)wherelabelsare the coupling names in column order ("Jring"last when present),ring_distanceis the square edge length (orNone), and each record is:{"number": int, # 1-based, deterministic "coefficients": {name: c}, "sz": int, # |Sz| of the order "degeneracy": int, # how many ±1 orders share this signature "spin_vector": [±1, …]} # representative, in target_species order- Raises:
ValueError – When
Nexceedsmax_atoms(the2^Nenumeration would be intractable) — use a smaller supercell or raisemax_atoms.- Return type:
- Parameters:
- mag4.energy_mapping.build_unique_groups(records)[source]
Wrap each record as a one-member group for the VASP/WIEN2k writers.
mag4.vasp.build_magmom_lines()/mag4.vasp.create_config_dirs()consumeList[List[FourStateConfig]]and read onlyspin_vector(for the MAGMOM) pluscoupling_name/state_label(for the printed label). Energy-mapping has no per-bond label, so the coefficient signature is used for display.- Return type:
- Parameters:
- mag4.energy_mapping.write_energy_mapping_report(path, records, labels, couplings, supercell, name, *, tr_pairs=None, config_msgs=None)[source]
Write the design-matrix report consumed by
mag4-extract.The format is deliberately simple and machine-parseable: a
Method:tag, the coupling labels + distances, then one whitespace-separated row per configuration givingconfig<N>, degeneracy, Sz and the integer coefficient of each coupling (column order =labels).tr_pairs(from--check-degeneracy) adds onepair: configA == configBline per time-reversal-degenerate pair;mag4-extractreads them back and reports|ΔE|per pair.config_msgs(magnetic Shubnikov groups) are recorded as comment lines — informational, ignored by parsers.
- mag4.energy_mapping.detect_report_method(report_path)[source]
Return the
Method:tag of a mag4 report (four-stateif absent).Legacy four-state reports carry no
Method:line, so their absence is treated asfour-state.
- mag4.energy_mapping.parse_energy_mapping_report(report_path)[source]
Parse the design-matrix report written by
write_energy_mapping_report().Returns
{"method", "labels", "dist_of", "supercell", "records"}where each record is{"number", "degeneracy", "sz", "coefficients": {label: c}}.