def __init__(self, alpha=0.6102, v1=3.042, v2=-1.372): self.alpha = alpha self.v1 = v1 self.v2 = v2 self.natoms = 0 self.E = 0.0 self.Z = 14 self.Nc = 10 self.Nv = 4 self.niAO = None nullspline = Spline(0, 0.5, [0., 0., 0.]) self.pt_j = [nullspline] self.ni = 1 self.l_j = [0] self.nct = nullspline self.Nct = 0.0 rc = 4.0 r2_g = np.linspace(0, rc, 100)**2 x_g = np.exp(-alpha * r2_g) self.ghat_l = [Spline(0, rc, 4 * alpha**1.5 / np.pi**0.5 * x_g)] self.vbar = Spline(0, rc, 2 * np.pi**0.5 * (v1 + v2 * r2_g) * x_g) self.Delta_pL = np.zeros((1, 1)) self.Delta0 = -4 / (4 * np.pi)**0.5 self.lmax = 0 self.K_p = self.M_p = self.MB_p = np.zeros(1) self.M_pp = np.zeros((1, 1)) self.Kc = 0.0 self.MB = 0.0 self.M = 0.0 self.xc_correction = null_xc_correction self.HubU = None self.dO_ii = np.zeros((1, 1)) self.type = 'ah' self.fingerprint = None
def generate(self, l, gd, kpt_u, spos_ac, dtype=None): """Generate polarization orbital.""" rcut = self.rcut phi_i = [QuasiGaussian(alpha, rcut) for alpha in self.alphas] r = np.arange(0, rcut, .01) dr = r[1] # equidistant integration_multiplier = r**(2 * (l + 1)) for phi in phi_i: y = phi(r) norm = (dr * sum(y * y * integration_multiplier))**.5 phi.renormalize(norm) splines = [Spline(l, r[-1], phi(r)) for phi in phi_i] if dtype is None: if np.any([kpt.dtype == complex for kpt in kpt_u]): dtype = complex else: dtype = float self.s, self.S = overlaps(l, gd, splines, kpt_u, spos_ac) self.optimizer = CoefficientOptimizer(self.s, self.S, len(phi_i)) coefs = self.optimizer.find_coefficients() self.quality = -self.optimizer.amoeba.y[0] self.qualities = self.optimizer.lastterms orbital = LinearCombination(coefs, phi_i) orbital.renormalize(get_norm(r, orbital(r), l)) return orbital
def spline(self, a_g, rcut=None, l=0, points=None): if points is None: points = self.default_spline_points if rcut is None: g = len(a_g) - 1 while a_g[g] == 0.0: g -= 1 rcut = self.r_g[g + 1] b_g = a_g.copy() N = len(b_g) if l > 0: b_g = divrl(b_g, l, self.r_g[:N]) r_i = np.linspace(0, rcut, points + 1) g_i = np.clip((self.r2g(r_i) + 0.5).astype(int), 1, N - 2) r1_i = self.r_g[g_i - 1] r2_i = self.r_g[g_i] r3_i = self.r_g[g_i + 1] x1_i = (r_i - r2_i) * (r_i - r3_i) / (r1_i - r2_i) / (r1_i - r3_i) x2_i = (r_i - r1_i) * (r_i - r3_i) / (r2_i - r1_i) / (r2_i - r3_i) x3_i = (r_i - r1_i) * (r_i - r2_i) / (r3_i - r1_i) / (r3_i - r2_i) b1_i = b_g[g_i - 1] b2_i = b_g[g_i] b3_i = b_g[g_i + 1] b_i = b1_i * x1_i + b2_i * x2_i + b3_i * x3_i return Spline(l, rcut, b_i)
def calculate_overlap_expansion(self, phit1phit2_q, l1, l2): """Calculate list of splines for one overlap integral. Given two Fourier transformed functions, return list of splines in real space necessary to evaluate their overlap. phi (q) * phi (q) --> [phi (r), ..., phi (r)] . l1 l2 lmin lmax The overlap <phi1 | phi2> can then be calculated by linear combinations of the returned splines with appropriate Gaunt coefficients. """ lmax = l1 + l2 splines = [] R = np.arange(self.Q // 2) * self.dr R1 = R.copy() R1[0] = 1.0 k1 = self.k_q.copy() k1[0] = 1.0 a_q = phit1phit2_q for l in range(lmax % 2, lmax + 1, 2): a_g = (8 * fbt(l, a_q * k1**(-2 - lmax - l), self.k_q, R) / R1**(2 * l + 1)) if l == 0: a_g[0] = 8 * np.sum(a_q * k1**(-lmax)) * self.dk else: a_g[0] = a_g[1] # XXXX a_g *= (-1)**((l1 - l2 - l) // 2) n = len(a_g) // 256 s = Spline(l, 2 * self.rcmax, np.concatenate((a_g[::n], [0.0]))) splines.append(s) return OverlapExpansion(l1, l2, splines)
def get_compensation_charge_functions(self): assert len(self.ghat_lg) == 1 ghat_g = self.ghat_lg[0] ng = len(ghat_g) rcutcc = self.rgd.r_g[ng - 1] # correct or not? r = np.linspace(0.0, rcutcc, 50) ghat_g[-1] = 0.0 ghatnew_g = Spline(0, rcutcc, ghat_g).map(r) return r, [0], [ghatnew_g]
def get_projectors(self): # XXX equal-range projectors still required for some reason maxlen = max([len(pt_g) for pt_g in self.pt_jg]) pt_j = [] for l, pt1_g in zip(self.l_j, self.pt_jg): pt2_g = self.rgd.zeros()[:maxlen] pt2_g[:len(pt1_g)] = divrl(pt1_g, l, self.rgd.r_g[:len(pt1_g)]) spline = Spline(l, self.rgd.r_g[maxlen - 1], pt2_g) pt_j.append(spline) return pt_j
def __init__(self, alpha1=10.0, alpha2=300.0): self.alpha1 = alpha1 self.alpha2 = alpha2 self.natoms = 0 self.E = 0.0 self.Z = 1 self.Nc = 0 self.Nv = 1 self.nao = None self.pt_j = [] self.ni = 0 self.l_j = [] self.n_j = [] self.nct = Spline(0, 0.5, [0.0, 0.0, 0.0]) self.Nct = 0.0 self.N0_p = [] rc = 2.0 r_g = np.linspace(0, rc, 100) r2_g = r_g**2 self.ghat_l = [ Spline(0, rc, 4 * alpha1**1.5 / np.pi**0.5 * np.exp(-alpha1 * r2_g)) ] v_g = erf(alpha1**0.5 * r_g) - erf(alpha2**0.5 * r_g) v_g[1:] *= (4 * np.pi)**0.5 / r_g[1:] v_g[0] = 4 * (alpha1**0.5 - alpha2**0.5) self.vbar = Spline(0, rc, v_g) self.Delta_pL = np.zeros((0, 1)) self.Delta0 = -1 / (4 * np.pi)**0.5 self.lmax = 0 self.K_p = self.M_p = self.MB_p = np.zeros(0) self.M_pp = np.zeros((0, 0)) self.Kc = 0.0 self.MB = 0.0 self.M = -(alpha1 / 2 / np.pi)**0.5 self.xc_correction = None self.HubU = None self.dO_ii = np.zeros((0, 0)) self.type = 'all-electron' self.fingerprint = None self.symbol = 'H'
def __init__(self, alpha, r_g, phit_g, v0_g): self.natoms = 0 self.E = 0.0 self.Z = 1 self.Nc = 0 self.Nv = 1 self.niAO = 1 self.pt_j = [] self.ni = 0 self.l_j = [] self.nct = None self.Nct = 0.0 rc = 1.0 r2_g = np.linspace(0, rc, 100)**2 x_g = np.exp(-alpha * r2_g) x_g[-1] = 0 self.ghat_l = [Spline(0, rc, (4 * pi)**0.5 * (alpha / pi)**1.5 * x_g)] self.vbar = Spline(0, rc, (4 * pi)**0.5 * v0_g[0] * x_g) r = np.linspace(0, 4.0, 100) phit = splev(r, splrep(r_g, phit_g)) poly = np.polyfit(r[[-30,-29,-2,-1]], [0, 0, phit[-2], phit[-1]], 3) phit[-30:] -= np.polyval(poly, r[-30:]) self.phit_j = [Spline(0, 4.0, phit)] self.Delta_pL = np.zeros((0, 1)) self.Delta0 = -1 / (4 * pi)**0.5 self.lmax = 0 self.K_p = self.M_p = self.MB_p = np.zeros(0) self.M_pp = np.zeros((0, 0)) self.Kc = 0.0 self.MB = 0.0 self.M = 0.0 self.xc_correction = null_xc_correction self.HubU = None self.dO_ii = np.zeros((0, 0)) self.type = 'local' self.fingerprint = None
def get_ghat(self, lmax, alpha, r, rcut): d_l = [ _fact[l] * 2**(2 * l + 2) / sqrt(pi) / _fact[2 * l + 1] for l in range(lmax + 1) ] g = alpha**1.5 * np.exp(-alpha * r**2) g[-1] = 0.0 ghat_l = [ Spline(l, rcut, d_l[l] * alpha**l * g) for l in range(lmax + 1) ] return ghat_l
def dummy_kpt_test2(): l = 0 rcut = 6. a = 5. k_c = (0.5, 0.5, 0.5) dtype = complex r = np.arange(0., rcut, .01) ngaussians = 8 rchars = np.linspace(1., rcut / 2., ngaussians + 1)[1:] print 'rchars', rchars rchar_ref = rchars[ngaussians // 2] print 'rchar ref', rchar_ref generator = PolarizationOrbitalGenerator(rcut, gaussians=rchars) # Set up reference system #alpha_ref = 1 / (rcut/4.) ** 2. alpha_ref = 1 / rchar_ref**2. ref = QuasiGaussian(alpha_ref, rcut) norm = get_norm(r, ref(r), l) ref.renormalize(norm) gd, kpt, center = make_dummy_kpt_reference(l, ref, k_c, rcut, a, 40, dtype) psit_nG = kpt.psit_nG kpt.f_n = np.array([1.]) print 'Norm sqr', gd.integrate(psit_nG * psit_nG) #gramschmidt(gd, psit_nG) print 'Normalized norm sqr', gd.integrate(psit_nG * psit_nG) quasigaussians = [QuasiGaussian(1 / rchar**2., rcut) for rchar in rchars] y = [] for g in quasigaussians: norm = get_norm(r, g(r), l) g.renormalize(norm) y.append(g(r)) splines = [Spline(l, rcut, f_g) for f_g in y] s_kmii, S_kmii = overlaps(l, gd, splines, [kpt], spos_ac=[(.5, .5, .5)]) orbital = generator.generate(l, gd, [kpt], [center], dtype=complex) print 'coefs' print np.array(orbital.coefs) print 'quality' print generator.qualities import pylab pylab.plot(r, ref(r), label='ref') pylab.plot(r, orbital(r), label='interp') pylab.legend() pylab.show()
def ft(spline): l = spline.get_angular_momentum_number() rc = 50.0 N = 2**10 assert spline.get_cutoff() <= rc dr = rc / N r_r = np.arange(N) * dr dk = pi / 2 / rc k_q = np.arange(2 * N) * dk f_r = spline.map(r_r) * (4 * pi) f_q = fbt(l, f_r, r_r, k_q) f_q[1:] /= k_q[1:]**(2 * l + 1) f_q[0] = (np.dot(f_r, r_r**(2 + 2 * l)) * dr * 2**l * fac[l] / fac[2 * l + 1]) return Spline(l, k_q[-1], f_q)
def f(n, p): N = 2 * n gd = GridDescriptor((N, N, N), (L, L, L)) a = gd.zeros() print(a.shape) #p = PoissonSolver(nn=1, relax=relax) p.set_grid_descriptor(gd) cut = N / 2.0 * 0.9 s = Spline(l=0, rmax=cut, f_g=np.array([1, 0.5, 0.0])) c = LFC(gd, [[s], [s]]) c.set_positions([(0, 0, 0), (0.5, 0.5, 0.5)]) c.add(a) I0 = gd.integrate(a) a -= I0 / L**3 b = gd.zeros() p.solve(b, a, charge=0, eps=1e-20) return gd.collect(b, broadcast=1)
def set_grid_descriptor(self, gd): GGA.set_grid_descriptor(self, gd) self.dedmu_g = gd.zeros() self.dedbeta_g = gd.zeros() # Create gaussian LFC l_lim = 1.0e-30 rcut = 12 points = 200 r_i = np.linspace(0, rcut, points + 1) rcgauss = 1.2 g_g = (2 / rcgauss**3 / np.pi * np.exp(-((r_i / rcgauss)**2)**self.alpha)) # Values too close to zero can cause numerical problems especially with # forces (some parts of the mu and beta field can become negative) g_g[np.where(g_g < l_lim)] = l_lim spline = Spline(l=0, rmax=rcut, f_g=g_g) spline_j = [[spline]] * len(self.atoms) self.Pa = LFC(gd, spline_j)
def test(): from gpaw.grid_descriptor import GridDescriptor ngpts = 40 h = 1 / ngpts N_c = (ngpts, ngpts, ngpts) a = h * ngpts gd = GridDescriptor(N_c, (a, a, a)) from gpaw.spline import Spline a = np.array([1, 0.9, 0.8, 0.0]) s = Spline(0, 0.2, a) x = LocalizedFunctionsCollection(gd, [[s], [s]]) x.set_positions([(0.5, 0.45, 0.5), (0.5, 0.55, 0.5)]) n_G = gd.zeros() x.add(n_G) import pylab as plt plt.contourf(n_G[20, :, :]) plt.axis('equal') plt.show()
def make_dummy_reference(l, function=None, rcut=6., a=12., n=60, dtype=float): """Make a mock reference wave function using a made-up radial function as reference""" #print 'Dummy reference: l=%d, rcut=%.02f, alpha=%.02f' % (l, rcut, alpha) r = np.arange(0., rcut, .01) if function is None: function = QuasiGaussian(4., rcut) norm = get_norm(r, function(r), l) function.renormalize(norm) #g = QuasiGaussian(alpha, rcut) mcount = 2 * l + 1 fcount = 1 gd = GridDescriptor((n, n, n), (a, a, a), (False, False, False)) spline = Spline(l, r[-1], function(r), points=50) center = (.5, .5, .5) lf = create_localized_functions([spline], gd, center, dtype=dtype) psit_k = gd.zeros(mcount, dtype=dtype) coef_xi = np.identity(mcount * fcount, dtype=dtype) lf.add(psit_k, coef_xi) return gd, psit_k, center, function
def make_dummy_kpt_reference(l, function, k_c, rcut=6., a=10., n=60, dtype=complex): r = np.linspace(0., rcut, 300) mcount = 2 * l + 1 fcount = 1 kcount = 1 gd = GridDescriptor((n, n, n), (a, a, a), (True, True, True)) kpt = KPoint([], gd, 1., 0, 0, 0, k_c, dtype) spline = Spline(l, r[-1], function(r)) center = (.5, .5, .5) lf = create_localized_functions([spline], gd, center, dtype=dtype) lf.set_phase_factors([kpt.k_c]) psit_nG = gd.zeros(mcount, dtype=dtype) coef_xi = np.identity(mcount * fcount, dtype=dtype) lf.add(psit_nG, coef_xi, k=0) kpt.psit_nG = psit_nG print 'Number of boxes', len(lf.box_b) print 'Phase kb factors shape', lf.phase_kb.shape return gd, kpt, center
def spline(self, l, f_g, points=None): ng = len(f_g) rmax = self.r_g[ng - 1] r_g = self.r_g[:ng] f_g = self.equidistant(f_g, points=points) return Spline(l, rmax, f_g)
def spline(self, l, f_g): ng = len(f_g) rmax = self.r_g[ng - 1] return Spline(l, rmax, f_g)
from gpaw.test import equal from gpaw.grid_descriptor import GridDescriptor from gpaw.spline import Spline import gpaw.mpi as mpi from gpaw.lfc import LocalizedFunctionsCollection as LFC s = Spline(0, 1.0, [1.0, 0.5, 0.0]) n = 40 a = 8.0 gd = GridDescriptor((n, n, n), (a, a, a), comm=mpi.serial_comm) c = LFC(gd, [[s], [s], [s]]) c.set_positions([(0.5, 0.5, 0.25 + 0.25 * i) for i in [0, 1, 2]]) b = gd.zeros() c.add(b) x = gd.integrate(b) gd = GridDescriptor((n, n, n), (a, a, a), comm=mpi.serial_comm) c = LFC(gd, [[s], [s], [s]]) c.set_positions([(0.5, 0.5, 0.25 + 0.25 * i) for i in [0, 1, 2]]) b = gd.zeros() c.add(b) y = gd.integrate(b) equal(x, y, 1e-13)
"""BSSE: Basis Set Superposition Error module. Defines a Setup-like class which has no properties that change anything, except for an atomic basis set.""" import numpy as np from ase.data import atomic_numbers from gpaw.setup import BaseSetup from gpaw.setup_data import SetupData from gpaw.basis_data import Basis from gpaw.spline import Spline from gpaw.hgh import null_xc_correction # Some splines are mandatory, but should then be zero to avoid affecting things zero_function = Spline(0, 0.5, [0.0, 0.0, 0.0]) # Some operations fail horribly if the splines are zero, due to weird # divisions and assumptions that various quantities are nonzero # # We'll use a function which is almost zero for these things nonzero_function = Spline(0, 0.5, [0.0, 1.0e-12, 0.0]) # XXX class GhostSetup(BaseSetup): def __init__(self, basis, data): self.symbol = data.symbol self.data = data self.phit_j = basis.tosplines() self.basis = basis self.niAO = sum([
ra.seed(8) for name in ['LDA', 'PBE']: xc = XC(name) s = create_setup('N', xc) ni = s.ni nao = s.nao wt0_j = s.phit_j rcut = s.xc_correction.rgd.r_g[-1] wt_j = [] for wt0 in wt0_j: data = [wt0(r) for r in np.arange(121) * rcut / 100] data[-1] = 0.0 l = wt0.get_angular_momentum_number() wt_j.append(Spline(l, 1.2 * rcut, data)) a = rcut * 1.2 * 2 + 1.0 ## n = 120 n = 70 n = 90 gd = GridDescriptor((n, n, n), (a, a, a), comm=serial_comm) pr = create_localized_functions(wt_j, gd, (0.5, 0.5, 0.5)) coefs = np.identity(nao, float) psit_ig = np.zeros((nao, n, n, n)) pr.add(psit_ig, coefs) nii = ni * (ni + 1) // 2 D_p = np.zeros(nii) H_p = np.zeros(nii)
def dummy_kpt_test(): l = 0 rcut = 6. a = 5. k_kc = [(.5, .5, .5)] #[(0., 0., 0.), (0.5, 0.5, 0.5)] kcount = len(k_kc) dtype = complex r = np.arange(0., rcut, .01) spos_ac_ref = [(0., 0., 0.)] #, (.2, .2, .2)] spos_ac = [(0., 0., 0.), (.2, .2, .2)] ngaussians = 4 realgaussindex = (ngaussians - 1) / 2 rchars = np.linspace(1., rcut, ngaussians) splines = [] gaussians = [QuasiGaussian(1. / rch**2., rcut) for rch in rchars] for g in gaussians: norm = get_norm(r, g(r), l) g.renormalize(norm) spline = Spline(l, r[-1], g(r)) splines.append(spline) refgauss = gaussians[realgaussindex] refspline = splines[realgaussindex] gd = GridDescriptor((60, 60, 60), (a, a, a), (1, 1, 1)) reflf_a = [ create_localized_functions([refspline], gd, spos_c, dtype=dtype) for spos_c in spos_ac_ref ] for reflf in reflf_a: reflf.set_phase_factors(k_kc) kpt_u = [ KPoint([], gd, 1., 0, k, k, k_c, dtype) for k, k_c in enumerate(k_kc) ] for kpt in kpt_u: kpt.allocate(1) kpt.f_n[0] = 1. psit_nG = gd.zeros(1, dtype=dtype) coef_xi = np.identity(1, dtype=dtype) integral = np.zeros((1, 1), dtype=dtype) for reflf in reflf_a: reflf.add(psit_nG, coef_xi, k=kpt.k) reflf.integrate(psit_nG, integral, k=kpt.k) kpt.psit_nG = psit_nG print 'ref norm', integral print 'calculating overlaps' os_kmii, oS_kmii = overlaps(l, gd, splines, kpt_u, spos_ac=spos_ac_ref) print 'done' lf_a = [ create_localized_functions(splines, gd, spos_c, dtype=dtype) for spos_c in spos_ac ] for lf in lf_a: lf.set_phase_factors(k_kc) s_kii = np.zeros((kcount, ngaussians, ngaussians), dtype=dtype) S_kii = np.zeros((kcount, ngaussians, ngaussians), dtype=dtype) for kpt in kpt_u: k = kpt.k all_integrals = np.zeros((1, ngaussians), dtype=dtype) tempgrids = gd.zeros(ngaussians, dtype=dtype) tempcoef_xi = np.identity(ngaussians, dtype=dtype) for lf in lf_a: lf.integrate(kpt.psit_nG, all_integrals, k=k) lf.add(tempgrids, tempcoef_xi, k=k) lf.integrate(tempgrids, s_kii[k], k=k) print 'all <phi|psi>' print all_integrals conj_integrals = np.conj(all_integrals) for i in range(ngaussians): for j in range(ngaussians): S_kii[k, i, j] = conj_integrals[0, i] * all_integrals[0, j] print 'handmade s_kmii' print s_kii print 'handmade S_ii' print S_kii s_kmii = s_kii.reshape(kcount, 1, ngaussians, ngaussians) S_kmii = S_kii.reshape(kcount, 1, ngaussians, ngaussians) print 'matrices from overlap function' print 's_kmii' print os_kmii print 'S_kmii' print oS_kmii optimizer = CoefficientOptimizer(s_kmii, S_kmii, ngaussians) coefficients = optimizer.find_coefficients() optimizer2 = CoefficientOptimizer(os_kmii, oS_kmii, ngaussians) coefficients2 = optimizer2.find_coefficients() print 'coefs' print coefficients print 'overlaps() coefs' print coefficients2 print 'badness' print optimizer.evaluate(coefficients) exactsolution = [0.] * ngaussians exactsolution[realgaussindex] = 1. print 'badness of exact solution' print optimizer.evaluate(exactsolution) orbital = LinearCombination(coefficients, gaussians) orbital2 = LinearCombination(coefficients2, gaussians) norm = get_norm(r, orbital(r), l) norm2 = get_norm(r, orbital2(r), l) orbital.renormalize(norm) orbital2.renormalize(norm2) import pylab pylab.plot(r, refgauss(r), label='ref') pylab.plot(r, orbital(r), label='opt') pylab.plot(r, orbital2(r), '--', label='auto') pylab.legend() pylab.show()
from gpaw.spline import Spline import numpy as np a = np.array([1, 0.9, 0.1, 0.0]) s = Spline(0, 2.0, a) dx = 0.0001 for x in [0.5, 1, 1.2, 3]: y, dydx = s.get_value_and_derivative(x) z = (s(x + dx) - s(x - dx)) / (2 * dx) print y, dydx - z assert abs(dydx - z) < 1e-7
import numpy as np from gpaw.atom.atompaw import AtomPAW from gpaw.utilities import erf from gpaw.setup import BaseSetup from gpaw.spline import Spline from gpaw.basis_data import Basis, BasisFunction null_spline = Spline(0, 1.0, [0., 0., 0.]) def screen_potential(r, v, charge, rcut=None, a=None): """Split long-range potential into short-ranged contributions. The potential v is a long-ranted potential with the asymptotic form Z/r corresponding to the given charge. Return a potential vscreened and charge distribution rhocomp such that v(r) = vscreened(r) + vHartree[rhocomp](r). The returned quantities are truncated to a reasonable cutoff radius. """ vr = v * r + charge if rcut is None: err = 0.0 i = len(vr) while err < 1e-5: # Things can be a bit sensitive to the threshold. The O.pz-mt # setup gets 20-30 Bohr long compensation charges if it's 1e-6.
def get_projections(self, locfun, spin=0): """Project wave functions onto localized functions Determine the projections of the Kohn-Sham eigenstates onto specified localized functions of the format:: locfun = [[spos_c, l, sigma], [...]] spos_c can be an atom index, or a scaled position vector. l is the angular momentum, and sigma is the (half-) width of the radial gaussian. Return format is:: f_kni = <psi_kn | f_i> where psi_kn are the wave functions, and f_i are the specified localized functions. As a special case, locfun can be the string 'projectors', in which case the bound state projectors are used as localized functions. """ wfs = self.wfs if locfun == 'projectors': f_kin = [] for kpt in wfs.kpt_u: if kpt.s == spin: f_in = [] for a, P_ni in kpt.P_ani.items(): i = 0 setup = wfs.setups[a] for l, n in zip(setup.l_j, setup.n_j): if n >= 0: for j in range(i, i + 2 * l + 1): f_in.append(P_ni[:, j]) i += 2 * l + 1 f_kin.append(f_in) f_kni = np.array(f_kin).transpose(0, 2, 1) return f_kni.conj() from gpaw.lfc import LocalizedFunctionsCollection as LFC from gpaw.spline import Spline from gpaw.utilities import _fact nkpts = len(wfs.ibzk_kc) nbf = np.sum([2 * l + 1 for pos, l, a in locfun]) f_kni = np.zeros((nkpts, wfs.nbands, nbf), wfs.dtype) spos_ac = self.atoms.get_scaled_positions() % 1.0 spos_xc = [] splines_x = [] for spos_c, l, sigma in locfun: if isinstance(spos_c, int): spos_c = spos_ac[spos_c] spos_xc.append(spos_c) alpha = .5 * Bohr**2 / sigma**2 r = np.linspace(0, 6. * sigma, 500) f_g = (_fact[l] * (4 * alpha)**(l + 3 / 2.) * np.exp(-alpha * r**2) / (np.sqrt(4 * np.pi) * _fact[2 * l + 1])) splines_x.append([Spline(l, rmax=r[-1], f_g=f_g, points=61)]) lf = LFC(wfs.gd, splines_x, wfs.kpt_comm, dtype=wfs.dtype) if not wfs.gamma: lf.set_k_points(wfs.ibzk_qc) lf.set_positions(spos_xc) k = 0 f_ani = lf.dict(wfs.nbands) for kpt in wfs.kpt_u: if kpt.s != spin: continue lf.integrate(kpt.psit_nG[:], f_ani, kpt.q) i1 = 0 for x, f_ni in f_ani.items(): i2 = i1 + f_ni.shape[1] f_kni[k, :, i1:i2] = f_ni i1 = i2 k += 1 return f_kni.conj()
def spline(self, a_g, rcut=None, l=0, points=None): b_g = a_g.copy() if l > 0: b_g = divrl(b_g, l, self.r_g[:len(a_g)]) return Spline(l, self.r_g[len(a_g) - 1], b_g)
"""BSSE: Basis Set Superposition Error module. Defines a Setup-like class which has no properties that change anything, except for an atomic basis set.""" import numpy as np from ase.data import atomic_numbers from gpaw.setup import BaseSetup, LocalCorrectionVar from gpaw.spline import Spline from gpaw.utilities import min_locfun_radius # Some splines are mandatory, # but should then be zero to avoid affecting things zero_function = Spline(0, min_locfun_radius, [0.0, 0.0, 0.0]) # Some operations fail horribly if the splines are zero, due to weird # divisions and assumptions that various quantities are nonzero # # We'll use a function which is almost zero for these things nonzero_function = Spline(0, min_locfun_radius, [0.0, 1.0e-12, 0.0]) # XXX class GhostSetup(BaseSetup): def __init__(self, basis, data): self.symbol = data.symbol self.data = data self.phit_j = basis.tosplines() self.basis = basis self.nao = sum([ 2 * phit.get_angular_momentum_number() + 1 for phit in self.phit_j
from gpaw.setup import Setup from gpaw.gaunt import gaunt as G_LLL from gpaw.spherical_harmonics import Y from gpaw.response.math_func import two_phi_planewave_integrals # Initialize s, p, d (9 in total) wave and put them on grid rc = 2.0 a = 2.5 * rc n = 64 lmax = 2 b = 8.0 m = (lmax + 1)**2 gd = GridDescriptor([n, n, n], [a, a, a]) r = np.linspace(0, rc, 200) g = np.exp(-(r / rc * b)**2) splines = [Spline(l=l, rmax=rc, f_g=g) for l in range(lmax + 1)] c = LFC(gd, [splines]) c.set_positions([(0.5, 0.5, 0.5)]) psi = gd.zeros(m) d0 = c.dict(m) if 0 in d0: d0[0] = np.identity(m) c.add(psi, d0) # Calculate on 3d-grid < phi_i | e**(-ik.r) | phi_j > R_a = np.array([a / 2, a / 2, a / 2]) rr = gd.get_grid_point_coordinates() for dim in range(3): rr[dim] -= R_a[dim] k_G = np.array([[11., 0.2, 0.1], [10., 0., 10.]])
def __init__(self, data, basis=None): self.data = data self.R_sii = None self.HubU = None self.lq = None self.filename = None self.fingerprint = None self.symbol = data.symbol self.type = data.name self.Z = data.Z self.Nv = data.Nv self.Nc = data.Nc self.f_j = data.f_j self.n_j = data.n_j self.l_j = data.l_j self.l_orb_j = data.l_orb_j self.nj = len(data.l_j) self.ni = sum([2 * l + 1 for l in data.l_j]) self.pt_j = data.get_projectors() if len(self.pt_j) == 0: assert False # not sure yet about the consequences of # cleaning this up in the other classes self.l_j = [0] self.pt_j = [null_spline] if basis is None: basis = data.create_basis_functions() self.phit_j = basis.tosplines() self.basis = basis self.nao = sum([2 * phit.get_angular_momentum_number() + 1 for phit in self.phit_j]) self.Nct = 0.0 self.nct = null_spline self.lmax = 0 self.xc_correction = None r, l_comp, g_comp = data.get_compensation_charge_functions() self.ghat_l = [Spline(l, r[-1], g) for l, g in zip(l_comp, g_comp)] self.rcgauss = data.rcgauss # accuracy is rather sensitive to this self.vbar = data.get_local_potential() _np = self.ni * (self.ni + 1) // 2 self.Delta0 = data.Delta0 self.Delta_pL = np.zeros((_np, 1)) self.E = 0.0 self.Kc = 0.0 self.M = 0.0 self.M_p = np.zeros(_np) self.M_pp = np.zeros((_np, _np)) self.K_p = data.expand_hamiltonian_matrix() self.MB = 0.0 self.MB_p = np.zeros(_np) self.dO_ii = np.zeros((self.ni, self.ni)) # We don't really care about these variables self.rcutfilter = None self.rcore = None self.N0_p = np.zeros(_np) # not really implemented self.nabla_iiv = None self.rnabla_iiv = None self.rxp_iiv = None self.phicorehole_g = None self.rgd = data.rgd self.rcut_j = data.rcut_j self.tauct = None self.Delta_iiL = None self.B_ii = None self.dC_ii = None self.X_p = None self.ExxC = None self.dEH0 = 0.0 self.dEH_p = np.zeros(_np) self.extra_xc_data = {} self.wg_lg = None self.g_lg = None
def get_local_potential(self): vbar = Spline(0, self.rgd.r_g[len(self.vbar_g) - 1], self.vbar_g) return vbar