Skip to content

feat(xc): add libvdwxc-backed rVV10 nonlocal XC - #8140

Draft
CleverPhysician wants to merge 32 commits into
deepmodeling:developfrom
CleverPhysician:rvv10-latest-clean
Draft

CleverPhysician wants to merge 32 commits into
deepmodeling:developfrom
CleverPhysician:rvv10-latest-clean

Conversation

@CleverPhysician

@CleverPhysician CleverPhysician commented Oct 13, 2026 •

Copy link
Copy Markdown

What's changed?

This adds rVV10 nonlocal correlation through libvdwxc MR !32, selected with vdw_method rvv10. The semilocal functional remains set by dft_functional.

  • vdw_rvv10_b defaults to 6.3 and must be positive; vdw_rvv10_c defaults to 0.0093 and must be nonnegative. Both parameters require vdw_method rvv10. Set b explicitly to 15.7 for SCAN or 11.95 for r2SCAN; it is not changed automatically when selecting a functional.
  • The correction is added in v_xc_libxc, v_xc_meta, and the native and NCGGA paths of v_xc. It uses the existing charge, gradient, potential and XC-energy bookkeeping. evdw remains zero because this is a density-functional contribution, not a pairwise dispersion term.
  • With more than one process per pool, the adapter uses vdwxc_init_mpi. Parallel_Common::alltoallv_data redistributes density, sigma and derivatives between ABACUS planes and libvdwxc slabs without gathering the full grid on one process. The libvdwxc object, FFT plans and buffers are reused; a grid or pool change rebuilds the workspace. Cell and b/C values are updated on each call. Left-handed cells are inverted for libvdwxc's signed-volume convention.
  • add_rvv10_stress combines vdwxc_stress with the ABACUS gradient contribution in stress_gga. Density-dependent terms use the existing XC and NLCC paths. Stress and cell relaxation are enabled; DFPT, LR-TDDFT forces and LR relaxations are rejected during INPUT validation.
  • ENABLE_LIBVDWXC defaults to OFF and requires ENABLE_LIBXC. CMake uses the exported libvdwxc::vdwxc target. MPI builds require an MPI-enabled libvdwxc and standalone FFTW; CMake rejects the MKL/KML FFTW interfaces. Build information follows DFT-D4. The legacy Makefile does not build this feature.

Installation, SCF usage and citations are updated in docs/advanced/install.md, docs/advanced/scf/advanced.md and docs/CITATIONS.md. INPUT metadata includes the new parameters and help text; generated INPUT documentation is not committed. Like the other vdw_method values, rvv10 must be lowercase. A build without the backend gives a rebuild hint.

Linked Issue

This continues the rVV10 work discussed in #8031; no separate issue was opened.

Unit Tests and/or Case Tests for my changes

The cluster runs cover the runtime changes through 7e9425c86, including an incremental rebuild and focused tests after that commit. b378fb261 changes CMake checks, documentation, a hint and comments. It passed local syntax, formatting and governance checks but has not been rebuilt on the cluster.

Builds used GCC 11.5, OpenMPI 4.1, Libxc 6.2.2, FFTW 3.3.10 with MPI and libvdwxc da2d55f with MPI enabled. Runtime tests used one OpenMP thread.

Commands run:

# PW: ENABLE_MPI=ON, ENABLE_LIBXC=ON, BUILD_TESTING=ON;
# run separately with ENABLE_LIBVDWXC=ON and OFF
ctest -R 'XCTest|nonlocal_xc|vdwTest|vdwd4|read_input_serial|parallel_device'

# LCAO build
ctest -R 'MODULE_LR_lr_util|MODULE_LR_pot_hxc|MODULE_HAMILT_surchem'

abacus --version
abacus -h vdw_method
abacus -h vdw_rvv10_b
abacus -h vdw_rvv10_c
abacus --check-input

The CLI checks passed for valid inputs and rejected the unsupported settings. CTest passed 18/18 with libvdwxc and 13/13 without it. This includes the adapter tests at 1, 2 and 4 ranks and the communication tests at 1 and 4 ranks. The LCAO selection passed 8/9: MODULE_LR_pot_hxc_lrtd failed because the loaded Libxc does not provide KXC for Slater exchange.

Case runs used abacus_pw_para and abacus_basic_para on two-atom Si, plus H2O ks-lr from tests/08_RI/lr_tddft_pbe_gamma with cal_force 0, tests/06_SDFT/03_PW_SDFT_5D10S and the WT-OFDFT case tests/07_OFDFT/22_OF_LibxcPBE.

  • For tightly converged rPW86+PBE+rVV10 Si, PW energies agree within 2e-11 eV across 1–4 ranks, including different ABACUS/libvdwxc plane distributions. A separate nonmagnetic Si comparison of nspin=1,2,4 at two ranks agrees within 5e-11 eV. The toy-cell energy agrees with earlier versions within 1e-12 eV.
  • For the tested Si force component, finite-difference errors are 2.6e-4 eV/angstrom without NLCC and 1.2e-4 eV/angstrom with NLCC in PW; the semilocal NLCC control gives 1.4e-4 eV/angstrom. In LCAO the corresponding errors are 5e-5, 1.1e-3 and 1.4e-3 eV/angstrom.
  • For the tested low-symmetry cell, the rVV10-minus-semilocal stress contribution agrees with finite strains within 0.02 kbar in PW and 0.05 kbar in LCAO. PW checks include rPW86+PBE and SCAN with b = 15.7, with and without a smooth NLCC core. Hard-NLCC residuals remain: Si.pz-n-nc.UPF gives up to 1.1 kbar at ecutrho 120 Ry and 0.4 kbar at 480 Ry. Its semilocal off-diagonal control differs by up to 0.35 kbar. Absolute PW NLCC diagonal stresses also have large residuals in the semilocal controls; total-stress accuracy and the cause of those discrepancies remain unresolved.
  • PW and LCAO cell relaxations run. The selected SDFT and WT-OFDFT cases run with forces and stress, and the H2O ks-lr spectrum runs. These are smoke tests, not independent force/stress checks for those solvers.

Earlier fixed-density QE comparisons found energy differences up to 3.5e-13 Ry on seven synthetic densities and 6e-15 Ry on graphene, with an own-energy directional residual up to 1.3e-10 Ry. Pointwise potentials differed in low-q and small-gradient cases. Those results belong to the earlier implementation; this revision has not had a new independent QE comparison.

OpenMP, GPU, ELPA-based LCAO solvers, USPP, rt-TDDFT and DeePKS have not been tested with rVV10. Hosted CI leaves libvdwxc disabled, so it does not test the backend-enabled path.

Core-module impact

ESolver_FP::before_all_runners copies three values into XCFunctionalParameters; it adds no solver step. The XC evaluators and stress_gga call the new functions only with __LIBVDWXC. Existing evaluator callers receive the correction, including NLCC, PotXC_FDM, RDMFT and matrix writers; the tests above do not cover every caller. ScopedType restores the added XC parameters.

The workspace is kept for the process lifetime to avoid destruction after MPI_Finalize or fftw_cleanup_threads; its buffers remain allocated after SCF. source_base gains the alltoallv_data wrapper and tests. Local governance checks found no issues; quality scores for nonlocal_xc.cpp, nonlocal_xc.h and test_nonlocal_xc.cpp were 89, 98 and 86.

Governance Exception

  • Rule: new compile definition and #define (AGENTS rule 20).
  • Reason: the optional backend uses __LIBVDWXC and ABACUS_LIBVDWXC_VERSION, following DFT-D4 (CMake: Move __DFTD4 to global feature definitions #7793).
  • Scope: the global feature-definition list and build_info.h.in.
  • Risk: feature code is excluded when ENABLE_LIBVDWXC=OFF, the default.
  • Why an exception is needed: existing optional-library integration uses a feature definition.
  • Follow-up cleanup: none planned beyond the existing feature mechanism.
  • Requested approver: a maintainer.

Open points

  • This depends on unreleased libvdwxc MR !32, tested at da2d55f; the PR remains Draft pending the library release.
  • libvdwxc does not expose its local slab layout. The adapter assumes the default FFTW-MPI block layout used by da2d55f (ceil(nz/P) z planes). A backend/layout change would require updating this mapping.
  • nonlocal_xc.cpp is in module_vdw and compiled into xc_; libvdwxc::vdwxc is linked to xc_. I can move the source to module_xc if that placement is preferred.

@CleverPhysician

Copy link
Copy Markdown
Author

Update after the hosted checks completed:

  • The standard upstream workflow is green: 18/18 checks passed on head f3d41ad55ed53abb18ec8953d64df805d926dedd.
  • The serial intern004 validation remains green: the libvdwxc adapter test passed 1/1 and the minimal CPU/PW/nspin=1 Si SCF converged with the recorded energy and density checks.
  • This revision addresses the main concerns from feat: add restricted rVV10 plane-wave support #8031: semilocal and nonlocal XC are separate inputs, the host side uses a generic additive component, and rVV10-specific numerical work is kept behind the thin libvdwxc adapter rather than duplicated in the generic XC evaluator.
  • Following the pattern of merged Add optional DFT-D4 support #7380, the PR now includes explicit dependency/build commands, user-facing INPUT documentation, citations, unit coverage, and an honest statement of checks not run.

The PR remains Draft while the maintainer confirms the staged CPU/serial/nspin=1 scope and while the QE same-density reference comparison (including gradient/divergence sign and normalization) is completed. libvdwxc MR !32 is still a Draft dependency, so I am not presenting it as a stable release.

@Growl1234

Copy link
Copy Markdown
Collaborator

The pinned libvdwxc Draft branch's own rvv10.serial test is not fully green: 7/8 CTest groups passed and 69 finite-difference/strain checks fail at roughly 1e-6--1e-5. This is reported as a dependency-side Draft issue, not hidden.

Could you provide the detailed information?

Another side note: libvdwxc currently requires FFTW-MPI wrapper when MPI is enabled, so be careful with MKL; for now you can consider adding a USE_FFTW3_WITH_MKL that use MKL Blas/lapack/scalapack but standalone FFTW library, but I'm in progress of refactoring its FFT backend and dropping the direct FFTW-MPI dependency, so hopefully in the future everything will be better.

@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 review of 32e12de74c07d2307a90c695dac6f8e452f592e5, independently cross-checked against the pinned libvdwxc implementation. Two geometry issues and one nonblocking timer-label cleanup are noted inline. No builds or runtime tests were run.

@CleverPhysician

Copy link
Copy Markdown
Author

Follow-up on head 32e12de:

  • The parser now rejects para.sys.double_grid explicitly, so unsupported double-density-grid inputs fail during input validation with a clear single-density-grid diagnostic.
  • The host component now enforces the declared first-PR nspin=1 scope instead of retaining an untested nspin=2 path.
  • The updated Python contract test is 7/7. On intern004, the real libvdwxc adapter CTest is 1/1, the abacus_pw_ser target relinks successfully, the two-atom Si CPU/PW/nspin=1 SCF converges with E_xc=-4.2517234318 Ry, E_total=-208.0135469216 eV, and the double-grid and nspin=2 negative-input checks both fail at the intended parser diagnostic.

The PR remains Draft while the new head's hosted checks are queued and the QE same-density reference is discussed.

@CleverPhysician

Copy link
Copy Markdown
Author

Addressed the ABACUS-PR-BOT static review on head e65e07c:

  • The libvdwxc cell adapter now passes ABACUS lattice rows as the C API's C00,C10,C20 vector groups. The oblique-cell test constructs the direct reference with the same documented row convention, so a transpose mismatch is now detected.
  • The adapter rejects non-positive latvec.Det() before constructing the backend. A left-handed-cell regression test covers this case.
  • The PotNonlocalXC timer labels now use cal_v_eff consistently.

The intern004 adapter CTest is 1/1 after these changes, and the Si CPU/PW/nspin=1 SCF remains numerically unchanged. The PR stays Draft pending the hosted checks for the new head and maintainer review.

Comment thread CMakeLists.txt Outdated
Comment on lines +633 to +637
if(NOT TARGET libvdwxc::vdwxc)
message(FATAL_ERROR
"ENABLE_LIBVDWXC requires the libvdwxc::vdwxc CMake target. "
"Use the libvdwxc development build that includes the rVV10 API.")
endif()

@Growl1234 Growl1234 Oct 14, 2026 •

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.

That shouldn't be needed as libvdwxc's CMake config will definitely have libvdwxc::vdwxc target. Previously I did this in abacus for RapidJSON due to its embarrassing release status, but with it replaced by nlohmann-json there's no longer the case. If abacus can deal with items like dftd4 and pexsi well then the same for libvdwxc (its cmake is cleaner). If you really encountered issues please report them.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. c23f000 removes the if(NOT TARGET libvdwxc::vdwxc) check; ABACUS now relies on find_package(libvdwxc CONFIG REQUIRED) and links the exported libvdwxc::vdwxc target through _abacus_feature_libs, alongside Libxc::xc.

Comment thread CMakeLists.txt Outdated
Comment on lines +638 to +670
get_target_property(LIBVDWXC_INCLUDE_DIRS libvdwxc::vdwxc INTERFACE_INCLUDE_DIRECTORIES)
if(NOT LIBVDWXC_INCLUDE_DIRS)
message(FATAL_ERROR "libvdwxc::vdwxc does not expose its include directory")
endif()
# Installed packages expose a concrete include path, while build-tree
# targets may expose generator expressions. Strip those expressions before
# probing so configuration gives a useful error instead of a later include
# failure.
set(_libvdwxc_include_hints)
foreach(_include_dir IN LISTS LIBVDWXC_INCLUDE_DIRS)
string(GENEX_STRIP "${_include_dir}" _include_dir_stripped)
if(IS_DIRECTORY "${_include_dir_stripped}")
list(APPEND _libvdwxc_include_hints "${_include_dir_stripped}")
endif()
endforeach()
unset(LIBVDWXC_HEADER_DIR CACHE)
find_path(LIBVDWXC_HEADER_DIR NAMES vdwxc.h HINTS ${_libvdwxc_include_hints}
NO_DEFAULT_PATH)
if(NOT LIBVDWXC_HEADER_DIR)
message(FATAL_ERROR "libvdwxc::vdwxc does not provide vdwxc.h")
endif()
file(READ "${LIBVDWXC_HEADER_DIR}/vdwxc.h" LIBVDWXC_HEADER_TEXT)
if(NOT LIBVDWXC_HEADER_TEXT MATCHES "VDWXC_RVV10"
OR NOT LIBVDWXC_HEADER_TEXT MATCHES "vdwxc_new"
OR NOT LIBVDWXC_HEADER_TEXT MATCHES "vdwxc_set_rvv10_parameters"
OR NOT LIBVDWXC_HEADER_TEXT MATCHES "vdwxc_set_unit_cell"
OR NOT LIBVDWXC_HEADER_TEXT MATCHES "vdwxc_init_serial"
OR NOT LIBVDWXC_HEADER_TEXT MATCHES "vdwxc_calculate"
OR NOT LIBVDWXC_HEADER_TEXT MATCHES "vdwxc_finalize")
message(FATAL_ERROR
"The selected libvdwxc headers do not provide the complete serial rVV10 API; "
"use the pinned development build containing MR !32.")
endif()

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.

Looks like you add a lot of lines simply for detecting rVV10 API? For the time it might be okay, but we should drop it at some time in the future.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dropped in c23f000: CMake no longer probes include directories, calls find_path(vdwxc.h), reads the header or matches rVV10 symbols with regexes. docs/advanced/install.md points to the libvdwxc MR !32 rVV10 branch instead.

Comment thread docs/developers_guide/nonlocal_xc.md Outdated

## Follow-up work

The next PRs can add a libvdwxc MPI/PFFT adapter, ordinary spin, GPU/LCAO

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.

Just a side note: PFFT dependency might be dropped in the future. Actually I'm proposing a minimal dependency policy upstream, but anyways PFFT will be the first lucky one.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted, thanks. This page was removed in c23f000; the adapter calls vdwxc_init_serial, and ABACUS does not directly discover or link PFFT.

@CleverPhysician

Copy link
Copy Markdown
Author

Thanks for asking. I reran the unchanged libvdwxc revision 91ef4820f3270e22b35fddc2ab4cab8efa4b6d79 in two fresh build directories. My earlier wording was too broad: these were 69 failed comparisons within one CTest, rather than 69 failed tests or evidence that all libvdwxc algorithms fail.

Both builds used GCC 11.2.1, Release (-O3 -DNDEBUG; the tests also use -UNDEBUG), shared libraries, and MPI disabled. The MKL imported target additionally supplies -m64:

-DCMAKE_BUILD_TYPE=Release
-DCMAKE_C_COMPILER=/opt/rh/devtoolset-11/root/usr/bin/cc
-DBUILD_SHARED_LIBS=ON -DBUILD_TESTING=ON -DVDWXC_ENABLE_MPI=OFF

With -DVDWXC_FFT_PROVIDER=MKL -DMKL_INTERFACE=lp64 -DMKL_THREADING=sequential -DMKL_LINK=dynamic and MKL 2022.2.1, 7/8 CTests pass. rvv10.serial reports:

  • 50 density-derivative finite-difference mismatches: maximum absolute discrepancy 2.34733549e-6; tolerance 3e-8 × (1 + |expected|).
  • 16 sigma-derivative mismatches: maximum absolute discrepancy 5.68711029e-6; tolerance 3e-7 × (1 + |expected|).
  • 3 full-strain derivative mismatches: maximum absolute discrepancy 9.01266900e-6; tolerance 3e-7 × (1 + |expected|).

The original MKL executable reproduces exactly the same values under a clean environment with no LD_LIBRARY_PATH:

env -i PATH=/usr/bin:/bin LANG=C LC_ALL=C OMP_NUM_THREADS=1 MKL_NUM_THREADS=1 \
  /tmp/libvdwxc-mr32-audit/build-audit/libvdwxc_rvv10_test

Selecting -DVDWXC_FFT_PROVIDER=FFTW3 with standalone FFTW 3.3.11 and the same common settings gives 8/8 CTests passing, and the same rvv10.serial test reports 0 failures, also under env -i.

Both configurations pass the separate CP2K-table reference comparisons in that test: energy, density/sigma derivatives, and explicit stress on a 3 × 3 × 5 oblique grid, for both default and custom parameters. Those fixtures were generated independently using CP2K's kernel table, NumPy FFT, and SciPy splines; this is a table-level reference, not a CP2K SCF or QE comparison.

The current evidence therefore isolates the discrepancy to this MKL backend configuration. The underlying cause has not been established.

Updated head c23f000 now builds ABACUS with OpenBLAS and the same standalone FFTW as libvdwxc, avoiding mixed fftw_* implementations. The full serial PW executable builds, the adapter/Makefile CTests pass 2/2 (six C++ numerical/error cases), and the Si SCF converges with E_total=-208.0135469216242 eV. I corrected the PR description accordingly. MPI is not yet implemented, so I have not tested the FFTW-MPI wrapper or added a new MKL/FFTW mixing option.

This update also removes the manual CMake target/header/API checks and uses libvdwxc::vdwxc directly as suggested. The redundant developer page has been removed, and the adapter does not encode a PFFT dependency. It uses ABACUS's standard error diagnostics and adds an independent oblique/orthogonal-cell geometry test: deliberately restoring the wrong transpose makes that test fail. The PR stays Draft pending the scope decision and independent QE comparison.

@Growl1234

Copy link
Copy Markdown
Collaborator

Ah OK, I can now reproduce the failure with oneMKL 2026.1.0. I will have a look into it.

@Growl1234

Copy link
Copy Markdown
Collaborator

Ah OK, I can now reproduce the failure with oneMKL 2026.1.0. I will have a look into it.

@CleverPhysician This should be fixed on libvdwxc side, please check

@CleverPhysician

Copy link
Copy Markdown
Author

Follow-up on c3dedfb:

  • The adapter now forbids copying its owned libvdwxc handle. A type-contract
    regression failed on the original implicit copy constructor/assignment and
    passes with the two deleted operations.
  • Added one focused host test using real Charge, UnitCell, and the backend.
    It checks valence-plus-core density construction, additive energy/vtxc/potential,
    preservation of existing XC values and unchanged density arrays. The separately
    tested adapter supplies the correction reference; this is host bookkeeping
    coverage, not an independent physical reference.
  • Mutation checks confirm it catches missing core density (3.33e-5 Ry energy
    discrepancy) and replacing += by =. Production source was restored and
    checksum-matched before final verification.
  • The full serial PW executable builds and all three libvdwxc-related CTests
    pass (seven adapter cases, one host case, one build-report test). The Si SCF
    and unsupported-input checks were rerun. Scope is unchanged.

The earlier 18 successful hosted checks apply to c23f000, not this new head;
new CI still needs to finish. The PR remains Draft pending scope approval and
independent QE validation. I found preserved raw QE density/output fixtures for
that next comparison, but have not counted the old native-backend results as
validation of this adapter.

@CleverPhysician

Copy link
Copy Markdown
Author

Thanks, checked the fix at 94410ebdf3dc9615a40f40c3a5b59dbe20a433d2.
With GCC 11.2.1, both standalone FFTW 3.3.11 and MKL 2022.2.1
(lp64/sequential/dynamic) now pass all 8 library CTests, including
fft.weights and rvv10.serial. The seven ABACUS adapter tests and the real
host bookkeeping test also pass with the new standalone-FFTW library.
These runs were on a scheduled compute node (Slurm 555743), with the two
FFT providers kept separate. I updated the documented pin; no ABACUS
implementation change was needed for this fix.

The new adapter has now also been compared against the immutable original-QE
directional fixtures: seven cases, 960 points each, nine steps each.
Maximum energy difference is 3.50e-13 Ry, and its own-energy directional
residual is at most 1.25e-10 Ry at h=1e-4 (L1-direction normalized).
I have not called the pointwise potential comparison a pass: low-q and
small-sigma conventions differ, and the kernel convolution G sets are not
identical even when the host PW gradient cutoff is the same. Those differences
are recorded separately in the PR description; material/vacuum reference
validation and staged-scope agreement are still pending. Keeping this Draft.

1 and others added 3 commits October 17, 2026 20:22
Replace the single combined scope check with per-setting diagnostics
that name the parameter to change, drop the rvv10_b/rvv10_c checks
already covered by the xc_nonlocal check, give the gamma_only reset its
own message, and note the nscf restriction in the parameter
description. The reader tests now create mkstemp scratch files under
testing::TempDir() so concurrent runs do not share INPUT/KPT names.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Forward-declare the opaque vdwxc_data_obj handle so only the
implementation and the API-parity test include <vdwxc.h>. Register the
module_vdw tests from their own CMakeLists again and the serial
libvdwxc host test from source_estate, remove the redundant dftd4 link
of the pairwise vdW test, read the single nspin=1 density channel in
PotNonlocalXC, and stop duplicating the rVV10 defaults in Potential.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The build-report contract test already runs in the "Other Unittests"
step, so the workflow is now unchanged from develop. The test README
keeps only how to run the tests, install.md documents the nscf
restriction, and CITATIONS.md fixes the Sabatini initial.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@mohanchen

Copy link
Copy Markdown
Collaborator

Please answer directly to each comment.

@mohanchen mohanchen added the Feature Discussed The features will be discussed first but will not be implemented soon label Oct 23, 2026
1 and others added 6 commits October 25, 2026 22:49
Resolves the CMake list re-indentation from the Prettify series, the
SCCS component next to the nonlocal XC branch in potential_types.cpp
and HamiltPW, and the renamed relax_method reader test.
…x the rVV10 parameters

Read xc_nonlocal in Potential::get_pot_type from the Input_para it now
receives, the same way the pcc, efield and sccs components do, and drop
the second Potential constructor, the three stored members and the
has_nonlocal_xc() query that HamiltPW no longer needs since the merge
of develop switched it to input.xc_nonlocal.

The current interface pairs GGA_X_RPW86+GGA_C_PBE with the published
rVV10 parameters b=6.3 and C=0.0093, so they become named constants in
nonlocal_xc.h instead of two INPUT parameters that accepted only one
value. The reader keeps the functional and scope checks in a small
helper that names the first unsupported setting; braces on every if, no
auto, a named spin channel, and a unit-cell guard in the factory.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…test from module_vdw

The tests/rvv10 CTest only asserted a hard-coded constant in
generate_build_info.sh through a Python interpreter found at configure
time; backend coverage stays with the two GoogleTest targets. The
serial adapter test is now registered from module_vdw/CMakeLists.txt,
leaving the MPI-only test directory as in develop, and nonlocal_xc
joins the coverage targets. install.md keeps the build recipe, the
libvdwxc merge request and the INPUT lines and points to
`abacus -h xc_nonlocal` for the supported scope; CITATIONS.md cites
libvdwxc itself.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
ModuleBase::e2 for the Hartree-to-Rydberg conversion and
ModuleBase::TWO_PI in the tests, named cell and finite-difference
tolerances with their origin, braces on nested loops, explicit types
instead of auto, one allocation for the returned potential, 2-space
CMake blocks matching the Prettify series, a configure-time warning
when ENABLE_LIBVDWXC meets the MKL FFTW interface, and clang-format on
the new files and touched hunks. The unrelated Makefile newline and the
hamilt_pw.h comment are gone.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
nonlocal_xc_libvdwxc.{h,cpp} become nonlocal_vdwxc.{h,cpp} (and the test
test_nonlocal_vdwxc.cpp) to keep file names within the 15-character
preference. LibvdwxcNonlocalXC::evaluate now delegates to small helpers
(serial grid and right-handed cell predicates, finite-value check,
initialized-cell check, host gradient/sigma, Ry assembly of energy,
potential and vtxc) so each unit stays readable; the numerical path is
unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…cmake-format

The pre-commit job formats the whole tree, so its exit code reflects
upstream formatting debt (2257 C++ and 67 CMake files at develop
8e20175); this commit only brings the lines this PR adds in line with
clang-format 23.1.3 and cmake-format 0.6.13: two wrapped WARNING_QUIT
calls, the xc_nonlocal field comment, the std::transform iterator
arguments, and the two new test-registration blocks. No functional
change; tokens verified equal before and after.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@CleverPhysician

Copy link
Copy Markdown
Author

Could you provide the detailed information?

At libvdwxc 91ef4820 with MKL 2022.2.1, the 69 failures were finite-difference comparisons within one CTest, rvv10.serial; standalone FFTW 3.3.11 with the same settings passed all 8 CTests (details in my earlier comment).

for now you can consider adding a USE_FFTW3_WITH_MKL that use MKL Blas/lapack/scalapack but standalone FFTW library

Not in this PR: the documented build uses standalone FFTW with ENABLE_MPI=OFF, and CMake warns when ENABLE_LIBVDWXC is combined with MKL (815deae).

@CleverPhysician

Copy link
Copy Markdown
Author

I can now reproduce the failure with oneMKL 2026.1.0.

Thanks for reproducing it.

@CleverPhysician

Copy link
Copy Markdown
Author

This should be fixed on libvdwxc side, please check

Checked, thanks for the fix. At libvdwxc 94410eb, all 8 library CTests pass with standalone FFTW 3.3.11 and, separately, with MKL 2022.2.1. The 7 ABACUS adapter tests and the host test also pass with the standalone-FFTW build, and docs/advanced/install.md references that commit.

@CleverPhysician

Copy link
Copy Markdown
Author

Please answer directly to each comment.

Done. Each inline and conversation comment from ABACUS-PR-BOT and Growl1234 now has a direct reply. Since your comment, I merged develop (8e20175) into the branch and revised it; the current head is a682b56, and the PR description is updated to match.

Two points need your decision:

  1. Is it acceptable to limit this first PR to CPU, a single process, nspin=1 and SCF, with MPI and collinear spin as follow-ups?
  2. Is it acceptable to depend on the unreleased libvdwxc MR !32 revision for now?

@Growl1234

Growl1234 commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

Please give us a little more time. Discussions on the related series of PRs are already underway and should be wrapped up soon. Once the rVV10 PR is merged, a new release will come.

Also, to be honest, I'm not happy with the code itself and restriction here; IMHO it makes many things unnecessarily complicated. Perhaps I could ping @askhl to help take a look at this integration attempt.

…nctional::v_xc

Replace the xc_nonlocal INPUT item and the PotXC hook by the dft_functional
short name RVV10 (rPW86 exchange, PBE correlation, rVV10 with b = 6.3 and
C = 0.0093), stored next to func_id like the other short names. The nonlocal
term is added in the libxc branch of XC_Functional::v_xc, so the SCF
potential, the NLCC force and stress terms, out_mat_h_vxc, PotXC_FDM, RDMFT
and the DeePKS base functional all use the same XC potential, and no
force-specific restriction is needed.

The libvdwxc adapter becomes one stateless function: it creates the handle
per call, as the libxc wrappers do, and collects the grid on the pool root
with the Parallel_Common wrappers. It is compiled into the XC library only
when ENABLE_LIBVDWXC is on, following the DFT-D4 build pattern. Stress and
DFPT are rejected where those quantities are built.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CleverPhysician

Copy link
Copy Markdown
Author

In 256d216, I simplified the implementation by reusing existing ABACUS modules and removing redundant code paths to reduce integration risk and improve compatibility with other modules.

@Growl1234

Growl1234 commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

Well, several questions:

  • rVV10 is a dispersion correction, why introduce dft_functional rvv10 and restrict it to one particular combination? Why not simply use vdw_method nonloc and nonloc_type rvv10 (you can even use single vdw_method rvv10), keeping dft_functional independent and allowing the corresponding b and C parameters to be selected? Supporting these combinations should be fairly straightforward.
  • Why create and destroy the libvdwxc object on every call? Could the object, FFT plans and work buffers be initialized once and reused across SCF iterations?
  • What prevents using libvdwxc's distributed interface? Collecting the complete grid on the pool root concentrates both the convolution and its memory requirements on one process, which seems problematic for larger systems.
  • libvdwxc already provides vdwxc_stress. What additional work is needed on the ABACUS side to support it?

@Growl1234

Growl1234 commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

Problem (AI-generated, correct me if I'm wrong):

set_xc_type is case-insensitive, but the new input checks only recognize rvv10, RVV10 and rVV10, so spellings such as Rvv10 bypass the restrictions. Please normalize the name before validation and add a runtime guard for unsupported LR force calculations.

1 and others added 3 commits October 27, 2026 18:47
…tributed interface

rVV10 becomes vdw_method rvv10 with the parameters vdw_rvv10_b and
vdw_rvv10_c, independent of dft_functional. The parameters reach the XC layer
through XCFunctionalParameters, and the nonlocal term is added in all three
return paths of XC_Functional::v_xc and in XC_Functional_Libxc::v_xc_meta, so
it can be combined with native, libxc and meta-GGA functionals.

The libvdwxc object, its FFT plans and buffers are kept between calls and
rebuilt only when the grid or the pool changes. With several processes per
pool, vdwxc_init_mpi is used and the fields are redistributed between the
ABACUS z-plane layout and libvdwxc's FFTW-MPI slabs instead of collecting the
grid on one process. Stress
is computed with vdwxc_stress plus the gradient term on the ABACUS grid.
DFPT and LR-TDDFT forces are rejected when INPUT is read and at
run time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The DFPT runtime guard and LR_Util::check_force_vdw repeated the INPUT
requirement on vdw_method, which is checked on the effective values before
any calculation; both are removed, so no esolver or LR file changes. ESolver_FP
copies the rVV10 settings like the other XC runtime parameters, with an
explicit rvv10 switch instead of rvv10_b > 0, and the XC hooks pass these
parameters to vdw::add_rvv10 instead of the adapter reading global state.
The libxc hook moves to the single exit of v_xc_libxc, next to the one in
v_xc_meta, so the existing return of v_xc is unchanged.

The adapter test drops cases that other cases already cover and merges the
distributed stress check into the distributed grid test; the new
Parallel_Common::alltoallv_data gets a case in the existing 4-rank
parallel_device test, which runs without libvdwxc. CMake enables C in the
shared language block and warns, instead of stopping, when MKL meets an MPI
libvdwxc. INPUT and docs keep the parameter values in one place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With an MPI build, vdwxc_init_mpi creates FFTW-MPI plans and libvdwxc runs
them through the public fftw_execute_* symbols. When ABACUS links the FFTW
interface of MKL or KML, these symbols resolve to that interface, which
cannot execute FFTW-MPI plans, so CMake now stops instead of warning.

The install guide builds libvdwxc as a shared library, the form that was
validated, and the rebuild hint names both required options. The workspace
comment is reworded, and the vdw_method comment in Input_para keeps its
develop text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CleverPhysician

Copy link
Copy Markdown
Author

Updated in a1b108ab3, 7e9425c86 and b378fb261:

  1. rVV10 is selected with vdw_method rvv10, independently of dft_functional. The new vdw_rvv10_b and vdw_rvv10_c parameters default to 6.3 and 0.0093. For SCAN, b can be set to 15.7. The correction uses the existing XC evaluators and bookkeeping.
  2. The libvdwxc object, FFT plans and buffers are reused. A grid or pool change rebuilds the workspace; cell and b/C values are updated on each call. The create/finalize benchmark took about 1–5 ms on 64^3–144^3 grids at 1 and 4 ranks, under 2% of one evaluation.
  3. With more than one process per pool, the adapter uses vdwxc_init_mpi and Parallel_Common::alltoallv_data to redistribute data without gathering the grid on the pool root. For MPI builds, CMake requires MPI-enabled libvdwxc and rejects the MKL/KML FFTW interfaces. The adapter still assumes libvdwxc's default FFTW-MPI slab layout because the library does not expose it.
  4. vdwxc_stress supplies the explicit strain derivative. ABACUS adds the gradient contribution, while density-dependent terms use the existing XC and NLCC paths. Stress and cell relaxation are enabled. The tested rVV10-minus-semilocal stress contribution agrees with finite strains within 0.02 kbar in PW and 0.05 kbar in LCAO for ONCV/smooth-NLCC cases. Hard-NLCC residuals remain up to 1.1 kbar at 120 Ry and 0.4 kbar at 480 Ry. Absolute PW NLCC stresses also have large residuals in the semilocal controls, so total-stress accuracy is still unresolved.

For the input-validation comment, vdw_method accepts the listed lowercase values; uppercase and mixed-case variants are rejected. DFPT and LR forces/relaxations are checked after INPUT resets, including the reset that enables forces for relaxation. These INPUT conditions have no duplicate runtime guard.

With MPI-enabled libvdwxc da2d55f, the tightly converged rPW86+PBE+rVV10 Si energies agree within 2e-11 eV across 1–4 ranks. Backend-enabled CTest passed 18/18; the LCAO selection passed 8/9, with the LR test failing because the loaded Libxc does not provide KXC for Slater exchange. The PR description lists the remaining coverage and limitations. Cluster validation covers the runtime changes through 7e9425c86; the final CMake/text commit b378fb261 was checked locally but has not been rebuilt on the cluster.

One correction to my earlier target reply: since 256d216, libvdwxc::vdwxc is linked to xc_, which compiles the adapter, rather than _abacus_feature_libs.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature Discussed The features will be discussed first but will not be implemented soon

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants