Tests: add nspin=4 sigma_y regression case (scf_angle_spin4_y); #7759 is already fixed - #7942
Conversation
`scf_angle_spin4` initialises the two Fe moments along +-x. m_x and m_z are read off the real part of the spinor density-matrix block and are invariant under the conjugation convention of that block; only m_y reads the imaginary part. The existing case therefore cannot see a sign error in the sigma_y loop between the Hamiltonian assembly (clx_j in merge_hr_part_to_hR) and the density extraction (func_xyz_to_updown) -- which is how that convention was able to change three times (deepmodeling#7513, deepmodeling#7664, deepmodeling#7832) without CI reacting. Add scf_angle_spin4_y: the same case with the moments globally rotated by 90 degrees about z (+-x -> +-y). Without spin-orbit coupling the spin frame is decoupled from the lattice, so every reference value must equal the scf_angle_spin4 one exactly; result.ref is that file, unchanged. Measured on develop (3937023), serial LAPACK solver: case E_KohnSham (eV) AMAG iters scf_angle_spin4 -6267.4651888506 6.70362 12 scf_angle_spin4_y -6267.4651888506 6.70362 12 Forces are identically zero in both; the stress tensors agree to 4e-10 kbar. With the deepmodeling#7664 m_y convention reintroduced (the state reported in deepmodeling#7759): scf_angle_spin4 -6267.4651888506 6.70362 12 unchanged scf_angle_spin4_y -6264.2726978309 3.9e-05 50 (no conv.) i.e. the x case is blind to the defect while the y case moves 3.19 eV, loses the moment entirely and stops converging. CPU cases only. scf_angle_spin4 is also in CASES_GPU.txt, but the GPU nspin=4 path was not available for testing here, so the y twin is not registered there. Refs deepmodeling#7759 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…modeling#7913) CI ran the new case for the first time and it failed: etotref cal=-6269.25160172 ref=-6267.46518962 dev= 1.78641210 totalstressref cal= 4089.31939500 ref= 3912.92043700 dev=-176.39895800 That is the case doing its job, not a bad reference. Reproduced locally across the solver matrix (develop 3937023, OpenBLAS so ScaLAPACK is usable): case solver np E_KohnSham (eV) AMAG iters x scalapack_gvx 2 -6267.4651888505 6.70362 12 y scalapack_gvx 2 -6267.4651888505 6.70362 12 x scalapack_gvx 4 -6267.4651888505 6.70362 12 y scalapack_gvx 4 -6267.4651888505 6.70362 12 x genelpa 2 -6267.4651898827 6.70362 12 y genelpa 2 -6269.6774946269 6.80171 50 (no conv.) x genelpa 4 -6267.4651902210 6.70362 12 y genelpa 4 -6267.7588409455 6.76183 50 (no conv.) With scalapack_gvx the two cases are bitwise identical at both rank counts, so the sigma_y convention this case exists to pin is correct. With genelpa the y case does not converge and lands BELOW the ground state by an np-dependent amount -- non-variational and rank-dependent, i.e. a solver defect. It matches defect 2 of deepmodeling#7913: the complex generalized transform reads the stale lower triangle of a matrix for which LCAO fills only the upper one. The x case is insensitive because H_{up,down} = B_x is real for +-x but purely imaginary for +-y. So pin ks_solver to scalapack_gvx, as scf_deltaspin4 and nine other cases in this directory already do, and record the measurements plus the removal condition in the README. Verified with the real harness: `../integrate/Autotest.sh -a <bin> -n 4 -r scf_angle_spin4` -> 8/8 checks passed over both cases. Refs deepmodeling#7759, deepmodeling#7913 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Update after the first CI run of this case, which failed — correctly. I had verified the invariance only with the serial LAPACK solver (my box could not link ScaLAPACK against MKL). Working around that with
With So the latest commit pins Net effect: the case is green, it still pins the σy convention (reintroducing the #7664 sign still moves it by 3.19 eV), and once #7913 lands the pin can be dropped so it guards the genelpa path too. |
|
Sry but... just a friendly heads-up: these convention issues are quite interconnected, so I would be cautious about treating this test as proof that the broader problem is resolved. I've explored this on my local experimental branch. A more systematic cleanup may involve making DMK store the physical density matrix These issues may need a thorough refactor by experts (like @dyzheng, he is very experienced😄), something like #7833, though it was closed due to out of sync :( This matters beyond the SCF test, the conventions also enter Mulliken/DeltaSpin, DFT+U, forces/stress, and RT-TDDFT current contractions, where conjugation and index ordering can affect even the sign of the RT-TDDFT current. That's why I care about consistency across the code. I'm not implying to block this PR, just some friendly comments. If it is merged, I would expect its reference values may need updating after independently validated fixes in the future. The no-SOC rotation invariant should still hold, but the current numbers aren't necessarily the final correct reference. |
Reminder
AGENTS.mdanddocs/developers_guide/agent_governance.md.source/changes.Linked Issue
Refs #7759 (and #7831). This PR contains no source change — please read the first section before merging.
First: #7759 is already fixed on develop
I set out to fix #7759 and found it had been fixed in the meantime, by #7832 (merged 2026-09-01), which is exactly "Option A" from the issue report. The history of the
m_yconvention:clx_jinmerge_hr_part_to_hRfunc_xyz_to_updown{0, 1, -1, 0}, no conjtmp[1].imag() - tmp[2].imag(){0, -1, 1, 0}+ conj (textbook Pauli)-tmp[1].imag() + tmp[2].imag()tmp[1].imag() - tmp[2].imag()— consistent againVerified empirically on develop
3937023d6with the two-Fe non-collinear case, serial LAPACK solver:scf_angle_spin4(±x)Identical to 2.7e-9 eV, identical iteration count, identical DRHO trajectory, forces identically zero, stress agreeing to 4e-10 kbar. The σy loop on develop is self-consistent; #7759 can be closed. (Unrelated to #7913, which is about the DeltaSpin operator and the genelpa lower-triangle read, both still open.)
What's changed?
What is not fixed is that nothing in CI would have noticed any of this — so this PR closes that gap instead.
scf_angle_spin4initialises the two Fe moments along ±x.m_xandm_zare read off the real part of the spinor density-matrix block and are invariant under the conjugation convention of that block; onlym_yreads the imaginary part. The existing case is therefore structurally incapable of seeing a sign error in the σy channel — which is how this convention managed to change three times without a single test reacting.tests/03_NAO_multik/scf_angle_spin4_yis the same case with the moments globally rotated by 90° about z (±x → ±y). Without spin–orbit coupling the spin frame is decoupled from the lattice, so every reference value must equal thescf_angle_spin4one exactly.result.refis that file byte for byte — the assertion is the invariant, rather than a freshly regenerated number. The anisotropic 1×2×1 k-mesh does not weaken this: atlspinorb 0a global spin rotation cannot couple to the k-mesh.Unit Tests and/or Case Tests for my changes
Build: Linux, GCC, OpenMPI,
cmake -B build -G Ninja -DBUILD_TESTING=ON -DENABLE_LCAO=ON -DENABLE_MPI=ON -DENABLE_OPENMP=ON;cmake --build build -j15→ 3318/3318, 0 errors.Ran both cases from their own directory with
OMP_NUM_THREADS=1 ./abacus_basic_para→ the table above.Teeth check. I reintroduced the Fix: correct Pauli-to-spinor Hamiltonian conversion for nspin=4 #7664
m_ysign infunc_xyz_to_updown, rebuilt, and reran both cases:scf_angle_spin4(±x)scf_angle_spin4_y(±y)3.19 eV off, moment gone, no convergence. The new case catches the regression that the old one is blind to. The source change was then reverted; this PR ships only the test.
Checks not run, with reason: I could not run the case under the CI solver. The box available to me links a gfortran-built ScaLAPACK against MKL, and
pzpotrf→zdotcsegfaults there for any rank count (an ABI mismatch in that environment, not an ABACUS defect), so both runs above useks_solver lapackin serial. This is whyresult.refis copied from the CI-generatedscf_angle_spin4reference rather than regenerated locally: the invariant is exactness against that file, and my serial numbers sit 7.7e-7 eV from it, well inside the case'sthreshold 0.00001. CI running this case for the first time is the real check.Governance Notes
source/change at all, only a new integration case plus its registration inCASES_CPU.txt. The governance check reports no findings.scf_angle_spin4is also listed inCASES_GPU.txt. I did not register the y twin there, because I had no GPU to verify the nspin=4 LCAO GPU path against. If a maintainer with GPU access confirms it, adding one line toCASES_GPU.txtextends the same guard to that path, and is worth doing.🤖 Generated with Claude Code