| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Fix two bugs in LCAO non-collinear Hamiltonian construction:
1. Wrong sign in off-diagonal elements: H_{up,down} = B_x + i*B_y (wrong)
should be B_x - i*B_y (correct), and vice versa for H_{down,up}.
Fixed by correcting clx_j coefficients in merge_hr_part_to_hR().
2. Missing complex conjugate in lower triangle fill: H(-R) used transpose
instead of conjugate transpose, breaking Hermiticity for complex matrices.
Fixed by using std::conj() when filling lower triangle.
These errors caused the non-collinear Hamiltonian to be the complex conjugate
of the correct result, leading to incorrect spin textures in nspin=4 calculations.
The PW code path was not affected.
Add test case and verification script to validate:
- H(R=0) Hermiticity: max|H - H^dagger| < 1e-10
- Off-diagonal phase: Im(H_{up,down}) < 0 for m||+y direction
See tests/03_NAO_multik/verify_hamiltonian_convention/TEST_DESIGN.md for details.
…pin=4
Fix three critical bugs in non-collinear (nspin=4) LCAO calculations:
1. DFT+U transfer_vu (dftu_lcao.cpp): Fix sign error in Pauli-to-spinor
conversion. The off-diagonal elements had wrong imaginary part sign:
- Before: V_{up,down} = 0.5*(V_x + i*V_y) (wrong)
- After: V_{up,down} = 0.5*(V_x - i*V_y) (correct, from sigma_y)
2. DFT+U force/stress (dftu_force_stress.hpp): Convert VU from Pauli basis
to spinor basis before force calculation. The old code incorrectly mixed
Pauli-basis VU with spinor-basis DM.
3. DeltaSpin force/stress (dspin_force_stress.hpp): Convert lambda from
Pauli basis to spinor basis. The constraint force F = lambda·dM/dR
requires proper Pauli-to-spinor conversion:
- lambda_spinor = (lambda_z, lambda_x, lambda_x, -lambda_z)
for (uu, ud, du, dd) components.
These fixes ensure consistent Pauli-to-spinor conversion across all modules:
- H construction (gint_common.cpp): already fixed
- DFT+U Hamiltonian: fixed in this commit
- DFT+U force/stress: fixed in this commit
- DeltaSpin force/stress: fixed in this commit
Verified by scf_u_spin4 test (nspin=4 + DFT+U): SCF converges correctly.
…ot spinor basis Two bugs fixed in dftu_force_stress.hpp: 1. Removed incorrect VU Pauli-to-spinor conversion: DM for nspin=4 is stored in Pauli basis (rho_0, rho_x, rho_y, rho_z) per func_xyz_to_updown(), so VU must also stay in Pauli basis for the force trace formula F = -Tr(VU * dDM/dR). 2. Removed force *= 2.0 for nspin=4: Pauli basis already includes all spin channels, unlike nspin=1 where the factor of 2 accounts for spin degeneracy. Updated scf_u_spin4 result.ref accordingly.
… covers all spin channels
Constructor 1 of ELPA_Solver was missing elpa_set_integer("blacs_context", ...)
while Constructor 2 (otherParameter) already had it. Without blacs_context,
ELPA's internal MPI operations (e.g. MPI_Bcast in complex Cholesky and
invert_triangular) can fail with INVALID DATATYPE when using complex eigensolves.
Also update scf_angle_spin4 result.ref with corrected reference energy.
…_updown) For Pauli decomposition: rho = rho_0*I + rho_x*sigma_x + rho_y*sigma_y + rho_z*sigma_z sigma_y = [[0,-i],[i,0]], so rho_updown = rho_x + i*rho_y, rho_downup = rho_x - i*rho_y Thus rho_y = Im(rho_updown - rho_downup) = tmp[1].imag() - tmp[2].imag]. Previously the real version had -tmp[1].imag()+tmp[2].imag() = -2*rho_y (wrong sign), and the complex version had i*(tmp[1].imag()-tmp[2].imag()) = 2i*rho_y (wrong formula). This broke rotational invariance: mag along y gave wrong energy (~4 eV deviation vs x/z).
…verify_hamiltonian_convention test dir - Revert density_matrix.cpp func_xyz_to_updown rho_y sign fix from commit 52ee608 (belongs on a separate DM-fix branch) - Remove tests/03_NAO_multik/verify_hamiltonian_convention/ (debug helper) - Update result.ref for scf_angle_spin4 and scf_u_spin4 to match current code (Pauli-to-spinor + ELPA fixes only)
…on clx_j fix) The gint_common.cpp fix corrects Pauli→spinor (H construction) and the density_matrix.cpp fix corrects spinor→Pauli (DM Fourier transform). Both must use the same σ_y convention for self-consistency. Also update result.ref files for both test cases.
…spin=4 block Both VU (from cal_v_of_u) and DMR are stored in Pauli basis for nspin=4, so the Pauli-to-spinor conversion in force/stress calculation is NOT needed. The previous result.ref for scf_u_spin4 (totalforceref=6.562) was incorrect because it was generated with code that mixed Pauli-basis VU with incorrectly converted values. The correct force is 11.33, consistent with the physical Pauli-basis trace Tr(VU * dDM/dR). Changes: - Remove empty if(nspin==4) block in dftu_force_stress.hpp (no conversion needed) - Update scf_u_spin4/result.ref: totalforceref 6.562 -> 11.332 (correct value) - Update scf_angle_spin4/result.ref: energy/stress to match computed values - Add scf_angle_spin4/threshold: relax energy threshold to 1e-5 eV for non-collinear calculation numerical reproducibility - Update scf_out_dos_spin4/result.ref: force/stress to match computed values
…nspin=4
Fix inconsistent Pauli-to-spinor and spinor-to-Pauli conversion signs
across multiple modules, which broke rotational invariance in
non-collinear (nspin=4) LCAO calculations.
The standard sigma_y = [[0,-i],[i,0]] convention requires:
H_{up,down} = B_x - i*B_y
rho_y = -Im(rho_updown - rho_downup)
Changes:
- density_matrix.cpp: fix rho_y sign in func_xyz_to_updown
(real: restore correct -Im(updown)+Im(downup);
complex: use i*(updown-downup) with full complex values)
- dftu_pw.cpp: fix Pauli-to-spinor sign in DFT+U transfer_vu (PW path)
- spin_constrain.h: fix pauli_to_moment My sign, update comments
- dspin_lcao.cpp: fix cal_coeff_lambda Pauli-to-spinor sign
- deltaspin_core_test.cpp: update unit test for corrected formula
- scf_u_spin4/result.ref: update reference values after correction
Resolved conflicts in density_matrix.cpp and result.ref by keeping the corrected Pauli-spinor conversion signs.
Correct the comment to match the sigma_y = [[0,-i],[i,0]] convention: My = -Im(occ[1] - occ[2]) instead of Im(occ[1] - occ[2])
There was a problem hiding this comment.
LGTM
Sorry, something went wrong.
Co-authored-by: Mohan Chen <mohanchen@pku.edu.cn>
Fix comment Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
These nspin=4 LCAO references were updated by deepmodeling#7664 (1457e26) to match its m_y sign convention in func_xyz_to_updown, which sign-flips the transverse magnetization (the stored DM block is conj(P); m_y reads Im so it flips). Commit fa8492f reverts that convention and restores the correct pre-deepmodeling#7664 physics (verified: Mn3Sn recovers the 120-deg AFM ground state, lower energy). scf_u_spin4 (mag[111]+U): force 14.360->11.332, stress 4334.0->4697.8, etot -6789.142->-6789.282 (the deepmodeling#7664 bug raised the energy by ~0.14 eV). scf_out_dos_spin4 / scf_angle_spin4: tiny (1e-4) reverts, near-collinear. 099_PW_DJ_SO left unchanged (PW path, not affected by the LCAO fix). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Guards the func_xyz_to_updown m_y convention against the deepmodeling#7664 regression. Asserts the physical invariant: the magnetization <sigma> encoded in a DM spinor block (built with cal_dm_psi's convention DM=conj(P)) is recovered with the correct sign in ALL THREE components by func_xyz_to_updown. The m_y channel (Im) is the sensitive one; m_x/m_z (Re) are conj-invariant. Fails on the deepmodeling#7664 convention (m_y sign-flipped), passes after the fix. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Follow-up to deepmodeling#7832 (revert deepmodeling#7664 m_y convention) addressing review feedback. DeltaSpin (was left in the deepmodeling#7664 y-convention while the DM was reverted): - dspin_lcao.cpp cal_coeff_lambda: revert to lambda_ud = lambda_x + i*lambda_y. pauli_to_moment already reads the bare +Im (via deepmodeling#7748) and measures the physical +m_y from the conj-first occupation; deepmodeling#7664 flipped both the measurement and this drive (y-mirror), deepmodeling#7748 reverted only the measurement, so the constraint loop was driving the y-mirror of the target. Restoring the pre-deepmodeling#7664 drive re-pairs it with the (correct) measurement. - spin_constrain.h/.cpp: fix stale comments (occ is conj-first; My=+Im). - deltaspin_core_test.cpp: local re-impl and GeneralCase pinned My=-0.4 (deepmodeling#7664); corrected to the bare +0.4 so it stops enshrining the wrong sign. Tests: - test_soc_magnetization_roundtrip: add the <complex> (multi-k) specialization case; drop the dangling ref/MSG doc path from the comment. - symm_rho_soc_test: relabel SpinConventionCoupling — it validates spin_so3 in the PHYSICAL-rho frame, not the runtime conj-first DM path; note it does not pin the DM convention. Mulliken: - output_mulliken.cpp: comment flagging that M_y (pre-existing, since 3.7.0) likely reports -m_y from the conj-first DM and must not be used as an oracle for the DM convention; real fix + unit test deferred to a separate PR. Not covered here (need integration runs / separate PR): regenerate & report the nspin=4 reference values from post-PR code; nspin=4 DeltaSpin regression with nonzero m_y target; in-plane non-collinear symmetry integration test; nspin=4 DMR restart compatibility with deepmodeling#7664-era files. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…updown Replaces the local Pauli re-implementation with the actual elecstate::DensityMatrix_Tools::func_xyz_to_updown, fed the conj-first stored DM block (DM=conj(P)) exactly as the runtime does, and asserts (a) it recovers the physical magnetization and (b) spin_so3 (the rotation psymmg_soc applies to the grid) agrees with the SU(2) block rotation + real extraction. The two conventions can no longer drift apart silently; the test fails on the deepmodeling#7664 m_y flip. Links density_matrix.cpp only (no io/mocks needed). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fix comment Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
These nspin=4 LCAO references were updated by deepmodeling#7664 (1457e26) to match its m_y sign convention in func_xyz_to_updown, which sign-flips the transverse magnetization (the stored DM block is conj(P); m_y reads Im so it flips). Commit fa8492f reverts that convention and restores the correct pre-deepmodeling#7664 physics (verified: Mn3Sn recovers the 120-deg AFM ground state, lower energy). scf_u_spin4 (mag[111]+U): force 14.360->11.332, stress 4334.0->4697.8, etot -6789.142->-6789.282 (the deepmodeling#7664 bug raised the energy by ~0.14 eV). scf_out_dos_spin4 / scf_angle_spin4: tiny (1e-4) reverts, near-collinear. 099_PW_DJ_SO left unchanged (PW path, not affected by the LCAO fix). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Guards the func_xyz_to_updown m_y convention against the deepmodeling#7664 regression. Asserts the physical invariant: the magnetization <sigma> encoded in a DM spinor block (built with cal_dm_psi's convention DM=conj(P)) is recovered with the correct sign in ALL THREE components by func_xyz_to_updown. The m_y channel (Im) is the sensitive one; m_x/m_z (Re) are conj-invariant. Fails on the deepmodeling#7664 convention (m_y sign-flipped), passes after the fix. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Follow-up to deepmodeling#7832 (revert deepmodeling#7664 m_y convention) addressing review feedback. DeltaSpin (was left in the deepmodeling#7664 y-convention while the DM was reverted): - dspin_lcao.cpp cal_coeff_lambda: revert to lambda_ud = lambda_x + i*lambda_y. pauli_to_moment already reads the bare +Im (via deepmodeling#7748) and measures the physical +m_y from the conj-first occupation; deepmodeling#7664 flipped both the measurement and this drive (y-mirror), deepmodeling#7748 reverted only the measurement, so the constraint loop was driving the y-mirror of the target. Restoring the pre-deepmodeling#7664 drive re-pairs it with the (correct) measurement. - spin_constrain.h/.cpp: fix stale comments (occ is conj-first; My=+Im). - deltaspin_core_test.cpp: local re-impl and GeneralCase pinned My=-0.4 (deepmodeling#7664); corrected to the bare +0.4 so it stops enshrining the wrong sign. Tests: - test_soc_magnetization_roundtrip: add the <complex> (multi-k) specialization case; drop the dangling ref/MSG doc path from the comment. - symm_rho_soc_test: relabel SpinConventionCoupling — it validates spin_so3 in the PHYSICAL-rho frame, not the runtime conj-first DM path; note it does not pin the DM convention. Mulliken: - output_mulliken.cpp: comment flagging that M_y (pre-existing, since 3.7.0) likely reports -m_y from the conj-first DM and must not be used as an oracle for the DM convention; real fix + unit test deferred to a separate PR. Not covered here (need integration runs / separate PR): regenerate & report the nspin=4 reference values from post-PR code; nspin=4 DeltaSpin regression with nonzero m_y target; in-plane non-collinear symmetry integration test; nspin=4 DMR restart compatibility with deepmodeling#7664-era files. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…updown Replaces the local Pauli re-implementation with the actual elecstate::DensityMatrix_Tools::func_xyz_to_updown, fed the conj-first stored DM block (DM=conj(P)) exactly as the runtime does, and asserts (a) it recovers the physical magnetization and (b) spin_so3 (the rotation psymmg_soc applies to the grid) agrees with the SU(2) block rotation + real extraction. The two conventions can no longer drift apart silently; the test fails on the deepmodeling#7664 m_y flip. Links density_matrix.cpp only (no io/mocks needed). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| Back | FazBrowse Home | New Git URL |
Reminder
Linked Issue
Fix #7513
Unit Tests and/or Case Tests for my changes
What's changed?
Governance Notes