Fix(module_xc): compute real density laplacian for meta-GGA functionals#7286
Draft
dyzheng wants to merge 6 commits intodeepmodeling:LTSfrom
Draft
Fix(module_xc): compute real density laplacian for meta-GGA functionals#7286dyzheng wants to merge 6 commits intodeepmodeling:LTSfrom
dyzheng wants to merge 6 commits intodeepmodeling:LTSfrom
Conversation
32e29f4 to
0d7fbe2
Compare
…eta-GGA functionals
SCANL, R2SCANL, and REVSCAN require the density laplacian (∇²ρ) but
v_xc_meta was passing |∇ρ|² instead. This caused ~150 kbar stress error
for Na with SCANL vs SCAN. Additionally, the vlapl stress contribution
was completely missing.
Laplacian computation method:
∇²ρ(r) = -∑_G |G|² ρ(G) e^{iGr}
- ρ(r) is Fourier-transformed to ρ(G) via real2recip()
- Each G-component is multiplied by -|G|² (i.e. -gg[ig] * tpiba²)
- Inverse FFT via recip2real() yields ∇²ρ(r) on the real-space grid
- Only the real part is retained (imaginary part should be ~0 for real ρ)
This is exact within the plane-wave basis, not numerical differentiation.
Spin handling:
- cal_lapl(nspin, nrxx, rho, tpiba2, chr) computes ∇²ρ for each spin
channel: rho is interleaved [rho_up[0], rho_dw[0], rho_up[1], ...]
and output lapl is [lapl_up[0], lapl_dw[0], lapl_up[1], ...]
- nspin=1: single channel (spin-unpolarized), loop runs once for is=0
- nspin=2: separate laplacian for spin-up and spin-down channels,
each computed independently from its own real-space density
- nspin=4 (noncollinear): blocked by set_xc_type for meta-GGA
Hessian computation for vlapl stress:
- cal_rho_hessian(nspin, nrxx, rho, chr) computes ∂²ρ/∂r_α∂r_β
via reciprocal space: FFT[ -G_α G_β ρ(G) ]
- Returns 6 independent components per spin (xx, yy, zz, xy, yz, zx)
- Stress contribution: σ_αβ^vlapl = -2 ∫ vlapl(r) ∂²ρ/∂r_α∂r_β dr
- Applied in gradcorr is_stress path for both nspin=1 and nspin=2
Changes:
- Add cal_lapl() and cal_rho_hessian() as reusable functions
- Fix v_xc_meta to call cal_lapl() and pass real laplacian to LibXC;
handle vlapl output by computing ∇²(vlapl) via same G-space method
- Fix tau_xc/tau_xc_spin wrappers to return vlapl derivative
- Fix gradcorr stress/force paths: replace duplicated inline Laplacian
code with cal_lapl() calls; add Hessian computation and vlapl stress
contribution for meta-GGA functionals
- Update test_xc4.cpp and test CMakeLists for new tau_xc signature
0d7fbe2 to
812061e
Compare
|
should this be removed |
…arning For meta-GGA functionals that depend on the Laplacian of the density (e.g., SCANL), the vlapl contribution to V_xc (e2*∇²(vlapl)) is omitted because it causes |G|² amplification in reciprocal space leading to SCF divergence. vtxc also omits vlapl for consistency with V. The vlapl energy is still included in etxc via exc, and the vlapl stress term (2*vlapl*Hess*e2) is computed in gradcorr. A runtime warning is printed when a Laplacian-dependent functional is detected, recommending r2SCAN or SCAN instead. See docs/scanl_laplacian_implementation_report.md for the full analysis including FD stress validation results.
Add ecutwfc 60/80/100 Ry PW and LCAO FD test results for scheme 3. All schemes that omit vlapl from V show 5-10% stress error due to etxc-vtxc mismatch. Update summary table accordingly.
…ential Replace spectral Laplacian (|G|² amplification → SCF divergence) with finite-difference Laplacian kernel in G-space. The FD kernel matches the spectral kernel at low G but is bounded at high G, enabling SCF convergence while preserving density-potential consistency. Key changes: - xc_functional_libxc_vxc.cpp: compute ∇²(vlapl·sgn) using FD kernel in G-space with metric tensor GGT for non-orthogonal cells - xc_functional.cpp: register SCANL functional name (XC_MGGA_X_SCANL + XC_MGGA_C_SCANL) - Update vtxc to include vlapl contribution for stress consistency FD stress validation (Si2 FCC, Γ-point): SCAN: FD/AB = 1.0000 (all ecutwfc) SCANL: FD/AB = 0.995 (ecutwfc=80, -0.51% error) vs scheme 3 (no vlapl in V): FD/AB = 0.906 (-9.5% error)
…st data Add complete derivation of FD Laplacian kernel in G-space for general (non-orthogonal) cells, including metric tensor cross terms. Document numerical verification of gg_FD vs gg_spectral at multiple FFT grid sizes, full FD stress validation results with energy data, and error analysis.
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.
SCANL, R2SCANL, and REVSCAN require the density laplacian (∇²ρ) but v_xc_meta was passing |∇ρ|² instead. This caused ~150 kbar stress error for Na with SCANL vs SCAN.
Reminder
Linked Issue
Fix #...
Unit Tests and/or Case Tests for my changes
What's changed?
Any changes of core modules? (ignore if not applicable)