Coverage for eminus/xc/gga_x_chachiyo.py: 100.00%

25 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-10-21 12:19 +0000

1# SPDX-FileCopyrightText: 2023 The eminus developers 

2# SPDX-License-Identifier: Apache-2.0 

3"""Chachiyo GGA exchange. 

4 

5Reference: Molecules 25, 3485. 

6""" 

7 

8import math 

9 

10from eminus import backend as xp 

11 

12from .lda_x import lda_x 

13 

14 

15def gga_x_chachiyo(n, dn_spin=None, **kwargs): 

16 """Chachiyo parametrization of the exchange functional (spin-paired). 

17 

18 Corresponds to the functional with the label GGA_X_CHACHIYO and ID 298 in Libxc. 

19 

20 Reference: Molecules 25, 3485. 

21 

22 Args: 

23 n: Real-space electronic density. 

24 

25 Keyword Args: 

26 dn_spin: Real-space gradient of densities per spin channel. 

27 **kwargs: Throwaway arguments. 

28 

29 Returns: 

30 Chachiyo exchange energy density, potential, and vsigma. 

31 """ 

32 norm_dn = xp.linalg.norm(dn_spin[0], axis=1) 

33 ex, _, _ = lda_x(n, **kwargs) 

34 

35 x = norm_dn / n ** (4 / 3) * 2 / 9 * (math.pi / 3) ** (1 / 3) 

36 x1 = x + 1 

37 logx1 = xp.log(x1) 

38 div = 3 * x + math.pi**2 

39 tmpgex = 3 * x**2 + math.pi**2 * logx1 

40 gex = tmpgex / (div * logx1) 

41 

42 term1 = 8 * ex / tmpgex * (x**2 + x * math.pi**2 / (6 * x1)) + 2 / 3 * norm_dn / n * ( 

43 1 / div + 1 / (3 * logx1 * x1) 

44 ) 

45 gvx = (1 + 1 / 3) * ex - term1 

46 

47 vsigmax = n * 3 * term1 / (8 * norm_dn**2) 

48 return ex * gex, xp.stack([gvx]) * gex, xp.stack([vsigmax]) * gex 

49 

50 

51def gga_x_chachiyo_spin(n, zeta, dn_spin=None, **kwargs): 

52 """Chachiyo parametrization of the exchange functional (spin-polarized). 

53 

54 Corresponds to the functional with the label GGA_X_CHACHIYO and ID 298 in Libxc. 

55 

56 Reference: Molecules 25, 3485. 

57 

58 Args: 

59 n: Real-space electronic density. 

60 zeta: Relative spin polarization. 

61 

62 Keyword Args: 

63 dn_spin: Real-space gradient of densities per spin channel. 

64 **kwargs: Throwaway arguments. 

65 

66 Returns: 

67 Chachiyo exchange energy density, potential, and vsigma. 

68 """ 

69 # Use the spin-scaling relationship Exc(n_up, n_down)=(Exc(2 n_up)+Exc(2 n_down))/2 

70 n_up = zeta * n + n # 2 * n_up 

71 n_dw = -zeta * n + n # 2 * n_down 

72 ex_up, vx_up, vsigma_up = gga_x_chachiyo(n_up, xp.stack([2 * dn_spin[0]]), **kwargs) 

73 ex_dw, vx_dw, vsigma_dw = gga_x_chachiyo(n_dw, xp.stack([2 * dn_spin[1]]), **kwargs) 

74 vx_up, vx_dw = vx_up[0], vx_dw[0] # Remove spin dimension for the correct shape 

75 vsigma_up, vsigma_dw = vsigma_up[0], vsigma_dw[0] # Remove spin dimension for the correct shape 

76 

77 vsigmax = xp.stack([2 * vsigma_up, xp.zeros_like(vsigma_up), 2 * vsigma_dw]) 

78 return 0.5 * (ex_up * n_up + ex_dw * n_dw) / n, xp.stack([vx_up, vx_dw]), vsigmax