mag4.ring16
16-state method for the four-spin ring (cyclic) exchange Jring.
Layer: common — the ring analogue of the four-state method.
Where the four-state method flips the two atoms of a bond (2² = 4 states) and
combines them to isolate a pairwise J, the 16-state method flips the four
atoms of one square plaquette (i, j, k, l) over a fixed bath (2⁴ = 16
states) and projects with the four-spin parity χ = s_i s_j s_k s_l
(mathematically, the Walsh character of the spin-flip group Z₂⁴):
Jring·S⁴ = (1 / 16M) · Σ_configs χ(config) · E(config)
By parity (character) orthogonality the projection annihilates every
lower-order term — the constant, single-spin (bath couplings), pairwise bonds,
and partial (≤3-spin) plaquettes — leaving only the genuine four-spin
coefficient. M is the plaquette multiplicity (how many squares close on the
same four atoms under PBC; M = 1 for a fully isolated plaquette).
χ is invariant under both a global spin flip (even number of factors) and
any permutation of the four corners, so symmetry-equivalent configurations carry
the same χ and the same energy. The 16 states therefore collapse
(via mag4.spinconfig.find_unique_configs()) to a handful of inequivalent
ones, and the projection is rewritten over the representatives with integer
weights w_u = (group size)·χ_u:
Jring·S⁴ = (Σ_u w_u · E[#u]) / (16M)
Intended for 2D square-lattice ring exchange (cuprates, etc.); the plaquette
is the nearest-neighbour square auto-detected by
mag4.energy_mapping.select_ring_plaquettes().
Functions
|
Which couplings are identifiable from the ring configs, and why not. |
|
Apply the ring formula to the per-config energies. |
|
Smallest supercell in which the target square plaquette is fully isolated — multiplicity |
|
|
|
The 16 spin configurations flipping the four plaquette atoms over the bath. |
|
Parse the PAIRWISE-J ANALYSIS design rows of a 16-state report. |
|
Parse the |
|
Four-spin parity |
|
Design-matrix rows of the unique ring configs (no extra DFT needed). |
|
Integer projection weight |
|
Pick the NN square plaquette for the ring term and return it as four distinct cell-atom indices. |
|
Print (and optionally write) the 16-state ring report. |
Classes
|
Parsed ring extraction formula: |
|
One square plaquette selected for the ring term. |
- class mag4.ring16.RingPlaquette(idx, labels, edge, multiplicity)[source]
Bases:
objectOne square plaquette selected for the ring term.
idxare the four cell-atom indices of the corners (incrystal.target_speciesorder);labelstheir labels;edgethe square edge length (Å);multiplicitythe number of distinct squares that close on exactly these four atoms (theMin the16Mdivisor).- Parameters:
- mag4.ring16.select_ring_quad(crystal, couplings, *, prefer_label=None, prefer_dist=None, tol_pos=0.15)[source]
Pick the NN square plaquette for the ring term and return it as four distinct cell-atom indices.
Raises
ValueErrorif no coupling shell forms a square, or if every square folds onto fewer than four distinct atoms (cell too small — enlarge it).- Return type:
- Parameters:
crystal (CrystalData)
couplings (list)
prefer_label (str | None)
prefer_dist (float | None)
tol_pos (float)
- mag4.ring16.find_ring_supercell(crystal, couplings, *, max_mult=4, prefer_label=None, prefer_dist=None)[source]
Smallest supercell in which the target square plaquette is fully isolated — multiplicity
M = 1: four independent atoms forming exactly one square, so the four-state-style divisor is exactly16(no16·M).This is the ring analogue of the four-state isolation criterion. At
M > 1the four atoms wrap onto their ownJ1images through the periodic boundary, so the plaquette is not independent of its copies and the DFT energies pick up self-interaction bias — the projection math tolerates it, but the physical extraction does not.Searches
(na, nb, nc)from smallest atom count upward (a layered square plaquette isolates withnc = 1). Returns((na, nb, nc), expanded crystal, plaquette). RaisesRuntimeErrorif no cell withinmax_multper axis reachesM = 1.- Return type:
Tuple[Tuple[int,int,int],CrystalData,RingPlaquette]- Parameters:
crystal (CrystalData)
couplings (list)
max_mult (int)
prefer_label (str | None)
prefer_dist (float | None)
- mag4.ring16.ring_design_records(crystal, couplings, unique_groups, quad, *, prefer_label=None, prefer_dist=None, tol=0.0005)[source]
Design-matrix rows of the unique ring configs (no extra DFT needed).
For each unique configuration the model energy is exactly
E[#u] = E0 + Σ_k c_k·(J_k·S²) + c_ring·(Jring·S⁴)
with
c_k = Σ_{⟨ij⟩∈k} s_i s_jover the unique bonds of shellkandc_ringthe four-spin plaquette coefficient. Returns energy-mapping style records{"number", "degeneracy", "sz", "coefficients"}where the ring column is labelled"Jring"— the raw material for deciding if and how the pairwiseJ_kcan be extracted from the very configurations the 16-state method already computes forJring.- Return type:
- Parameters:
crystal (CrystalData)
couplings (list)
unique_groups (List[List[FourStateConfig]])
quad (RingPlaquette)
prefer_label (str | None)
prefer_dist (float | None)
tol (float)
- mag4.ring16.analyze_pairwise_extractability(records, labels)[source]
Which couplings are identifiable from the ring configs, and why not.
A coupling is not extractable when its design-matrix column is constant across the configurations (the plaquette flips never change its bond sum) or lies in the span of the constant + the other columns (degenerate — only a combination is constrained). Returns
{label: (extractable, reason)}.
- mag4.ring16.ring_chi(config, quad)[source]
Four-spin parity
χ = Π_{m∈plaquette} s_m(±1) for one configuration.- Return type:
- Parameters:
config (FourStateConfig)
quad (RingPlaquette)
- mag4.ring16.generate_ring_16(ref_bath, quad)[source]
The 16 spin configurations flipping the four plaquette atoms over the bath.
Only the four plaquette corners differ between configs; the rest stay at
ref_bath.state_labelis theu/dpattern of the corners.- Return type:
- Parameters:
ref_bath (list)
quad (RingPlaquette)
- mag4.ring16.ring_weights(unique_groups, quad)[source]
Integer projection weight
w_u = (group size)·χ_uper unique config.All members of a symmetry group share
χ(permutation/flip invariant), so the per-group weight is well defined; this is verified defensively.- Return type:
- Parameters:
unique_groups (List[List[FourStateConfig]])
quad (RingPlaquette)
- mag4.ring16.format_ring_formula(weights, divisor, edge)[source]
Jring (...) = ( +w1*E[#1] +w2*E[#2] … ) / D(machine-parseable).
- mag4.ring16.write_ring_report(path, unique_groups, atoms, quad, supercell, n_sym_ops, *, n_supercell_atoms=None, ref_bath=None, design_records=None, coupling_dists=None, config_sgs=None, config_msgs=None, symmetric_structs=False, tr_pairs=None)[source]
Print (and optionally write) the 16-state ring report.
Optional extras (all analysis-only — the written structures stay P1):
design_records(fromring_design_records()) — adds the PAIRWISE-J ANALYSIS section: the design-matrix rows of the unique configs and, per coupling, whether/why it is extractable from the very energies computed forJring.coupling_dists—{label: d(Å)}shown next to each verdict.config_sgs— per-config(spacegroup_number, symbol)of the spin-decorated structure (spglib), shown as an extra column.tr_pairs(from--check-degeneracy) — config pairs related only by the antiunitary symmetry (unitary op × time reversal); their DFT energies must coincide andmag4-extractreports|ΔE|per pair.
- class mag4.ring16.RingFormula(terms, divisor, edge=None)[source]
Bases:
objectParsed ring extraction formula:
Jring·S⁴ = Σ w_i·E[#i] / divisor.
- mag4.ring16.parse_ring_report(report_path)[source]
Parse the
Jring = ( … ) / Dline of a 16-state report.- Return type:
- Parameters:
report_path (str)
- mag4.ring16.parse_ring_design(report_path)[source]
Parse the PAIRWISE-J ANALYSIS design rows of a 16-state report.
Returns
{"labels": [...], "records": [{"number", "degeneracy", "sz", "coefficients"}, ...]}(energy-mapping record format,Jringcolumn included) orNonewhen the report has no analysis section (older reports).
- mag4.ring16.compute_jring(formula, energies)[source]
Apply the ring formula to the per-config energies.
energiesmaps config id → object with anenergy_eVattribute (anmag4.energy.EnergyResult). Returns(Jring·S⁴ in eV, problems); the value isNonewhen an energy is missing/unparsed.