Repository navigation
feat(dfpt): acoustic sum rule enforcement (dfpt_asr = no | simple | crystal) - #8182
Conversation
Print the per-atom row-sum norm of the Gamma dynamical matrix right after the raw diagonalization and, when the LO-TO correction runs, again on the corrected matrix (the nonanalytic term carries its own Z* sum rule, so the two violations are audited separately). This is the diagnostics feeder for the acoustic-branch investigation: the existing check_sum_rule helper only returns a bool against a 1e-6 relative tolerance and is not wired anywhere, while the observed Gamma acoustic modes are off by tens to hundreds of cm^-1 across all ten validation systems.
New INPUT parameter dfpt_asr = no (default) | simple | crystal, applied to the RAW Gamma dynamical matrix before the LO-TO nonanalytic term, together with the Z* sum rule sum_a Z*_a = 0 on the Born effective charges (the LO-TO term then consumes the corrected charges, QE dynmat set_asr order). Unconstrained linear-response self-consistency violates both sum rules at the percent to tens-of-percent level -- measured on ten validation systems (raw worst rowsum rel 1.8e-3 .. 8.3e-1, invariant under a 100x tighter convergence threshold), and QE ph.x raw output shows the same behavior (0.09% .. 34%); the reference workflow post-processes with dynmat asr='crystal', so this option aligns the treatment. - simple: the legacy fix, each row's total is subtracted from its diagonal element, with a Hermitian re-symmetrization pass - crystal: the optimized minimal-norm fix -- the symmetric projection D -> (1-P) D (1-P) with the orthonormal translations u_i(3a+alpha) = delta(alpha,i)/sqrt(nat); zeroes every row AND column sum exactly, preserves Hermiticity and keeps symmetry-equivalent atoms equivalent; the three acoustic eigenvalues vanish to machine precision - an explicit report line prints the worst rowsum before -> after (and the |sum Z*| correction); run_assemble audits raw / asr / loto stages separately Tests (MODULE_DFPT_phon_serial 12 -> 16): simple and crystal zero the row sums; crystal keeps Hermiticity, maps the acoustic triplet to zero (sqrt-scaled residual ~1e-5 cm^-1 from a ~1e-17 matrix residual), keeps equivalent atoms equivalent, and shifts each Born charge by the per-component mean.
The first crystal/simple implementation enforced UNWEIGHTED row sums on
the stored mass-REDUCED matrix (D = Phi/sqrt(m_a m_b)), which projects
out the wrong direction (uniform mass-coordinate displacement instead
of uniform physical displacement). Consequence caught by the first
ten-system validation run: the pre-LO-TO acoustic modes zero out along
the spurious direction, but the LO-TO nonanalytic term -- which decouples
from the PHYSICAL acoustic subspace only through sum_a Z*_a = 0 -- mixes
back in and lifts one acoustic mode (bn_cubic Gamma: +36 cm^-1 along
(1,1,1) while QE stays at ~1e-5).
QE dynmat operates on the UNreduced matrix (dyndiag divides by the
sqrt(m_a m_b) only at diagonalization), so its unweighted rows are the
physical rule; the correct translation into our reduced storage carries
the sqrt(m) weights:
- crystal: project with the orthonormal physical translations
w_i(3a+alpha) = sqrt(m_a) delta(alpha,i)/sqrt(sum m), i.e.
D' = D - (sqrt(m_a)/M) S - (sqrt(m_b)/M) T + (sqrt(m_a m_b)/M^2) U
with S/T/U the sqrt(m)-weighted single and double atom sums
- simple: D(a,a) = -sum_{b!=a} sqrt(m_b/m_a) D(a,b)
- the audit and the report line now print the PHYSICAL row sums
sum_jb sqrt(m_jb) D(3a+da, jb), the quantity QE's rows sum to
Tests (phon serial 16 -> 17): row-sum assertions move to the physical
sums; the equivalent-atoms case runs with mass-equal species; new
regression AsrCrystalPlusLotoKeepsAcousticExactlyZero (masses 12/4,
violating matrix, eps 3I and unbalanced Z*): after crystal + LO-TO the
acoustic triplet stays at zero to 1e-4 cm^-1.
…tru fixture The CI MODULE_DFPT_pw_run_test (GCC 11 container) segfaulted inside the first run() of the ASR branch while the same binary passed everywhere locally (GCC 13): DFPTStruTestFixture::construct_ucell never populated ucell.iat2it, so the audit's cosmetic species-label lookup atoms[iat2it[ia]].label read an EMPTY vector -- undefined behavior that GCC 13 layouts happened to survive and GCC 11 did not. - audit_asr: print the atom index only; production code no longer touches iat2it (apply_asr's mass lookup still does, legitimately) - the stru fixture now fills iat2it/iat2ia like any real cell
ABACUS-PR-BOT
left a comment
There was a problem hiding this comment.
Static review of f7c9bd39e2cd0166fd55a7664321fc0f6154d775 with independent verification: two correctness issues and two nonblocking suggestions inline. git diff --check passed; the trusted governance checker reported documentation warnings only. No build or runtime tests were run; CI diagnostics were unavailable.
Non-blocking: Please add the exact commands, configuration, and observed results behind the test claims (or explicitly mark them not run), plus a short note that the INPUT pages are generated from the updated C++ metadata by the existing documentation pipeline.
[P2: directional cancellation in the audit metric] The audit and the apply_asr report summed over ALL columns (atoms AND Cartesian directions) before taking the norm, so opposite x/y residuals could cancel: the block [[1,-1,0],[-1,1,0],[0,0,0]] reported zero although D*t_x != 0. Both the audit and the report now compute per-direction residuals R(a,alpha,beta) = sum_b sqrt(m_b) D(3a+alpha, 3b+beta) at a FIXED translation direction beta, then combine the norms. New regression: the cancellation pattern must be detected. [P2: Hermitian re-symmetrization breaks the simple correction] The simple mode dumped the residual onto the onsite 3x3 blocks, which can write complex values on the DIAGONAL (the j>i symmetrization loop leaves the diagonal untouched), producing a non-Hermitian input to the crystal projection -- whose result is then non-Hermitian, and the shared re-symmetrization halves the correction back (the review's +/-delta/2 example). Fix: (1) take the real part of the diagonal after the onsite dump, making the input genuinely Hermitian before the projection; (2) finish with the crystal projection, which now gives an exact Hermitian matrix satisfying all three translation constraints. New regression: cross-Cartesian coupling (atom0-x <-> atom1-y) with unequal masses, checking translations exact + Hermiticity + real diagonal. Also addresses the two non-blocking notes: - header doc: correct translation vectors to sqrt(m_a) delta/sqrt(M), describe simple as onsite-block correction + projection finish - run_assemble: single eigensolve after any applicable correction (the raw audit does not consume frequencies)
|
Both P2 findings are fixed in 64fcadf: |
… loop
When a pseudopotential with nonlinear core correction (nlcc) displaces,
its core charge density moves with the atom. The first-order density
drho must include this contribution in the XC channel (the core
Coulomb interaction is already absorbed in the ionic pseudopotential,
so no Hartree term). Previously compute_drho carried only the valence
u*du cross terms, leaving nlcc systems' response incomplete: bn_hex
Gamma soft-mode pair was 8.7x too imaginary versus QE (-259.7 vs
-29.8 cm^-1) while non-nlcc systems were unaffected.
New DFPT_Rho::compute_drhoc computes the q-shifted G-space amplitude
d rho_core / d tau_dir (G+q)
= -i * tpiba * (G+q)_dir * rho_core~(|G+q|) * exp(i (G+q) tau_iat)
where rho_core~ is the radial spherical-Bessel Fourier transform of
the core charge (evaluated per-|G+q| from the pseudopotential's
rho_atc radial data, the same integral the ground state's
non_linear_core_correction performs). Non-nlcc atoms give zero.
assemble_v_sc injects the core derivative on the XC input side only:
a_r += drhoc_r before xc_->apply; the Hartree above keeps the pure
valence density. solve_displacement computes drhoc once per
displacement (it is iteration-independent) alongside build_dv.
Verified: all existing DFPT serial suites pass (rho/pert/phon/q0/
xc_analytic 8/7/19/6/6); nlcc validation runs in flight.
Summary
Unconstrained linear-response self-consistency violates the translational
acoustic sum rule on the Gamma dynamical matrix, and the Born effective
charges violate sum_a Z*_a = 0 similarly. This PR adds the standard
post-processing remedy as a new INPUT parameter
dfpt_asr(defaultno),applied to the RAW Gamma matrix before the LO-TO nonanalytic term, together
with the Z* sum rule, so the LO-TO term consumes the corrected charges (the
QE dynmat
set_asrorder). Two modes:D(a,a) = -sum_{b!=a} sqrt(m_b/m_a) D(a,b).D -> (1-P) D (1-P)with the orthonormal translation vectorsw_i(3a+alpha) = sqrt(m_a) delta(alpha,i)/sqrt(sum m); zeroes everyphysical row AND column sum exactly, preserves Hermiticity and keeps
symmetry-equivalent atoms equivalent.
Diagnostics: per-stage audit lines (
raw/asr/loto) print per-atomPHYSICAL row sums (sum_jb sqrt(m_jb) D) with the worst relative to the
matrix scale, plus an explicit correction report (
worst physical rowsum before -> after | max |sum_a Z*_a| -> 0).Tests (
MODULE_DFPT_phon_serial12 -> 17): simple and crystal zero thephysical row sums; crystal keeps Hermiticity, maps the acoustic triplet to
machine zero, and keeps symmetry-equivalent atoms equivalent (mass-equal
species); Born charges shift by the per-component mean; regression: unequal
masses + violating matrix + eps and unbalanced Z* -> after crystal + LO-TO
the acoustic triplet stays at zero.