Coverage for gpaw/test/ralda/test_pbe_deriv.py: 100%
17 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-14 00:18 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-14 00:18 +0000
1import pytest
2import numpy as np
3from gpaw.xc.fxc_kernels import get_pbe_fxc_and_intermediate_derivatives
6def eps_unif_x(kf_g):
7 return -3 * kf_g / (4.0 * np.pi)
10# (We test "small" and "large" densities separately)
11@pytest.mark.parametrize(
12 'n_g', [
13 np.linspace(0.001, 0.02, 10000),
14 np.linspace(0.02, 0.5, 1000)
15 ])
16def test_pbe_x_derivs(n_g):
17 # Here we test d(fxc(n))/dn. We create a linspace of n and
18 # calculate all the derivatives. However we put a dummy (constant)
19 # value for s2_g (the gradient) which makes the numerics sensitive
20 # (I think) for small densities.
21 #
22 # This test guards against the problem observed in #723.
23 dn = n_g[1] - n_g[0]
24 # (assuming np.linspace)
26 gradn2 = np.ones_like(n_g)
27 kf_g = (3. * np.pi**2 * n_g)**(1 / 3.)
28 s2_g = gradn2 / (4 * kf_g**2 * n_g**2)
30 fxc_g, F_g, Fn_g, Fnn_g = get_pbe_fxc_and_intermediate_derivatives(
31 n_g, s2_g)
33 def numderiv(y_g):
34 return (y_g[1:] - y_g[:-1]) / dn
36 E_g = n_g * eps_unif_x(kf_g) * F_g
37 d2Edn2_num = numderiv(numderiv(E_g))
39 assert fxc_g[1:-1] == pytest.approx(d2Edn2_num, abs=1e-4, rel=1e-4)
40 # We could also test the other derivatives (Fn, Fnn)
41 # but that's probably not highest priority.