Fix per-atom error in the Laplacian meta-GGA nuclear gradient - #228
Open
susilehtola wants to merge 1 commit into
Open
susilehtola wants to merge 1 commit into
susilehtola wants to merge 1 commit into
Conversation
lapl(rho) = 2 X . lapl(B) + 2 sum_c X_c . d_c B, with X = fac P B and
X_c = fac P d_c B. One term of its nuclear derivative contracts the BARE
d_x B against 2 P lapl(B); the code contracted (2 P d_x B) against the
bare lapl(B) instead.
The two are equal only after summing over every basis function, so the
total gradient was right and translational invariance held -- but the sum
in exc_grad_local_work_ is restricted to the shells on one atom, so the
force on each individual atom was wrong. Measured against a central
difference of eval_exc over a displaced molecule and displaced basis
(benzene/cc-pVDZ/UltraFine, atom 0, worst of the three components):
before after
MGGA_X_BR89 1.595e-01 1.604e-09
MGGA_X_R2SCANL 1.383e-01 9.365e-08
MGGA_X_SCANL 1.608e-01 --
Three independent Laplacian functionals fail identically beforehand,
including BR89, which has none of SCAN's numerical difficulty; the sign
of the error also differs between them, which no fixed numerical defect
would do. LDA (5.1e-09), GGA (2.1e-09) and tau-only meta-GGA (4.3e-09)
are unaffected and unchanged, as are energies and potentials at every
rung.
The matrix contracted with the Laplacian is not otherwise formed, so it
is built with one extra eval_xmat and one extra block of host_data.zmat,
allocated only when needs_laplacian.
RKS only: exc_grad already refuses needs_laplacian with is_uks.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Fixes #227.
The defect
lapl(rho) = 2 X . lapl(B) + 2 sum_c X_c . d_c B, withX = fac P BandX_c = fac P d_c B(host driver,eval_uvvar_mgga_rks). Differentiating withrespect to a nuclear coordinate gives, per basis function on the moving atom,
(1) and (3) were correct. (2) was not — the code had
(2 P d_x B) . lapl(B),i.e. the two indices swapped:
The two forms coincide only after summing over every basis function (relabel
mu <-> nu, P symmetric). The sum in
exc_grad_local_work_is restricted to theshells on one atom, so the total gradient came out right — and translational
invariance held, being imposed explicitly by the parent-atom subtraction — while
the force on each individual atom was wrong by ~15%. A geometry optimisation
drifts; every invariance check passes.
The change
2 P lapl(B)is not otherwise formed, so it is built with one extraeval_xmatand one extra block ofhost_data.zmat, allocated only whenneeds_laplacian:+24 / -4, one file, RKS only (
exc_gradalready refusesneeds_laplacianwithis_uks).Verification
eval_exc_gradagainst a central difference ofeval_excover a displacedmolecule and displaced basis — the grid and its partition weights ride on
the atoms, so this is a total derivative that shares no algebra with the
gradient code. Benzene / cc-pVDZ / UltraFine, atom 0, h = 1e-4, worst relative
deviation over the three Cartesian components:
Three independent Laplacian functionals fail identically beforehand, including
BR89, which is plain Becke-Roussel exchange with none of SCAN's numerical
difficulty. The sign of the error differs between BR89 and r2SCANL/SCANL,
which no fixed numerical defect would do. The analytic value moves onto the
finite difference that was already there:
Energies and potentials were never affected and still are not:
VXCagainst acentral difference of
Excin the density matrix gives the ratio 2 (the RKSconvention) to 8 digits at every rung, Laplacian included.
ctest/gauxc_test: all 3640979 assertions in 56 test cases pass,unchanged. No test covers this path —
tests/ref_dataholds two Laplacianmeta-GGA reference files and neither contains a gradient, which is how the error
survived.
Not covered here
Laplacian functionals outright
(
"Device EXC Gradients + Laplacian Dependent MGGAs Not Yet Implemented"),so there is no device Laplacian gradient to correct.
GAUXC_GENERIC_EXCEPTION).Happy to follow up with that as a separate PR.
🤖 Generated with Claude Code