Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
a110fc5
feat(xc): add libvdwxc-backed rVV10 adapter
Oct 13, 2026
a8ab61b
fix(build-info): report libvdwxc in Makefile builds
Oct 13, 2026
52d9da6
fix(xc): avoid libvdwxc header macro collision
Oct 13, 2026
48bc03f
test(xc): cover nonlocal potential derivative
Oct 13, 2026
e609791
docs(xc): state external validation gate clearly
Oct 13, 2026
3b58915
build(tests): register adapter after its dependencies
Oct 13, 2026
4ad8c37
build(tests): register after device target
Oct 13, 2026
e476398
docs(xc): make serial libvdwxc test command reproducible
Oct 13, 2026
67e6c66
docs(xc): add rVV10 citation guidance
Oct 13, 2026
f3d41ad
refactor(xc): make adapter validation explicit
Oct 13, 2026
32e12de
fix(xc): reject unsupported rVV10 density grids and spin
Oct 14, 2026
e65e07c
fix(xc): preserve cell orientation in libvdwxc adapter
Oct 14, 2026
3286e20
Merge latest develop and keep generated INPUT docs untracked
Oct 14, 2026
c23f000
refactor(xc): simplify libvdwxc adapter after review
Oct 14, 2026
9da9d84
fix(xc): prohibit copying owned libvdwxc handles
Oct 14, 2026
c3dedfb
test(xc): verify additive nonlocal host bookkeeping
Oct 14, 2026
95528a1
docs(xc): pin validated libvdwxc FFT-boundary fix
Oct 14, 2026
be61717
Merge develop and preserve rVV10 input parameters
Oct 15, 2026
1b09868
fix(io): report the first unsupported rVV10 input setting
Oct 17, 2026
00ae9bb
refactor(xc): keep the libvdwxc C header out of the adapter interface
Oct 17, 2026
a6c3ed4
docs(xc): trim the rVV10 test notes and drop the duplicate CI step
Oct 17, 2026
916a35e
Merge develop 8e20175 into rvv10-latest-clean
Oct 25, 2026
9828e9b
refactor(xc): select the nonlocal XC component from Input_para and fi…
Oct 25, 2026
76e9c1c
test(xc): drop the Python build-report test and register the adapter …
Oct 25, 2026
815deae
style(xc): name tolerances, reuse constants.h and format the new files
Oct 25, 2026
0df2a42
refactor(xc): shorten the adapter file names and split its evaluation
Oct 26, 2026
a682b56
style(xc): format the new hunks with the pre-commit clang-format and …
Oct 26, 2026
256d216
refactor(xc): select rVV10 through dft_functional and add it in XC_Fu…
Oct 27, 2026
a1b108a
refactor(xc): select rVV10 as vdw_method rvv10 and use libvdwxc's dis…
Oct 27, 2026
7e9425c
refactor(xc): keep the rVV10 hooks in their owning modules
Oct 27, 2026
b378fb2
build(xc): stop for MKL or KML with an MPI libvdwxc
Oct 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ option(USE_SW "Enable SW Architecture" OFF)

option(ENABLE_ABACUS_LIBM "Build libmath from source to speed up" OFF)
option(ENABLE_LIBXC "Enable using the LibXC package" OFF)
cmake_dependent_option(ENABLE_LIBVDWXC "Enable using the libvdwxc package" OFF
"ENABLE_LIBXC" OFF)
option(ENABLE_FLOAT_FFTW "Enable using single-precision FFTW library." OFF)

option(ENABLE_LCAO "Enable LCAO algorithm" ON)
Expand Down Expand Up @@ -285,6 +287,10 @@ if(ENABLE_DFTD4 OR ENABLE_PEXSI)
enable_language(C)
enable_language(Fortran)
endif()
# The libvdwxc package configuration looks up MPI for C when libvdwxc was built with MPI.
if(ENABLE_LIBVDWXC)
enable_language(C)
endif()

macro(set_if_higher VARIABLE VALUE)
if(${VARIABLE} LESS ${VALUE})
Expand Down Expand Up @@ -643,6 +649,24 @@ if(ENABLE_LIBXC)
endif()
endif()

if(ENABLE_LIBVDWXC)
find_package(libvdwxc CONFIG REQUIRED)
# An MPI build calls vdwxc_init_mpi, which only an MPI-enabled libvdwxc provides.
if(ENABLE_MPI AND NOT VDWXC_ENABLE_MPI)
message(
FATAL_ERROR
"ENABLE_LIBVDWXC with ENABLE_MPI requires libvdwxc configured with -DVDWXC_ENABLE_MPI=ON"
)
endif()
# vdwxc_init_mpi creates FFTW-MPI plans, which the FFTW interface of MKL or KML cannot execute.
if(ENABLE_MPI AND (MKL_FOUND OR USE_KML))
message(
FATAL_ERROR
"ENABLE_LIBVDWXC with ENABLE_MPI requires ABACUS built with FFTW3, not with the FFTW interface of MKL or KML"
)
endif()
endif()

if(DEFINED DeePMD_DIR)
find_package(DeePMD REQUIRED)
endif()
Expand Down
7 changes: 7 additions & 0 deletions cmake/CollectBuildInfoVars.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@ else()
set(ABACUS_DFTD4_VERSION "no")
endif()

if(ENABLE_LIBVDWXC)
set(ABACUS_LIBVDWXC_VERSION "yes (v${libvdwxc_VERSION})")
else()
set(ABACUS_LIBVDWXC_VERSION "no")
endif()

# Accelerators
if(USE_CUDA AND CUDAToolkit_VERSION)
set(ABACUS_CUDA_VERSION "yes (v${CUDAToolkit_VERSION})")
Expand Down Expand Up @@ -480,6 +486,7 @@ message(" NEP = ${ABACUS_NEP_VERSION}")
message(" Features : Libxc = ${ABACUS_LIBXC_VERSION}")
message(" LibRI = ${ABACUS_LIBRI_VERSION}")
message(" DFT-D4 = ${ABACUS_DFTD4_VERSION}")
message(" libvdwxc = ${ABACUS_LIBVDWXC_VERSION}")
message(" JSON = ${ABACUS_JSON_VERSION}")
message(" PEXSI = ${ABACUS_PEXSI_VERSION}")
message(" CNPY = ${ABACUS_CNPY_VERSION}")
Expand Down
10 changes: 10 additions & 0 deletions docs/CITATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,13 @@ The following references are required to be cited when using ABACUS. Specificall
Eike Caldeweyher, Jan-Michael Mewes, Sebastian Ehlert, and Stefan Grimme. "Extension and evaluation of the D4 London-dispersion model for periodic systems." Physical Chemistry Chemical Physics 22, 8499-8512 (2020). DOI: 10.1039/D0CP00502A.

Nikolay V. Tkachenko, Linus B. Dittmer, Rebecca Tomann, and Martin Head-Gordon. "Smooth D4S model." The Journal of Physical Chemistry Letters 15, 10629-10637 (2024). DOI: 10.1021/acs.jpclett.4c02653.

- **If the rVV10 nonlocal correlation (`vdw_method rvv10`) is used:**

O. A. Vydrov and T. Van Voorhis. "Nonlocal van der Waals density functional: The simpler the better." The Journal of Chemical Physics 133, 244103 (2010). DOI: 10.1063/1.3521275.

R. Sabatini, T. Gorni, and S. de Gironcoli. "Nonlocal van der Waals density functional made simple and efficient." Physical Review B 87, 041108(R) (2013). DOI: 10.1103/PhysRevB.87.041108.

A. H. Larsen, M. Kuisma, J. Löfgren, Y. Pouillon, P. Erhart, and P. Hyldgaard. "libvdwxc: a library for exchange-correlation functionals in the vdW-DF family." Modelling and Simulation in Materials Science and Engineering 25, 065004 (2017). DOI: 10.1088/1361-651X/aa7320.

For SCAN+rVV10 and r2SCAN+rVV10, also cite the parametrization: H. Peng, Z.-H. Yang, J. P. Perdew, and J. Sun. "Versatile van der Waals density functional based on a meta-generalized gradient approximation." Physical Review X 6, 041005 (2016). DOI: 10.1103/PhysRevX.6.041005; J. Ning, M. Kothakonda, J. W. Furness, A. D. Kaplan, S. Ehlert, J. G. Brandenburg, J. P. Perdew, and J. Sun. "Workhorse minimally empirical dispersion-corrected density functional with tests for weakly bound systems: r2SCAN+rVV10." Physical Review B 106, 075422 (2022). DOI: 10.1103/PhysRevB.106.075422.
19 changes: 19 additions & 0 deletions docs/advanced/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,25 @@ vdw_d4_model d4 # or d4s for the smooth D4S model

If `vdw_d4_xc` is set to `default`, ABACUS will infer the functional name from `dft_functional` or pseudopotential metadata and pass it to the DFT-D4 library. The `vdw_d4_model` keyword selects the dispersion model inside the DFT-D4 library; the default is `d4`, while `d4s` enables the smooth D4S model.

## Build with libvdwxc support

`vdw_method rvv10` evaluates the rVV10 nonlocal correlation with the external [libvdwxc](https://gitlab.com/libvdwxc/libvdwxc) library. Until a tagged libvdwxc release contains the rVV10 interface, build the branch of [libvdwxc merge request !32](https://gitlab.com/libvdwxc/libvdwxc/-/merge_requests/32) (tested at commit `da2d55f`) with libvdwxc's CMake build, which installs the package that ABACUS looks up, and against the FFTW that ABACUS uses. For an MPI build of ABACUS, configure libvdwxc with MPI, which needs FFTW with its MPI library:

```bash
cmake -S libvdwxc -B build-libvdwxc -DBUILD_SHARED_LIBS=ON -DVDWXC_ENABLE_MPI=ON -DCMAKE_INSTALL_PREFIX=/path/to/libvdwxc
cmake --build build-libvdwxc && cmake --install build-libvdwxc
```

Then pass `-DENABLE_LIBXC=ON -DENABLE_LIBVDWXC=ON` to CMake for ABACUS and add `/path/to/libvdwxc` to `CMAKE_PREFIX_PATH`. ABACUS hands each k-point pool's density to libvdwxc's distributed interface, so the nonlocal convolution and its memory are shared by the processes of the pool. libvdwxc's MPI build plans its FFTs with FFTW-MPI, so an MPI build of ABACUS with libvdwxc must use FFTW3 rather than the FFTW interface of MKL or KML; CMake stops otherwise. The legacy Makefile does not build this feature.

In the input file:

```text
vdw_method rvv10
dft_functional scan
vdw_rvv10_b 15.7 # b of SCAN+rVV10; see vdw_rvv10_b for other functionals
```

## Build with JSON support

ABACUS uses [nlohmann-json](https://github.com/nlohmann/json) for optional JSON output. To build ABACUS with JSON support, pass `-DENABLE_JSON=ON` to CMake.
Expand Down
1 change: 1 addition & 0 deletions docs/advanced/scf/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ To use VdW-correction, users need to supply value to the `vdw_method` keyword in
- d2: DFT-D2 method
- d3_0: DFT-D3(0) method
- d3_bj: DFT-D3(BJ) method
- rvv10: rVV10 nonlocal correlation (requires libvdwxc). Unlike the DFT-D methods, it depends on the electron density: it is added self-consistently to the exchange-correlation energy and potential of `dft_functional`, and its energy is reported in the exchange-correlation term. Set `vdw_rvv10_b` for the functional; its description lists the published values.

Furthermore, ABACUS also provides a [list of keywords](../input_files/input-main.md#vdw-correction) to control relevant parmeters used in calculating the VdW correction, such as the scale factor (s6) term. Recommended values of such parameters can be found on the [webpage](https://www.chemie.uni-bonn.de/pctc/mulliken-center/software/dft-d3). The default values of the parameters in ABACUS are set to be the recommended values for PBE.

Expand Down
1 change: 1 addition & 0 deletions generate_build_info.sh
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ sed \
-e "s#@ABACUS_OPENMP_VERSION@#$OPENMP_VERSION#g" \
-e "s#@ABACUS_MKL_SUPPORT@#$MKL_SUPPORT#g" \
-e "s#@ABACUS_LIBXC_VERSION@#$LIBXC_VERSION#g" \
-e "s#@ABACUS_LIBVDWXC_VERSION@#no#g" \
-e "s#@ABACUS_FFTW_VERSION@#$FFTW3_VERSION#g" \
-e "s#@ABACUS_CUDA_VERSION@#$CUDA_VERSION#g" \
-e "s#@ABACUS_ROCM_VERSION@#$ROCM_VERSION#g" \
Expand Down
2 changes: 2 additions & 0 deletions source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ set(_abacus_feature_definitions
$<$<BOOL:${ENABLE_LIBRI}>:TEST_EXX_RADIAL=1>
$<$<BOOL:${ENABLE_LIBXC}>:__LIBXC>
$<$<BOOL:${ENABLE_DFTD4}>:__DFTD4>
$<$<BOOL:${ENABLE_LIBVDWXC}>:__LIBVDWXC>
$<$<BOOL:${MATH_INFO}>:GATHER_INFO>)

if(ABACUS_COMMIT_INFO_INCLUDE_DIR)
Expand Down Expand Up @@ -407,6 +408,7 @@ foreach(
ELPA::ELPA
Libxc::xc
dftd4::dftd4
libvdwxc::vdwxc
DeePMD::deepmd_c
DeePMD::deepmd_cc
NEP::nep
Expand Down
10 changes: 10 additions & 0 deletions source/source_base/parallel_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,16 @@ void gatherv_data(const std::complex<float>* sendbuf, int sendcount, std::comple
{
MPI_Allgatherv(sendbuf, sendcount, MPI_COMPLEX, recvbuf, recvcounts, displs, MPI_COMPLEX, comm);
}
void alltoallv_data(const double* sendbuf,
const int* sendcounts,
const int* sdispls,
double* recvbuf,
const int* recvcounts,
const int* rdispls,
const MPI_Comm& comm)
{
MPI_Alltoallv(sendbuf, sendcounts, sdispls, MPI_DOUBLE, recvbuf, recvcounts, rdispls, MPI_DOUBLE, comm);
}

#ifndef __CUDA_MPI
template <typename T>
Expand Down
7 changes: 7 additions & 0 deletions source/source_base/parallel_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ void gatherv_data(const double* sendbuf, int sendcount, double* recvbuf, const i
void gatherv_data(const std::complex<double>* sendbuf, int sendcount, std::complex<double>* recvbuf, const int* recvcounts, const int* displs, MPI_Comm& comm);
void gatherv_data(const float* sendbuf, int sendcount, float* recvbuf, const int* recvcounts, const int* displs, MPI_Comm& comm);
void gatherv_data(const std::complex<float>* sendbuf, int sendcount, std::complex<float>* recvbuf, const int* recvcounts, const int* displs, MPI_Comm& comm);
void alltoallv_data(const double* sendbuf,
const int* sendcounts,
const int* sdispls,
double* recvbuf,
const int* recvcounts,
const int* rdispls,
const MPI_Comm& comm);

#if defined(__NCCL_PARALLEL_DEVICE)
void nccl_bcast_data(double* object, const int& n, MPI_Comm& comm, int root = 0);
Expand Down
43 changes: 43 additions & 0 deletions source/source_base/test_parallel/parallel_device_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,5 +131,48 @@ TEST(ParallelDevice, CoversMpiTypeOverloads)
exercise_mpi_wrappers<std::complex<double>>(domain);
}

TEST(ParallelDevice, AlltoallvExchangesUnevenBlocks)
{
const ModuleBase::CommunicationDomain domain = ModuleBase::world_comm_domain();
MPI_Comm communicator = domain.communicator();
const int rank = domain.rank();
MPICommGroup world_group(communicator);
const int size = world_group.gsize;
// rank r sends (r + p) % 2 + 1 copies of 100 r + p to rank p
std::vector<int> send_counts(size);
std::vector<int> send_offsets(size);
std::vector<int> recv_counts(size);
std::vector<int> recv_offsets(size);
std::vector<double> sent;
int received_total = 0;
for (int peer = 0; peer < size; ++peer)
{
const double value = 100.0 * rank + peer;
send_counts[peer] = (rank + peer) % 2 + 1;
send_offsets[peer] = static_cast<int>(sent.size());
sent.insert(sent.end(), send_counts[peer], value);
recv_counts[peer] = send_counts[peer];
recv_offsets[peer] = received_total;
received_total += recv_counts[peer];
}
std::vector<double> received(received_total);
Parallel_Common::alltoallv_data(sent.data(),
send_counts.data(),
send_offsets.data(),
received.data(),
recv_counts.data(),
recv_offsets.data(),
communicator);
for (int peer = 0; peer < size; ++peer)
{
const double expected = 100.0 * peer + rank;
for (int index = 0; index < recv_counts[peer]; ++index)
{
const int position = recv_offsets[peer] + index;
EXPECT_EQ(received[position], expected);
}
}
}

} // namespace
#endif
3 changes: 3 additions & 0 deletions source/source_esolver/esolver_fp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ void ESolver_FP::before_all_runners(BaseCell& basecell, const Input_para& inp)
xc_parameters.exx_erfc_alpha = inp.exx_erfc_alpha;
xc_parameters.xc_exch_ext = inp.xc_exch_ext;
xc_parameters.xc_corr_ext = inp.xc_corr_ext;
xc_parameters.rvv10 = inp.vdw_method == "rvv10";
xc_parameters.rvv10_b = inp.vdw_rvv10_b;
xc_parameters.rvv10_c = inp.vdw_rvv10_c;
XC_Functional::set_runtime_parameters(xc_parameters);

ModuleBase::TITLE("ESolver_FP", "before_all_runners");
Expand Down
Loading
Loading