Repository navigation
feat(xc): add libvdwxc-backed rVV10 nonlocal XC - #8140
CleverPhysician wants to merge 28 commits into
Conversation
|
Update after the hosted checks completed:
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. |
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 |
ABACUS-PR-BOT
left a comment
There was a problem hiding this comment.
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.
|
Follow-up on head
The PR remains Draft while the new head's hosted checks are queued and the QE same-density reference is discussed. |
|
Addressed the ABACUS-PR-BOT static review on head
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. |
| 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() |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
| 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() |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
|
|
||
| ## Follow-up work | ||
|
|
||
| The next PRs can add a libvdwxc MPI/PFFT adapter, ordinary spin, GPU/LCAO |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Noted, thanks. This page was removed in c23f000; the adapter calls vdwxc_init_serial, and ABACUS does not directly discover or link PFFT.
|
Thanks for asking. I reran the unchanged libvdwxc revision Both builds used GCC 11.2.1, Release ( With
The original MKL executable reproduces exactly the same values under a clean environment with no 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_testSelecting Both configurations pass the separate CP2K-table reference comparisons in that test: energy, density/sigma derivatives, and explicit stress on a The current evidence therefore isolates the discrepancy to this MKL backend configuration. The underlying cause has not been established. Updated head This update also removes the manual CMake target/header/API checks and uses |
|
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 |
|
Follow-up on
The earlier 18 successful hosted checks apply to |
|
Thanks, checked the fix at The new adapter has now also been compared against the immutable original-QE |
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>
|
Please answer directly to each comment. |
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>
At libvdwxc
Not in this PR: the documented build uses standalone FFTW with |
Thanks for reproducing it. |
Checked, thanks for the fix. At libvdwxc |
Done. Each inline and conversation comment from ABACUS-PR-BOT and Growl1234 now has a direct reply. Since your comment, I merged develop ( Two points need your decision:
|
|
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>
|
In |
rVV10 nonlocal correlation through libvdwxc
dft_functional rvv10selects rPW86 exchange, PBE correlation and the rVV10 nonlocal correlation (Sabatini, Gorni and de Gironcoli, PRB 87, 041108(R) (2013); b = 6.3, C = 0.0093). The kernel and convolution come from libvdwxc (rVV10 API from merge request !32, commit94410eb).Implementation
XC_Functional::set_xc_typemaps the short nameRVV10to{XC_GGA_X_RPW86, XC_GGA_C_PBE}and the nonlocal parametersnlc_b,nlc_c(named after libxc's fields), reset on every call and saved byScopedType.XC_Functional::v_xcadds the nonlocal term afterv_xc_libxcwhennlc_b > 0. Existing callers ofv_xc, includingPotXCand the NLCC force code, receive the same nonlocal correction. Nosource_estatechanges remain relative to develop8e20175.vdw::add_rvv10(source_hamilt/module_vdw/nonlocal_xc.{h,cpp}, compiled into the XC library whenENABLE_LIBVDWXCis on) forms the total density and its plane-wave gradient, collects the grid on the pool root withParallel_Commonsend/recv, calls the serial libvdwxc API with a per-call handle, and adds energy, potential andvtxcin Ry. Left-handed cells are inverted before the call because libvdwxc integrates with the signed volume.stress_ggaandinit_dfptback this up.dft_functional rvv10replaces the earlierxc_nonlocalparameter; no new INPUT key is added. Thedft_functionalmetadata is updated in its existing registration.Build
ENABLE_LIBVDWXCis acmake_dependent_optiononENABLE_LIBXC;find_package(libvdwxc CONFIG REQUIRED)needs libvdwxc's CMake build. Same pattern as DFT-D4: compile definition, build info,--infoline,docs/advanced/install.md,docs/CITATIONS.md. The legacy Makefile does not build the feature.Tests
Recorded cluster validation for the source changes in
256d216used GCC 11.5.0, OpenMPI 4.1.1, Libxc 6.2.2, standalone FFTW 3.3.11 and libvdwxc94410eb:MODULE_HAMILT_nonlocal_xcTestat 1 and 2 ranks, the existing vdW test and 11 selected XC CTest entries.dft_functional rvv10was rejected with the intended build-support diagnostic; semilocal SCF passed.MODULE_LR_pot_hxc_lrtdstopped because the loaded Libxc did not provide KXC for Slater exchange.ScopedTyperestoration, parity with direct libvdwxc calls, spin channels, distributed vs complete grids (an uneven 5+4 z split at two ranks), finite-difference potential, oblique and left-handed cells, andv_xcfor RVV10 vs the semilocal result plus the nonlocal term.MODULE_IO_read_input_serial.Rvv10RejectsStressDfptAndLrForces; this reader regression is not part of the archived CTest selections above. Separate runtime cases confirmed early rejection of stress, cell relaxation and DFPT.scf_thr=1e-10, PW energies differ by at most1.4e-11 eVacross 1, 2 and 4 ranks, and by4.1e-11 eVacrossnspin=1,2,4for nonmagnetic Si at two ranks. The tested LCAO 1/2-rank andnspin=1,2cases agree within1.3e-11 eV. These are separate comparisons, not a complete rank-by-spin matrix.1e-13 eV. For the tested Si NLCC force component, the finite-difference errors are1.2e-4 eV/angstrom(PW) and1.1e-3 eV/angstrom(LCAO), comparable to the semilocal controls (1.4e-4and1.4e-3 eV/angstrom, respectively).Checks not run in this validation: GPU builds, ELPA-based LCAO solvers, USPP with rVV10, and an independent material SCF reference comparison. Hosted CI does not enable the optional libvdwxc backend; results for the previous head do not certify
256d216.Open points for the maintainers
vdwxc_stress), and libxc's own*_RVV10functionals throughxc_nlc_coef.<tuple>for the result-tuple declaration;ChargeandModuleBase::matrixare forward-declared.🤖 Generated with Claude Code