Repository navigation
[OFDFT] Non-unit TF weight is missing from single-spin total energy #8243
Description
Describe the bug
For nspin = 1, KEDF_TF::get_energy() omits tf_weight_, although tf_potential() and get_energy_density() already apply it. As a result, the reported energy and its functional derivative describe different functionals when of_tf_weight != 1.
Reproduced on develop at 64463eb3d using CPU unit tests. Relevant implementation: kedf_tf.cpp.
Expected behavior
For a prescribed density, the weighted TF energy in Ry is
For two grid values rho = {1, 8} and dV = 0.25, the integral is 33 * dV:
| TF weight | Current total energy (Ry) | Expected total energy (Ry) |
|---|---|---|
| 0 | 47.3753610031052 | 0 |
| 0.4 | 47.3753610031052 | 18.9501444012421 |
| 1 | 47.3753610031052 | 47.3753610031052 |
At weight zero the TF potential vanishes, but the current total energy still depends on density. For a particle-conserving perturbation eta = {1, -1}, weight 0.4 gives a central energy difference of approximately -7.178085, while dV * sum(v_TF * eta) is approximately -2.871234.
To reproduce
Append this small prescribed-density test to source/source_pw/module_ofdft/test/test_kedf_tf.cpp:
TEST_F(TestKEDFTF, ReproduceNonUnitTFWeight)
{
const double density[] = {1.0, 8.0};
const double* rho[] = {density};
const double weight = 0.4;
const double dV = 0.25;
kedf.set_para(2, dV, weight);
const double energy = kedf.get_energy(rho);
const double expected = 18.950144401242063;
EXPECT_NEAR(energy, expected, 1e-12);
}Configure a CPU testing build, then run:
cmake -S . -B build -DBUILD_TESTING=ON -DENABLE_MPI=ON \
-DENABLE_LCAO=OFF -DENABLE_ELPA=OFF -DENABLE_LIBXC=OFF \
-DENABLE_LIBRI=OFF -DENABLE_FFT_TWO_CENTER=OFF
cmake --build build --target MODULE_PW_OfDFT -j 6
OMP_NUM_THREADS=1 build/source/source_pw/module_ofdft/test/MODULE_PW_OfDFT \
--gtest_filter=TestKEDFTF.ReproduceNonUnitTFWeightThe test runs with the default single spin channel. This is an analytic API reproducer, not a material-dependent reference calculation.
Additional regression tests confirm the same inconsistency through KEDF_Manager for both TF and complete WT energies with a fixed-electron-number density perturbation. The WT kernel does not compensate for the missing factor in the TF energy.
Environment
- Ubuntu 24.04.4 LTS
- GCC 13.3.0, CMake 3.28.3
- CPU, MPI-enabled build; test executed as one process with
OMP_NUM_THREADS=1 - FFTW3, OpenBLAS/ScaLAPACK, system GoogleTest
Scope and proposed fix
Apply the stored TF weight in the single-spin energy integral and add energy/derivative, energy-density integral, and cached-stress regressions. get_stress() uses the cached TF energy, so its TF contribution also needs the corrected energy.
The nspin = 2 total-energy branch already includes the weight, and the default weight of 1 is unchanged. The potential formula already includes the weight. This report does not imply that all OFDFT densities, forces, or previous calculations are wrong: the effect depends on the actual parameters, convergence path, and quantity being used.
The existing tests/07_OFDFT/11_OF_TF_weight case uses of_tf_weight = 1.1; its reference values need to be regenerated and explained with the fix. Other kinetic-energy-density/ELF semantics are separate from this narrowly scoped energy issue.
Activity
ABACUS-PR-BOT commentedon Oct 30, 2026
Confirmed by source tracing and independent scalar checks at
64463eb3d896bb878d8efecdd8c10ab2e9484be7: the missing single-spin TF weight reaches the cached energy used byKEDF_Manager, line search, energy convergence and TF stress. The fixed-particle-number derivative mismatch also rules out a chemical-potential offset; at a fixed configured WT kernel, its nonlocal term does not cancel this inconsistency.The one-spin energy factor proposed in #8244 targets this cause. This diagnosis did not execute ABACUS or verify the reported material results; those remain separate from the source conclusion. Broader ELF/KED conventions are outside this narrowly scoped fix.