Skip to content

Fix DMR spin-channel mismatch in openshell LR spectra - #8016

Merged
mohanchen merged 3 commits into
deepmodeling:developfrom
maki49:fix-lr
Sep 25, 2026
Merged

mohanchen merged 3 commits into
deepmodeling:developfrom
maki49:fix-lr

Conversation

@maki49

@maki49 maki49 commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator

The bug only happens in: openshell LR (lr_unrestricted=1) && length form (abs_gauge="length") && multi-k (gamma_only=0).
DMR will be doubled before the fix. Now it gives the same oscillator strength as the gamma-only case.

Copilot AI lite review requested due to automatic review settings September 25, 2026 01:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Add focused regression tests and remove the ambiguous default argument.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 2 Medium severity

Open (2)
What changed in this PR

Fixes spin-channel mixing in open-shell, multi-k length-form LR spectra and adds MPI-safe HContainer handling.

Changes:

  • Adds spin-selective complex DMR extraction.
  • Passes the active spin channel during spectrum calculation.
  • Guards unavailable distributed HContainer pairs.
File Summary
source/​source_lcao/​module_lr/​utils/​lr_util_hcontainer.h Declares spin-selective extraction; the new type default should be removed.
source/​source_lcao/​module_lr/​utils/​lr_util_hcontainer.cpp Implements channel extraction and MPI pair checks; focused regression coverage is missing.
source/​source_lcao/​module_lr/​lr_spectrum.cpp Uses the selected spin channel; the bug-specific regression case is not covered.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread source/source_lcao/module_lr/lr_spectrum.cpp
Comment thread source/source_lcao/module_lr/utils/lr_util_hcontainer.cpp Outdated
maki49 and others added 2 commits September 24, 2026 22:45
LR_Spectrum<complex<double>>::cal_transition_dipole_istate_length looped
over all nspin_x spin channels of the transition density matrix but
called get_DMR_real_imag_part() without selecting a channel, so the
function copied every channel of DM_trans (size nspin_x) into the
single-channel DM_trans_real_imag. For nspin_x==2 (open-shell/spin-
polarized, multi-k) this hits an assertion failure (or out-of-bounds
access in release builds), and even when it doesn't crash it double-
counts the merged density on each iteration of the outer loop.

Add an overload of get_DMR_real_imag_part() that copies a single named
spin channel into the (always single-channel) DMR_real, and use it from
the two call sites in cal_transition_dipole_istate_length so each outer
loop iteration only processes its own channel, matching the double
(gamma-only) specialization's behavior.

Verified: reproduced the original assertion failure with gdb on the
open-shell (nspin=2) multi-k length-gauge path, confirmed the fix
resolves it, and confirmed the fixed multi-k oscillator strength /
transition dipoles match the gamma-only result exactly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
get_DMR_real_imag_part() (both overloads) and set_HR_real_imag_part()
dereferenced the result of HContainer::find_pair(ia, ja) without a
null check. Under real multi-rank MPI parallelism, the HContainer is
distributed 2D block-cyclic, so find_pair() legitimately returns
nullptr for atom pairs not owned by the current rank — dereferencing
that pointer segfaults.

Reproduced with gdb on tests/08_EXX/54_GO_ULR_HF (gamma_only=0, KPT
1 1 1, mpirun -np 2): SIGSEGV in get_DMR_real_imag_part, called from
OperatorLRHxc::grid_calculation during the Casida eigenvalue solve —
a different call site/crash than the spin-channel-mismatch bug fixed
in the previous commit, and only reproducible with more than one MPI
rank (a single-rank run owns every atom pair locally, masking the
bug).

Skip atom pairs not present on the local rank, matching the existing
pattern used elsewhere in the codebase for MPI-parallel HContainer
access. Verified: the same 54_GO_ULR_HF case now runs cleanly under
mpirun -np 2 (gdb shows a clean exit, no crash) and its excitation
energies exactly match both the gamma_only=1 run and result.ref.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Upstream deepmodeling#8000 renamed elecstate::DensityMatrix to module_dm::DensityMatrix
and get_DMR_vector/get_DMR_pointer to get_dmr_vec/get_dmr_ptr; update the
spin-index overload added in this branch accordingly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@mohanchen mohanchen added Bugs Bugs that only solvable with sufficient knowledge of DFT EXX and lr-TDDFT Related to EXX or lr-TDDFT Refactor Refactor ABACUS codes labels Sep 25, 2026
@mohanchen
mohanchen merged commit 7fb23a2 into deepmodeling:develop Sep 25, 2026
17 checks passed
@maki49
maki49 deleted the fix-lr branch September 29, 2026 08:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bugs Bugs that only solvable with sufficient knowledge of DFT EXX and lr-TDDFT Related to EXX or lr-TDDFT Refactor Refactor ABACUS codes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants