mag4.geometry
Geometric fingerprints for J-shell discrimination via M–X–M bond angles.
The four-state method needs each magnetic coupling to correspond to a unique physical exchange path. Grouping pairs by distance alone lumps together pairs that share the same M–M distance but route their super-exchange through different bridging ligands at different M–L–M angles — physically distinct couplings the four-state method would conflate into a single J.
This module adds a secondary discriminator derived from the bridging-ligand
geometry of each pair: a quantised, sorted tuple of M–L–M angles. Pairs are
clustered first by distance, then sub-clustered by fingerprint. Resulting
sub-shells inherit their parent’s index plus a letter suffix (J1a,
J1b, …).
The fingerprint computation reuses
mag4.analysis.bond_angles.find_bridging_angles(); no new physics is
introduced.
Module Attributes
A geometric fingerprint for an M–M pair, packed as a 4-tuple: |
|
|
Backwards-compatible alias. |
Functions
|
Geometric fingerprint of one M–M pair. |
|
Build a |
|
Drop magnetic-sublattice symmetry ops that disagree with the bridging environment. |
|
Cluster M–M pairs by |
|
Bin a sequence of angles to integer multiples of |
|
Backwards-compatible alias. |
|
Reduce a |
- mag4.geometry.AngleFingerprint
A geometric fingerprint for an M–M pair, packed as a 4-tuple:
- ``(n_bridges, sorted bridge-angle bins,
n_dihedrals, sorted signed dihedral bins)``
n_bridges/bridge binsdescribe the direct M–L–M paths.n_dihedrals/dihedral binsdescribe the M–L–L–M super-super-exchange paths through two distinct ligands joined by an L–L contact withinll_cutoff.
The dihedral component is populated only when
n_bridges == 0andll_cutoff > 0— direct-bridge pairs keep(0, ())for the dihedral slot so they are not over-split by what is, for them, a redundant secondary signal.
- mag4.geometry.quantise_angles(angles, angle_tol)[source]
Bin a sequence of angles to integer multiples of
angle_tol.Returns a sorted tuple so equal fingerprints compare equal regardless of the input order. Empty input yields the empty tuple.
- mag4.geometry.compute_pair_fingerprint(structure, site_i, site_j, image, ligand_elements, bond_cutoff, angle_tol, *, ll_cutoff=0.0, signed_dihedral=False)[source]
Geometric fingerprint of one M–M pair.
- Parameters:
structure (pymatgen.core.Structure) – The cell containing the pair (primitive or supercell — both work).
site_i (int) – Indices of the two magnetic atoms in
structure.site_j (int) – Indices of the two magnetic atoms in
structure.image (tuple of 3 int) – Periodic image of
site_jrelative tosite_i. Use(0, 0, 0)for direct intra-supercell pairs.ligand_elements (sequence of str) – Element symbols treated as bridging ligands (e.g.
["O"]).bond_cutoff (float) – Maximum M–L distance (Å) for a ligand to be considered bonded.
angle_tol (float) – Tolerance (°) for quantising both M–L–M angles and M–L–L–M dihedrals into integer bins.
ll_cutoff (float) – Maximum L–L distance (Å) for a pair of distinct ligands to be counted as a super-super-exchange bridge. Used only when the pair has no direct M–L–M bridge (
n_bridges == 0). Set to0to disable dihedral analysis.signed_dihedral (bool) – Keep the IUPAC sign of each M–L–L–M dihedral when
True— this distinguishes mirror-image (chiral) paths and is appropriate when Dzyaloshinskii–Moriya / antisymmetric exchange matters. DefaultFalsefolds every dihedral to|θ|in[0°, 180°]so chiral counterparts are merged, which is the right choice for plain Heisenberg J.
- Returns:
4-tuple
(n_bridges, bridge bins, n_dihedrals, dihedral bins). For pairs with a direct bridge the dihedral slot is(0, ())— selective fallback so bridged shells aren’t over-split.- Return type:
- mag4.geometry.group_inequivalent_geom(results, structure, *, ligand_elements, bond_cutoff=2.5, dist_tol=0.01, angle_tol=1.0, ll_cutoff=0.0, signed_dihedral=False)[source]
Cluster M–M pairs by
(distance, angle fingerprint).First-level clustering by distance is identical to
mag4.io_cif.group_inequivalent(). Within each distance shell, pairs are then sub-grouped by their bridging-ligand fingerprint. Sub-shells take suffix letters (J1a,J1b, …) when a split occurs; singletons keep the plainJ1label.Each output dict carries an extra
fingerprintfield (AngleFingerprint) and afingerprint_strfield (human-readable summary).
- mag4.geometry.filter_symops_by_fingerprint(sym_ops, structure, n_mag, *, ligand_elements, bond_cutoff, angle_tol, ll_cutoff=0.0, signed_dihedral=False)[source]
Drop magnetic-sublattice symmetry ops that disagree with the bridging environment.
The default
mag4.symmetry.find_symmetry_ops()considers only the magnetic sites: two pairs related by such an op are considered equivalent even if their bridging ligands sit very differently in space. When that happens,mag4.spinconfig.find_unique_configs()merges configurations from physically distinct sub-shells (e.g.J1avsJ1b) and the extraction formulas degenerate.This filter keeps an op only when the permutation maps every M–M pair onto another pair with the same bridging fingerprint — i.e. the op is a symmetry of the decorated magnetic structure, not just of the bare sublattice. Fingerprints are computed once per pair and cached.
- mag4.geometry.reduce_to_wien2k_cell(crystal, group, *, spin_magnitude=1.0, symprec=0.001)[source]
Reduce a
CrystalDatato the standardized conventional cell of its spin-decorated (colored) structure — the setting WIEN2k’sinit_lapwpipeline expects.Uses
spglib.standardize_cell(no_idealize=False, to_primitive=False)on the same colored(lattice, frac_coords, atom_types)tuple thatanalyze_config_symmetry()already builds.to_primitive=False— return the conventional cell, not the primitive cell. WIEN2k’s lattice-type letters (F, I, R, …) are defined relative to the conventional cell of the parent space group; for F-centered cubic groups like Fm-3m the primitive cell is rhombohedral with 60° angles, which WIEN2k’ssgroupimmediately rewrites to the cubic conventional setting — yielding a sym-op mismatch with whatever mag4 had written. Emitting the conventional cell directly avoids that round trip.no_idealize=False— apply spglib’s origin shift so the cell sits at the canonical origin of its space group (4/m m m at the corner for P4/mmm, etc.). Without this,sgroupcomplains “Wrong multiplicity for atom 1” / “Struct file is not consistent” because the orbit-grouping mag4 reports (computed in spglib’s canonical setting) does not match the atom positions (kept in mag4’s input setting). Idealizing the cell aligns positions and orbits in one go.
For primitive groups (Pm-3m, P4/mmm, …) the conventional and primitive cells coincide; only the origin shift is non-trivial.
Returns a brand-new
CrystalDatawhosecell,lattice_vectors,all_species,target_species,nb_species,total_atomsandelementsdescribe the reduced cell. Atom labels mirror thecrystal.elementsorder (Ni1,Ni2, …) re-numbered inside the smaller cell.Falls back to the input
crystalwhen spglib refuses to reduce and would not shift the origin either (typically: cell already in canonical setting and primitive). The fallback path emits a single debug log entry and never raises.- Return type:
- Parameters:
crystal (CrystalData)
group (List)
spin_magnitude (float)
symprec (float)
- mag4.geometry.reduce_to_primitive(crystal, group, *, spin_magnitude=1.0, symprec=0.001)
Backwards-compatible alias. The function used to return the rhombohedral primitive for F-centered groups (which WIEN2k’s
init_lapwrejected), it now returns the conventional cell. The old name is preserved so existing imports keep working.- Return type:
- Parameters:
crystal (CrystalData)
group (List)
spin_magnitude (float)
symprec (float)
- mag4.geometry.crystal_to_pymatgen(crystal)[source]
Build a
pymatgen.core.Structurefrom aCrystalData.Magnetic atoms (
crystal.target_species) are placed first in the structure so that their mag4 supercell indices coincide with their pymatgen indices. This makes it trivial forfind_dimers()to look up bridging-angle fingerprints by passing the same integer index it already uses internally.- Parameters:
crystal (CrystalData)