Coverage for gpaw/test/xc/test_gga_atom.py: 100%
61 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-20 00:19 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-20 00:19 +0000
1import numpy as np
2import numpy.random as ra
3import pytest
4from gpaw.setup import create_setup
5from gpaw.grid_descriptor import GridDescriptor
6from gpaw.lfc import LFC
7from gpaw.spline import Spline
8from gpaw.xc import XC
9from gpaw.utilities import pack_density
10from gpaw.mpi import serial_comm
13def test_xc_gga_atom():
14 rng = ra.default_rng(8)
15 for name in ['LDA', 'PBE']:
16 xc = XC(name)
17 s = create_setup('N', xc)
18 ni = s.ni
19 nao = s.nao
20 wt0_j = s.basis_functions_J
22 rcut = s.xc_correction.rgd.r_g[-1]
24 wt_j = []
25 for wt0 in wt0_j:
26 data = [wt0(r) for r in np.arange(121) * rcut / 100]
27 data[-1] = 0.0
28 l = wt0.get_angular_momentum_number()
29 wt_j.append(Spline.from_data(l, 1.2 * rcut, data))
31 a = rcut * 1.2 * 2 + 1.0
32 n = 70
33 n = 90
34 gd = GridDescriptor((n, n, n), (a, a, a), comm=serial_comm)
35 pr = LFC(gd, [wt_j])
36 pr.set_positions([(0.5, 0.5, 0.5)])
38 psit_ig = np.zeros((nao, n, n, n))
39 pr.add(psit_ig, {0: np.eye(nao)})
41 nii = ni * (ni + 1) // 2
42 D_p = np.zeros(nii)
44 e_g = np.zeros((n, n, n))
45 n_g = np.zeros((1, n, n, n))
46 v_g = np.zeros((1, n, n, n))
48 P_ni = 0.2 * rng.random((20, ni))
49 P_ni[:, nao:] = 0.0
50 D_ii = np.dot(np.transpose(P_ni), P_ni)
51 D_p = pack_density(D_ii)
52 p = 0
53 for i1 in range(nao):
54 for i2 in range(i1, nao):
55 n_g += D_p[p] * psit_ig[i1] * psit_ig[i2]
56 p += 1
57 p += ni - nao
59 p = LFC(gd, [[s.nct]])
60 p.set_positions([(0.5, 0.5, 0.5)])
61 p.add(n_g[0], 1.0)
62 e_g = gd.zeros()
63 xc.calculate(gd, n_g, v_g, e_g)
65 r2_g = np.sum((np.indices((n, n, n)) - n / 2)**2, axis=0)
66 dv_g = gd.dv * np.less(r2_g, (rcut / a * n)**2)
68 E2 = -np.dot(e_g.ravel(), dv_g.ravel())
70 s.xc_correction.n_qg[:] = 0.0
71 s.xc_correction.nc_g[:] = 0.0
72 E1 = (xc.calculate_paw_correction(s, D_p.reshape(1, -1))
73 + s.xc_correction.e_xc0)
75 print(name, E1, E2, E1 - E2)
76 assert E1 == pytest.approx(E2, abs=0.0013)