Skip to content

Feature: Support PW partial-charge output under ultrasoft pseudopotentials (USPP) - #7944

Open
AsTonyshment wants to merge 4 commits into
deepmodeling:developfrom
AsTonyshment:feat/uspp_pchg
Open

Feature: Support PW partial-charge output under ultrasoft pseudopotentials (USPP)#7944
AsTonyshment wants to merge 4 commits into
deepmodeling:developfrom
AsTonyshment:feat/uspp_pchg

Conversation

@AsTonyshment

@AsTonyshment AsTonyshment commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

What's changed?

PW out_pchg previously exported only the squared pseudo-wavefunction amplitude for ultrasoft pseudopotentials (USPP). Since USPP states are normalized with the overlap operator, this soft contribution alone generally does not integrate to the expected state charge. This PR adds the missing augmentation contribution to produce the complete band-decomposed valence density.

The single-state density is
image
where $Q_{ij}^{I}$ are the augmentation functions and $\beta_i^I$ are the atomic projectors.

The implementation shares the projector-overlap and augmentation-density routines with ElecStatePW. Augmentation is constructed on the dense charge grid and included before the merged density is symmetrized, with support for k-point and band parallelism and mixed norm-conserving/USPP species.

Related changes:

  • Split the PW partial-charge and wavefunction output implementations into .h and .cpp files with reusable workspaces, and use the solver's native CPU/GPU wavefunction precision for FFTs and projector overlaps.
  • Run real-space wavefunction output alongside partial-charge output after each electronic solve. During relaxation and MD, each ionic step overwrites the same output filenames.
  • Reject PW NSCF mem_saver=1 when out_pchg, out_wfc_norm, or out_wfc_re_im is specified, because wavefunctions from earlier k points are overwritten.
  • Clarify the parameter descriptions: USPP partial charge includes augmentation, while wavefunction outputs contain pseudo-wavefunction amplitudes normalized with the overlap operator. Regenerate the parameter documentation.
  • Add the NaCl USPP regression case 213_PW_USPP_pchg_wfc, covering occupied and unoccupied partial charges, wavefunction output, double grids, and k-point/band parallelism.

Test results

Test case: NaCl, nspin=1, CPU double, 4 MPI × 2 OpenMP

Measured USPP pchg cube integral Before (d9d5206) After
Band 1 (occupied), separate k point 1 1.074619848273 2.000000000000
Band 1 (occupied), separate k point 2 1.074280548227 2.000000000000
Band 1 (occupied), merged k points 1.074450198250 2.000000000000
Band 9 (unoccupied), separate k point 1 2.386923580266 2.000000000000
Band 9 (unoccupied), separate k point 2 1.981077616418 2.000000000000
Band 9 (unoccupied), merged k points 2.184000598342 2.000000000000

@AsTonyshment
AsTonyshment requested review from mohanchen and a lite review from Copilot September 9, 2026 07:53
@AsTonyshment
AsTonyshment removed the request for review from Copilot September 9, 2026 07:54
@AsTonyshment
AsTonyshment requested a lite review from Copilot and removed request for Copilot September 9, 2026 08:10
@AsTonyshment
AsTonyshment requested a lite review from Copilot and removed request for Copilot September 9, 2026 08:36
@mohanchen mohanchen added Features Needed The features are indeed needed, and developers should have sophisticated knowledge Refactor Refactor ABACUS codes labels Sep 9, 2026
const std::complex<double> zero_d(0, 0);
char transa = 'N';
char transb = 'T';
zgemm_(&transa,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

use blas connector?

const std::complex<double>* owner_wfcr = transform_wfc(&psi_(local_band, component * work->npwx), ik, component, work);
std::copy(owner_wfcr, owner_wfcr + work->dense_nrxx, work->wfcr[component].begin());
}
#ifdef __MPI

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

you don't need to write #ifdef __MPI, it should be included in the bcast_data function

work->state_weight,
&work->state_becsum);
}
#ifdef __MPI

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

same as above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Features Needed The features are indeed needed, and developers should have sophisticated knowledge Refactor Refactor ABACUS codes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants