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
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-14 00:18 +0000
1"""BSSE: Basis Set Superposition Error module.
3Defines a Setup-like class which has no properties that change anything,
4except for an atomic basis set."""
6import numpy as np
7from ase.data import atomic_numbers
9from gpaw.setup import BaseSetup, LocalCorrectionVar
10from gpaw.spline import Spline
11from gpaw.utilities import min_locfun_radius
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])
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)
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 ?
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'
41 self.Z = 0
42 self.Nv = 0
43 self.Nc = 0
45 self.ni = 1
46 self.pt_j = [zero_function]
47 self.wg_lg = None
48 self.g_lg = None
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
58 self.Delta0 = 0.0
59 self.Delta_pL = np.zeros((1, self.lmax + 1))
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
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)
102class GhostSetupData:
103 def __init__(self, symbol):
104 self.chemsymbol = symbol
105 self.symbol = symbol + '.ghost'
106 self.Z = atomic_numbers[symbol]
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
114 def print_info(self, text, _setup):
115 text('Ghost setup for %s' % self.chemsymbol)