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

1"""Python wrapper for GPAW's native XC functionals.""" 

2 

3from gpaw import debug 

4 

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__ 

16 

17 

18class XCNull: 

19 type = 'LDA' 

20 name = 'null' 

21 

22 def calculate(self, e_g, n_sg, dedn_sg): 

23 e_g[:] = 0.0 

24 

25 

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]) 

37 

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. 

42 

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) 

59 

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)