Coverage for gpaw/lcao/bsse.py: 99%

84 statements  

« prev     ^ index     » next       coverage.py v7.7.1, created at 2025-07-14 00:18 +0000

1"""BSSE: Basis Set Superposition Error module. 

2 

3Defines a Setup-like class which has no properties that change anything, 

4except for an atomic basis set.""" 

5 

6import numpy as np 

7from ase.data import atomic_numbers 

8 

9from gpaw.setup import BaseSetup, LocalCorrectionVar 

10from gpaw.spline import Spline 

11from gpaw.utilities import min_locfun_radius 

12 

13 

14# Some splines are mandatory, 

15# but should then be zero to avoid affecting things 

16zero_function = Spline.from_data(0, min_locfun_radius, [0.0, 0.0, 0.0]) 

17 

18# Some operations fail horribly if the splines are zero, due to weird 

19# divisions and assumptions that various quantities are nonzero 

20# 

21# We'll use a function which is almost zero for these things 

22nonzero_function = Spline.from_data( 

23 0, min_locfun_radius, [0.0, 1.0e-12, 0.0], # XXX 

24) 

25 

26 

27class GhostSetup(BaseSetup): 

28 def __init__(self, basis, data): 

29 self.symbol = data.symbol 

30 self.data = data 

31 self.basis_functions_J = basis.tosplines() 

32 self.pseudo_partial_waves_j = None # XXX ? 

33 

34 self.basis = basis 

35 self.nao = sum([2 * phit.get_angular_momentum_number() + 1 

36 for phit in self.basis_functions_J]) 

37 self.filename = None 

38 self.fingerprint = None 

39 self.type = 'ghost' 

40 

41 self.Z = 0 

42 self.Nv = 0 

43 self.Nc = 0 

44 

45 self.ni = 1 

46 self.pt_j = [zero_function] 

47 self.wg_lg = None 

48 self.g_lg = None 

49 

50 self.Nct = 1e-12 # XXX XXX XXX XXX 

51 self.nct = nonzero_function # XXXXXX 

52 self.lmax = 0 

53 self.xc_correction = None 

54 self.ghat_l = [nonzero_function] * (self.lmax + 1) # XXXXXX 

55 self.rcgauss = 1e12 # XXX XXX XXX XXX 

56 self.vbar = zero_function 

57 

58 self.Delta0 = 0.0 

59 self.Delta_pL = np.zeros((1, self.lmax + 1)) 

60 

61 self.E = 0.0 

62 self.Kc = 0.0 

63 self.M = 0.0 

64 self.M_p = np.zeros(1) 

65 self.M_pp = np.zeros((1, 1)) 

66 self.M_wpp = {} 

67 self.K_p = np.zeros(1) 

68 self.MB = 0.0 

69 self.MB_p = np.zeros(1) 

70 self.dO_ii = np.zeros((1, 1)) 

71 self.f_j = [0.0] 

72 self.n_j = [0] 

73 self.l_j = [0] 

74 self.l_orb_J = [0] 

75 self.nj = 1 

76 self.nq = 1 

77 self.N0_q = None # XXXX 

78 

79 self.rcutfilter = None 

80 self.rcore = None 

81 self.N0_p = np.zeros(1) 

82 self.nabla_iiv = np.zeros((self.ni, self.ni, 3)) 

83 self.rxnabla_iiv = np.zeros((self.ni, self.ni, 3)) 

84 self.phicorehole_g = None 

85 self.rgd = None 

86 self.rcut_j = [0.5] 

87 self.tauct = None 

88 self.Delta_iiL = None 

89 self.B_ii = None 

90 self.dC_ii = None 

91 self.X_p = None 

92 self.X_wp = {} 

93 self.X_pg = None 

94 self.ExxC = None 

95 self.ExxC_w = {} 

96 self.dEH0 = 0.0 

97 self.dEH_p = np.zeros(1) 

98 self.extra_xc_data = {} 

99 self.local_corr = LocalCorrectionVar(None) 

100 

101 

102class GhostSetupData: 

103 def __init__(self, symbol): 

104 self.chemsymbol = symbol 

105 self.symbol = symbol + '.ghost' 

106 self.Z = atomic_numbers[symbol] 

107 

108 def build(self, xcfunc, lmax, basis, filter=None): 

109 if basis is None: 

110 raise ValueError('Loading partial waves not supported right now') 

111 setup = GhostSetup(basis, self) 

112 return setup 

113 

114 def print_info(self, text, _setup): 

115 text('Ghost setup for %s' % self.chemsymbol)