fix(uhfk): handle spin-block Transfer entries consistently in hermiticity check and sublattice fold - #164
Open
aoymt wants to merge 2 commits into
Open
fix(uhfk): handle spin-block Transfer entries consistently in hermiticity check and sublattice fold#164aoymt wants to merge 2 commits into
aoymt wants to merge 2 commits into
Conversation
…sfer entries In normal mode (enable_spin_orbital=False) a spin-orbital-format Transfer file may carry orbital indices up to 2*norb; _check_orbital_index accepts them for compatibility and _make_ham_trans drops them with a warning. But _check_hermite scattered every entry into a (nx,ny,nz,norb,norb) array, so a spin-block index raised an unhandled IndexError during __init__ and the documented ignored-with-warning path was unreachable. With a sublattice fold the inflated self.norb happened to absorb the indices instead, and the dropped entries landed in sublattice-orbital slots they do not belong to, spuriously failing the strict hermiticity check. Size the check array with the pre-reshape norb (the check runs before the sublattice reshape) and skip the spin-block entries, matching what _make_ham_trans keeps in H(k). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nto H(k) The normal-mode branch of fold.reshape_interaction folds orbital indices with the physical stride a + norb_phys_orig * cellidx, which relabels a spin-block index (a >= norb_phys_orig, legal in the compatibility path for spin-orbital-format files read with enable_spin_orbital=False) onto the folded index of a genuine sublattice orbital. The relabeled entries then pass _make_ham_trans's index guard and enter H(k) as spurious inter-orbital hoppings, silently corrupting the Hamiltonian instead of being dropped: on a 1-orbital chain with CellShape=[6,1,1], SubShape=[3,1,1], onsite -1 and spin-block hops 0.7 at R=+-1, H(k) gained 0.7 off-diagonals where -1 * identity is correct. RPA/FLEX share this fold and had the same latent defect. Skip such entries before folding, consistent with the solvers dropping them from H(k), and emit the ignore-warning from the fold: the dropped entries no longer reach the solvers' own spin-block warning. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related fixes for how UHFk handles spin-block
Transferentries — orbitalindices in
[norb, 2*norb)from Wannier90 spin-orbital-format files read innormal mode (
enable_spin_orbital = false). The documented behavior for suchentries is "ignored with a warning" (
_make_ham_trans), but two otherconsumers of the
Transfertable did not implement it:_check_hermitecrashed with an unhandledIndexError(fix insrc/hwave/solver/uhfk.py). The check scattered every entry into an arrayof shape
(nx, ny, nz, norb, norb), so any spin-block index was out ofbounds. Since
_check_interactionruns in__init__before_make_ham_trans, the documented ignored-with-warning path was unreachablefor such files. With a sublattice fold the inflated
self.norbhappened toabsorb the indices instead, but the dropped entries landed in
sublattice-orbital slots they do not belong to and could spuriously fail
the
strict_hermitecheck.fold.reshape_interactionsilently corrupted H(k) (fix insrc/hwave/solver/fold.py). The normal-mode folda + norb_phys_orig * cellidxrelabels a spin-block index onto the foldedindex of a genuine sublattice orbital. The relabeled entries then pass
_make_ham_trans's index guard and enter H(k) as spurious inter-orbitalhoppings instead of being dropped. Verified repro: a 1-orbital chain with
CellShape = [6,1,1],SubShape = [3,1,1], onsite −1 and spin-block hops0.7 at R = ±1 produced 0.7 off-diagonals in H(k) where −1 × identity is
correct. RPA/FLEX share this fold and had the same latent defect.
Fix
Both sites now skip entries with an orbital index
>= norb_orig, matching thesemantics of
_make_ham_transdropping them from H(k):_check_hermitesizes its array with the pre-reshapenorb(the check runsbefore the sublattice reshape, so
Transferstill carries original-geometryindices) and excludes spin-block entries from the hermiticity comparison —
the check covers exactly the terms that end up in H(k).
reshape_interactionskips spin-block entries before folding and emits theignore-warning itself, since the dropped entries can no longer reach the
solvers' own spin-block warning. No duplicate logs: without a sublattice the
warning still comes from
_make_ham_trans, with one it comes from the fold.Per-consumer guards were chosen deliberately as the minimal fix; consolidating
the drop into a single normalization point right after
_check_orbital_indexis planned as a follow-up refactor once the current feature work stabilizes.
Tests
New regression file
tests/test_uhfk_spin_block_transfer.py(3 tests, allverified to fail before their respective fix):
SubShape = [1,1,1]must not raise(the original
IndexError), and H(k) must equal the orbital block ⊗ spinidentity — the entry is deliberately non-hermitian to pin down that dropped
entries are excluded from the check rather than checked in a larger array;
SubShape(=CellShape), an unpaired spin-block hop mustnot abort the strict hermiticity check via mis-folded slots;
Transfermust carry no spin-blockindices and
ham_transmust equal −1 × identity.Full sweep passing:
tests/test_uhfk_*.py,test_uhf.py,test_wraparound_hopping.py,test_block_matrix.py,test_qlms_run_result.py,plus the RPA fold-related tests (
test_rpa_fold_collision.py,test_rpa_trans_mod.py,test_rpa_so_trans_mod.py,test_rpa_geom_norb.py)and
test_rpa_1orb/2orb/spin/output/ext— 146 + 33 tests.🤖 Generated with Claude Code