Coverage for gpaw/xc/kernel.py: 100%
40 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-12 00:18 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-12 00:18 +0000
1"""Python wrapper for GPAW's native XC functionals."""
3from gpaw import debug
5codes = {
6 'LDA': -1,
7 'PBE': 0,
8 'revPBE': 1,
9 'RPBE': 2,
10 'PW91': 14,
11 'TPSS': 20,
12 'M06-L': 21,
13 'revTPSS': 22}
14# NOTE: when adding MGGA functionals to the above
15# list, self.type must be set to MGGA in XCKernel:__init__
18class XCNull:
19 type = 'LDA'
20 name = 'null'
22 def calculate(self, e_g, n_sg, dedn_sg):
23 e_g[:] = 0.0
26class XCKernel:
27 def __init__(self, name):
28 self.name = name
29 if name == 'LDA':
30 self.type = 'LDA'
31 elif name == 'TPSS' or name == 'M06-L' or name == 'revTPSS':
32 self.type = 'MGGA'
33 else:
34 self.type = 'GGA'
35 from _gpaw import XCFunctional
36 self.xc = XCFunctional(codes[name])
38 def calculate(self, e_g, n_sg, dedn_sg,
39 sigma_xg=None, dedsigma_xg=None,
40 tau_sg=None, dedtau_sg=None):
41 """Calculate energy and derivatives from density and gradients.
43 * e_g is the energy density. Values are overwritten.
44 * n_sg is the density and is an input.
45 * dedn_sg is the partial derivative of the energy with
46 respect to the density (any gradients constant). Values are
47 added to this array.
48 * sigma_xg is the squared norm of the gradient and is an input.
49 * dedsigma_xg is the partial derivative of the energy with respect
50 to the squared gradient norm. Values are overwritten.
51 * tau_sg and dedtau_sg probably behave similarly but correspond to
52 2nd-order derivatives for MGGAs. XXX verify and document this.
53 """
54 if debug:
55 self.check_arguments(e_g, n_sg, dedn_sg, sigma_xg, dedsigma_xg,
56 tau_sg, dedtau_sg)
57 self.xc.calculate(e_g, n_sg, dedn_sg, sigma_xg, dedsigma_xg, tau_sg,
58 dedtau_sg)
60 def check_arguments(self, e_g, n_sg, dedn_sg, sigma_xg, dedsigma_xg,
61 tau_sg, dedtau_sg):
62 S = n_sg.shape[0]
63 assert 1 <= S <= 2
64 G = n_sg.shape[1:]
65 assert e_g.shape == G, (e_g.shape, G)
66 assert e_g.flags.contiguous and e_g.dtype == float
67 assert dedn_sg.shape == (S,) + G
68 assert dedn_sg.flags.contiguous
69 assert dedn_sg.dtype == float
70 if self.type != 'LDA':
71 assert sigma_xg.shape == (2 * S - 1,) + G
72 assert dedsigma_xg.shape == (2 * S - 1,) + G
73 assert sigma_xg.flags.contiguous and sigma_xg.dtype == float
74 assert (dedsigma_xg.flags.contiguous and
75 dedsigma_xg.dtype == float)
76 if self.type == 'MGGA':
77 assert tau_sg.shape == (S,) + G
78 assert dedtau_sg.shape == (S,) + G
79 assert tau_sg.flags.contiguous and tau_sg.dtype == float
80 assert (dedtau_sg.flags.contiguous and
81 dedtau_sg.dtype == float)