Repository navigation
feat(dfpt): acoustic sum rule enforcement (dfpt_asr = no | simple | crystal) - #8182
Open
Zanthoxylum wants to merge 4 commits into
Open
Zanthoxylum wants to merge 4 commits into
Zanthoxylum wants to merge 4 commits into
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
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.