Skip to content

refactor(dfpt): route the first-order core response through module_charge - #8263

Merged
mohanchen merged 7 commits into
deepmodeling:developfrom
Zanthoxylum:refactor-dfpt-nlcc-reuse
Nov 2, 2026
Merged

mohanchen merged 7 commits into
deepmodeling:developfrom
Zanthoxylum:refactor-dfpt-nlcc-reuse

Conversation

@Zanthoxylum

Copy link
Copy Markdown
Collaborator

Summary

The core-charge math for the non-linear core correction was implemented
three times: the ground-state module_charge::set_rho_core, the DFPT
first-order response inside DFPT_Rho::compute_drhoc_g, and the DFPT
dynmatcc real-space route accum_nlcc_diag. This PR consolidates the
core-charge math in module_charge so each piece exists once:

  • module_charge::set_drho_core (new, chg_tools): the q-shifted
    first-order core response moves verbatim out of
    DFPT_Rho::compute_drhoc_g — the single-atom structure-factor phase
    exp(-i(G+q)tau) and the -i tpiba (G+q)_dir derivative around the
    shared radial kernel. DFPT_Rho::compute_drhoc_g becomes a thin
    delegate; the public API and every call site are unchanged. Design
    note (documented on the interface): unlike set_rho_core, it
    evaluates per G — |G+q| differs at every ig, so the gg_uniq
    shell cache of the q = 0 path cannot be reused.
  • module_charge::core_charge_form_factor (new, chg_tools): the
    numeric Simpson radial transform
    4pi/Omega Int r^2 rho_atc(r) j0(g r) dr, previously duplicated
    inline in both the first-order response and accum_nlcc_diag; both
    now call it, and the per-point Bessel/Simpson includes drop out of
    the DFPT translation units.
  • The ground-state set_rho_core keeps its cached, multithreaded
    non_linear_core_correction (numeric + analytic shells) — that
    structure does not fit the per-point q-shifted paths; the boundary is
    documented on the new interface.
  • The DFPT test targets that compile dfpt_rho.cpp directly
    (rho/phon/xc_analytic serial, pw_run) now also compile
    chg_tools.cpp — the delegate's cross-module call is otherwise an
    undefined reference in those directly-linked test binaries.

The layering follows existing precedent (source_pw/module_pwdft
already includes source_estate; dfpt_rho.cpp already included
chg_tools.h).

What did NOT change

  • No behavior change: the moved bodies are verbatim; the
    DrhocLocalizesAtTheAtomNotItsMirror phase regression (localization
    • exp(-i q.tau) phase check at generic q) passes without touching
      the test.

Verification

cmake --build build-gcc13 --target abacus_basic_para MODULE_DFPT_rho_serial \
  MODULE_DFPT_phon_serial MODULE_DFPT_xc_analytic_serial MODULE_DFPT_pw_run_test -j 20
ctest --test-dir build-gcc13 -R "MODULE_DFPT"      # 10/10 targets Passed
  • The affected test binaries were deleted and rebuilt from scratch
    (make exit code 0 on every target); full MODULE_DFPT suite
    10/10.
  • Anchor against the pre-change baseline (branch binary): bn_hex_G
    full DFPT rerun (the nlcc-bearing wurtzite case; exercises both the
    first-order response and the dynmatcc route) — phonon frequencies and
    the QE-format dyn.q0 output bit-identical to the pre-change
    results.

Documentation

No docs change needed: internal reuse refactor, no INPUT, interface, or
behavior change.

…arge

The q-shifted core-density response (compute_drhoc_g's numeric Simpson
radial transform, the single-atom structure-factor phase exp(-i(G+q)tau)
and the -i tpiba (G+q)_dir derivative) moves verbatim from
DFPT_Rho::compute_drhoc_g to the new module_charge::set_drho_core,
next to its ground-state sibling set_rho_core -- one home for the
core-charge math instead of two parallel implementations. DFPT_Rho::
compute_drhoc_g becomes a thin delegate (public API and call sites
unchanged). Per-point |G+q| evaluation (no gg_uniq shell cache) is
documented in the interface: the shell cache is only valid at q = 0.
The DrhocLocalizesAtTheAtomNotItsMirror regression passes unchanged;
bn_hex_G anchor rerun verified bit-identical dyn output.
…t_rho.cpp

compute_drhoc_g now delegates to module_charge::set_drho_core, so the
test targets compiling dfpt_rho.cpp directly (rho/phon/xc serial,
pw_run) need chg_tools.cpp in their SOURCES. Rebuild from deleted
binaries + full MODULE_DFPT ctest: 10/10.
…T nlcc routes

The numeric Simpson radial kernel (4pi/Omega Int r^2 rho_atc j0(gr) dr)
was duplicated between the moved set_drho_core and the dynmatcc
real-space route accum_nlcc_diag. Extract it as
module_charge::core_charge_form_factor and call it from both; the
per-point include math_integral/math_sphbes drop out of the DFPT
translation units. The ground-state set_rho_core keeps its cached,
multithreaded non_linear_core_correction (numeric+analytic shells),
documented on the new interface. Rebuild from deleted binaries + full
MODULE_DFPT ctest 10/10; bn_hex_G anchor rerun bit-identical
(frequencies and dyn.q0).
@Zanthoxylum Zanthoxylum added Refactor Refactor ABACUS codes DFPT Density Functional Perturbation Theory labels Nov 2, 2026

@ABACUS-PR-BOT ABACUS-PR-BOT left a comment

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.

The extracted NLCC formulas match the previous implementation by static comparison. No builds or runtime tests were run; the reported test and bit-identical results were not independently verified.

Non-blocking: The unchanged DrhocLocalizesAtTheAtomNotItsMirror phase check in dfpt_rho_serial_test.cpp:865-879 predates this PR, but is cited as validation. Its extra /lat0 changes the expected phase from about -0.02851 to -0.01509 rad; omitted and reversed q-only phases are then about 0.015 and 0.044 rad from that expectation, both within the 0.05 tolerance. Please correct the expected phase and make the assertion distinguish those cases. The moved production phase is correct.

…icit K conventions

core_charge_form_factor now takes a caller-owned scratch buffer of size
mesh and allocates nothing per call -- set_drho_core reuses one buffer
across its G loop and accum_nlcc_diag one across the six tensor-component
passes, restoring the pre-extraction allocation behavior. The interface
documentation states the conventions explicitly: q_cart is in the scaled
gcar units (q_frac * ucell.G), K = tpiba * (gcar + q_cart) is the
physical 1/bohr wavevector, |K| enters the radial transform and K.tau_
cart the phase, tau_cart = lat0 * tau; the implementation locals are
renamed to match (k_phys). Arithmetic unchanged. Rebuild from deleted
binaries + full MODULE_DFPT ctest: 10/10.
…-reuse

# Conflicts:
#	source/source_pw/module_dfpt/test/CMakeLists.txt
#	source/source_pw/module_dfpt/test_serial/CMakeLists.txt

@ABACUS-PR-BOT ABACUS-PR-BOT left a comment

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.

The scratch-reuse and unit-documentation follow-ups are addressed, and the CMake merge retains the required source entries. The earlier phase-test suggestion remains open; one additional magnitude-test suggestion is below. Static review of 5b7133953: no builds or runtime tests were run, and the author-reported results were not independently verified.

…ssian

core_charge_form_factor now has a focused unit test in test_chg_tools:
the closed-form spherical transform of exp(-alpha r^2),
sqrt(pi)/(4 alpha^{3/2}) exp(-k^2/4 alpha), evaluated at K = 0 and four
finite K values with one scratch buffer reused across the calls. This
independently constrains the absolute radial normalization (4pi/Omega
and the Simpson mesh convention) that the DFPT localization/phase
regresses do not pin. MODULE_CHARGE_tools rebuilt from a deleted binary;
full target passes.

@ABACUS-PR-BOT ABACUS-PR-BOT left a comment

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.

Static incremental review at 89e7a27 covered the Gaussian reference, Simpson mesh, scratch reuse and test registration. I did not run builds or tests.

@mohanchen
mohanchen merged commit eb3396e into deepmodeling:develop Nov 2, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

DFPT Density Functional Perturbation Theory Refactor Refactor ABACUS codes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants