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 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 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
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) e_g = np.zeros((n, n, n)) n_g = np.zeros((1, n, n, n)) v_g = np.zeros((1, n, n, n)) P_ni = 0.2 * ra.random((20, ni)) P_ni[:, nao:] = 0.0
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(niAO, float) psit_ig = np.zeros((niAO, n, n, n)) pr.add(psit_ig, coefs) nii = ni * (ni + 1) // 2 D_p = np.zeros(nii) H_p = np.zeros(nii) e_g = np.zeros((n, n, n)) n_g = np.zeros((1, n, n, n)) v_g = np.zeros((1, n, n, n)) P_ni = 0.2 * ra.random((20, ni))
from gpaw.setup import create_setup from gpaw.grid_descriptor import GridDescriptor from gpaw.localized_functions import create_localized_functions from gpaw.xc import XC n = 60 #40 /8 * 10 a = 10.0 gd = GridDescriptor((n, n, n), (a, a, a)) c_LL = np.identity(9, float) a_Lg = gd.zeros(9) nspins = 2 xc = XC('LDA') for soft in [False]: s = create_setup('Cu', xc, lmax=2) ghat_l = s.ghat_l ghat_Lg = create_localized_functions(ghat_l, gd, (0.54321, 0.5432, 0.543)) a_Lg[:] = 0.0 ghat_Lg.add(a_Lg, c_LL) for l in range(3): for m in range(2 * l + 1): L = l**2 + m a_g = a_Lg[L] Q0 = gd.integrate(a_g) / sqrt(4 * pi) Q1_m = -gd.calculate_dipole_moment(a_g) / sqrt(4 * pi / 3) print(Q0) if l == 0: Q0 -= 1.0 Q1_m[:] = 0.0 elif l == 1: Q1_m[(m + 1) % 3] -= 1.0 print(soft, l, m, Q0, Q1_m)
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()
def old_overlaps(l, gd, splines, kpt_u, center=(.5, .5, .5)): """Get scalar products of basis functions and references. Returns the triple-indexed matrices s and S, where:: s = < phi | phi > , mij mi mj ----- \ / | ~ \ / ~ | \ S = ) ( phi | psi ) ( psi | phi ) mij / \ mi | k / \ k | mj / ----- k The functions phi are taken from the given splines, whereas psit must be on the grid represented by the GridDescriptor gd. Integrals are evaluated at the relative location given by center. """ raise DeprecationWarning('Use overlaps method') # This method will be deleted, but presently we want to keep it # for testing assert len(kpt_u) == 1, 'This method only works for one k-point' kpt = kpt_u[0] psit_k = kpt.psit_nG mcounts = [spline.get_angular_momentum_number() for spline in splines] mcount = mcounts[0] for mcount_i in mcounts: assert mcount == mcount_i mcount = 2 * l + 1 fcount = len(splines) phi_lf = create_localized_functions(splines, gd, center) #print 'loc funcs boxes',len(phi_lf.box_b) phi_mi = gd.zeros(fcount * mcount) # one set for each phi coef_xi = np.identity(fcount * mcount) phi_lf.add(phi_mi, coef_xi) integrals = np.zeros((fcount * mcount, fcount * mcount)) phi_lf.integrate(phi_mi, integrals) """Integral matrix contents (assuming l==1 so there are three m-values) --phi1-- --phi2-- --phi3-- ... m1 m2 m3 m1 m2 m3 m1 m2 m3 ... +--------------------------------- | | m1| x 0 0 x 0 0 phi1 m2| 0 x 0 0 x 0 ... | m3| 0 0 x 0 0 x | | m1| . phi2 m2| . | m3| . . | . We want < phi_mi | phi_mj >, and thus only the diagonal elements of each submatrix! For l=1 the diagonal elements are all equal, but this is not true in general""" # phiproducts: for each m, < phi_mi | phi_mj > phiproducts_mij = np.zeros((mcount, fcount, fcount)) for i in range(fcount): for j in range(fcount): ioff = mcount * i joff = mcount * j submatrix_ij = integrals[ioff:ioff + mcount, joff:joff + mcount] phiproducts_mij[:, i, j] = submatrix_ij.diagonal() # This should be ones in submatrix diagonals and zero elsewhere # Now calculate scalar products < phi_mi | psit_k >, where psit_k are # solutions from reference calculation psitcount = len(psit_k) integrals_kim = np.zeros((psitcount, fcount * mcount)) phi_lf.integrate(psit_k, integrals_kim) # Now psiproducts[k] is a flat list, but we want it to be a matrix with # dimensions corresponding to f and m. # The first three elements correspond to the same localized function # and so on. # What we want is one whole matrix for each m-value. psiproducts_mik = np.zeros((mcount, fcount, psitcount)) for m in range(mcount): for i in range(fcount): for k in range(psitcount): w = kpt.f_n[k] * kpt.weight psiproducts_mik[m, i, k] = w * integrals_kim[k, mcount * i + m] # s[mij] = < phi_mi | phi_mj > s = np.array([phiproducts_mij]) # S[mij] = sum over k: < phi_mi | psit_k > < psit_k | phi_mj > S = np.array([[ np.dot(psiproducts_ik, np.transpose(psiproducts_ik)) for psiproducts_ik in psiproducts_mik ]]) return s, S
def overlaps(l, gd, splines, kpt_u, spos_ac=((.5, .5, .5), ), txt=devnull): """Get scalar products of basis functions and references. Returns the quadruple-indexed matrices s and S, where:: s = < phi | phi > , kmij kmi kmj ----- \ / | ~ \ / ~ | \ S = ) ( phi | psi ) ( psi | phi ) kmij / \ mi | n / \ n | mj / ----- n The functions phi are taken from the given splines, whereas psit must be on the grid represented by the GridDescriptor gd. Integrals are evaluated at the relative location given by center. """ if txt == '-': txt = sys.stdout # XXX spos_c = spos_ac[0] assert len(spos_ac) == 1, str(spos_c) mcount = 2 * l + 1 fcount = len(splines) kcount = len(kpt_u) bcount = kpt_u[0].psit_nG.shape[0] dtype = kpt_u[0].dtype print >> txt, 'Creating localized functions' lf = create_localized_functions(splines, gd, spos_c, dtype=dtype) k_kc = [kpt.k_c for kpt in kpt_u] if dtype == complex: lf.set_phase_factors(k_kc) # make sanity checks for kpt in kpt_u: assert kpt.psit_nG.shape[0] == bcount # same band count for all kpts assert [kpt.dtype for kpt in kpt_u].count(dtype) == kcount # same dtype lvalues = [spline.get_angular_momentum_number() for spline in splines] assert lvalues.count(l) == len(lvalues) # all l must be equal # First we have to calculate the scalar products between # pairs of basis functions < phi_kmi | phi_kmj >. s_kmii = np.zeros((kcount, mcount, fcount, fcount), dtype=dtype) coef_xi = np.identity(mcount * fcount, dtype=dtype) #phi_miG = gd.zeros(mcount * fcount, dtype=dtype) print >> txt, 'Calculating phi-phi products' for kpt in kpt_u: gramschmidt(gd, kpt.psit_nG) normsqr = gd.integrate(np.conjugate(kpt.psit_nG) * kpt.psit_nG) for n in range(bcount): kpt.psit_nG[n] /= normsqr[n]**.5 phi_nG = gd.zeros(mcount * fcount, dtype=dtype) #for lf in lf_a: # lf.add(phi_nG, coef_xi, k=kpt.k) lf.add(phi_nG, coef_xi, k=kpt.k) phi_overlaps_ii = np.zeros((fcount * mcount, fcount * mcount), dtype=dtype) # XXX products for different m unneeded. Bottleneck for large fcount lf.integrate(phi_nG, phi_overlaps_ii, k=kpt.k) #for lf in lf_a: # # every integration will add to the result array # lf.integrate(phi_nG, phi_overlaps_ii, k=kpt.k) phi_overlaps_ii.shape = (fcount, mcount, fcount, mcount) for m in range(mcount): for i in range(fcount): for j in range(fcount): s_kmii[kpt.u, m, i, j] = phi_overlaps_ii[i, m, j, m] # Now calculate scalar products between basis functions and # reference functions < phi_kmi | psi_kn >. overlaps_knmi = np.zeros((kcount, bcount, mcount, fcount), dtype=dtype) print >> txt, 'Calculating phi-psi products' for kpt in kpt_u: # Note: will be reashaped to (n, i, m) like its name suggests overlaps_nim = np.zeros((bcount, mcount * fcount), dtype=dtype) lf.integrate(kpt.psit_nG, overlaps_nim, k=kpt.k) overlaps_nim.shape = (bcount, fcount, mcount) overlaps_knmi[kpt.u, :, :, :] = overlaps_nim.swapaxes(1, 2) print >> txt, 'Aligning matrices' for k in range(kcount): f_n = kpt_u[k].f_n # Apply weights depending on occupation for n in range(bcount): # if n == bcount -1: # w = 1.#f_n[n] # else: # w = 0. overlaps_knmi[k, n, :, :] *= f_n[n] S_kmii = np.zeros((kcount, mcount, fcount, fcount), dtype=dtype) conj_overlaps_knmi = overlaps_knmi.conjugate() for k in range(kcount): for m in range(mcount): for i in range(fcount): for j in range(fcount): x1 = conj_overlaps_knmi[k, :, m, i] x2 = overlaps_knmi[k, :, m, j] S_kmii[k, m, i, j] = (x1 * x2).sum() assert s_kmii.shape == S_kmii.shape return s_kmii, S_kmii
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()
def old_overlaps(l, gd, splines, kpt_u, center=(.5, .5, .5)): """Get scalar products of basis functions and references. Returns the triple-indexed matrices s and S, where:: s = < phi | phi > , mij mi mj ----- \ / | ~ \ / ~ | \ S = ) ( phi | psi ) ( psi | phi ) mij / \ mi | k / \ k | mj / ----- k The functions phi are taken from the given splines, whereas psit must be on the grid represented by the GridDescriptor gd. Integrals are evaluated at the relative location given by center. """ raise DeprecationWarning('Use overlaps method') # This method will be deleted, but presently we want to keep it # for testing assert len(kpt_u) == 1, 'This method only works for one k-point' kpt = kpt_u[0] psit_k = kpt.psit_nG mcounts = [spline.get_angular_momentum_number() for spline in splines] mcount = mcounts[0] for mcount_i in mcounts: assert mcount == mcount_i mcount = 2*l + 1 fcount = len(splines) phi_lf = create_localized_functions(splines, gd, center) #print 'loc funcs boxes',len(phi_lf.box_b) phi_mi = gd.zeros(fcount * mcount) # one set for each phi coef_xi = np.identity(fcount * mcount) phi_lf.add(phi_mi, coef_xi) integrals = np.zeros((fcount * mcount, fcount * mcount)) phi_lf.integrate(phi_mi, integrals) """Integral matrix contents (assuming l==1 so there are three m-values) --phi1-- --phi2-- --phi3-- ... m1 m2 m3 m1 m2 m3 m1 m2 m3 ... +--------------------------------- | | m1| x 0 0 x 0 0 phi1 m2| 0 x 0 0 x 0 ... | m3| 0 0 x 0 0 x | | m1| . phi2 m2| . | m3| . . | . We want < phi_mi | phi_mj >, and thus only the diagonal elements of each submatrix! For l=1 the diagonal elements are all equal, but this is not true in general""" # phiproducts: for each m, < phi_mi | phi_mj > phiproducts_mij = np.zeros((mcount, fcount, fcount)) for i in range(fcount): for j in range(fcount): ioff = mcount * i joff = mcount * j submatrix_ij = integrals[ioff:ioff + mcount,joff:joff + mcount] phiproducts_mij[:, i, j] = submatrix_ij.diagonal() # This should be ones in submatrix diagonals and zero elsewhere # Now calculate scalar products < phi_mi | psit_k >, where psit_k are # solutions from reference calculation psitcount = len(psit_k) integrals_kim = np.zeros((psitcount, fcount * mcount)) phi_lf.integrate(psit_k, integrals_kim) # Now psiproducts[k] is a flat list, but we want it to be a matrix with # dimensions corresponding to f and m. # The first three elements correspond to the same localized function # and so on. # What we want is one whole matrix for each m-value. psiproducts_mik = np.zeros((mcount, fcount, psitcount)) for m in range(mcount): for i in range(fcount): for k in range(psitcount): w = kpt.f_n[k] * kpt.weight psiproducts_mik[m, i, k] = w * integrals_kim[k, mcount * i + m] # s[mij] = < phi_mi | phi_mj > s = np.array([phiproducts_mij]) # S[mij] = sum over k: < phi_mi | psit_k > < psit_k | phi_mj > S = np.array([[np.dot(psiproducts_ik, np.transpose(psiproducts_ik)) for psiproducts_ik in psiproducts_mik]]) return s, S
def overlaps(l, gd, splines, kpt_u, spos_ac=((.5, .5, .5),), txt=devnull): """Get scalar products of basis functions and references. Returns the quadruple-indexed matrices s and S, where:: s = < phi | phi > , kmij kmi kmj ----- \ / | ~ \ / ~ | \ S = ) ( phi | psi ) ( psi | phi ) kmij / \ mi | n / \ n | mj / ----- n The functions phi are taken from the given splines, whereas psit must be on the grid represented by the GridDescriptor gd. Integrals are evaluated at the relative location given by center. """ if txt == '-': txt = sys.stdout # XXX spos_c = spos_ac[0] assert len(spos_ac) == 1, str(spos_c) mcount = 2 * l + 1 fcount = len(splines) kcount = len(kpt_u) bcount = kpt_u[0].psit_nG.shape[0] dtype = kpt_u[0].dtype print >> txt, 'Creating localized functions' lf = create_localized_functions(splines, gd, spos_c, dtype=dtype) k_kc = [kpt.k_c for kpt in kpt_u] if dtype == complex: lf.set_phase_factors(k_kc) # make sanity checks for kpt in kpt_u: assert kpt.psit_nG.shape[0] == bcount # same band count for all kpts assert [kpt.dtype for kpt in kpt_u].count(dtype) == kcount # same dtype lvalues = [spline.get_angular_momentum_number() for spline in splines] assert lvalues.count(l) == len(lvalues) # all l must be equal # First we have to calculate the scalar products between # pairs of basis functions < phi_kmi | phi_kmj >. s_kmii = np.zeros((kcount, mcount, fcount, fcount), dtype=dtype) coef_xi = np.identity(mcount * fcount, dtype=dtype) #phi_miG = gd.zeros(mcount * fcount, dtype=dtype) print >> txt, 'Calculating phi-phi products' for kpt in kpt_u: gramschmidt(gd, kpt.psit_nG) normsqr = gd.integrate(np.conjugate(kpt.psit_nG) * kpt.psit_nG) for n in range(bcount): kpt.psit_nG[n] /= normsqr[n] ** .5 phi_nG = gd.zeros(mcount * fcount, dtype=dtype) #for lf in lf_a: # lf.add(phi_nG, coef_xi, k=kpt.k) lf.add(phi_nG, coef_xi, k=kpt.k) phi_overlaps_ii = np.zeros((fcount * mcount, fcount * mcount), dtype=dtype) # XXX products for different m unneeded. Bottleneck for large fcount lf.integrate(phi_nG, phi_overlaps_ii, k=kpt.k) #for lf in lf_a: # # every integration will add to the result array # lf.integrate(phi_nG, phi_overlaps_ii, k=kpt.k) phi_overlaps_ii.shape = (fcount, mcount, fcount, mcount) for m in range(mcount): for i in range(fcount): for j in range(fcount): s_kmii[kpt.u, m, i, j] = phi_overlaps_ii[i, m, j, m] # Now calculate scalar products between basis functions and # reference functions < phi_kmi | psi_kn >. overlaps_knmi = np.zeros((kcount, bcount, mcount, fcount), dtype=dtype) print >> txt, 'Calculating phi-psi products' for kpt in kpt_u: # Note: will be reashaped to (n, i, m) like its name suggests overlaps_nim = np.zeros((bcount, mcount * fcount), dtype=dtype) lf.integrate(kpt.psit_nG, overlaps_nim, k=kpt.k) overlaps_nim.shape = (bcount, fcount, mcount) overlaps_knmi[kpt.u, :, :, :] = overlaps_nim.swapaxes(1, 2) print >> txt, 'Aligning matrices' for k in range(kcount): f_n = kpt_u[k].f_n # Apply weights depending on occupation for n in range(bcount): # if n == bcount -1: # w = 1.#f_n[n] # else: # w = 0. overlaps_knmi[k, n, :, :] *= f_n[n] S_kmii = np.zeros((kcount, mcount, fcount, fcount), dtype=dtype) conj_overlaps_knmi = overlaps_knmi.conjugate() for k in range(kcount): for m in range(mcount): for i in range(fcount): for j in range(fcount): x1 = conj_overlaps_knmi[k, :, m, i] x2 = overlaps_knmi[k, :, m, j] S_kmii[k, m, i, j] = (x1 * x2).sum() assert s_kmii.shape == S_kmii.shape return s_kmii, S_kmii
from gpaw.setup import create_setup from gpaw.grid_descriptor import GridDescriptor from gpaw.localized_functions import create_localized_functions from gpaw.xc import XC n = 60#40 /8 * 10 a = 10.0 gd = GridDescriptor((n, n, n), (a, a, a)) c_LL = np.identity(9, float) a_Lg = gd.zeros(9) nspins = 2 xc = XC('LDA') for soft in [False]: s = create_setup('Cu', xc, lmax=2) ghat_l = s.ghat_l ghat_Lg = create_localized_functions(ghat_l, gd, (0.54321, 0.5432, 0.543)) a_Lg[:] = 0.0 ghat_Lg.add(a_Lg, c_LL) for l in range(3): for m in range(2 * l + 1): L = l**2 + m a_g = a_Lg[L] Q0 = gd.integrate(a_g) / sqrt(4 * pi) Q1_m = -gd.calculate_dipole_moment(a_g) / sqrt(4 * pi / 3) print Q0 if l == 0: Q0 -= 1.0 Q1_m[:] = 0.0 elif l == 1: Q1_m[(m + 1) % 3] -= 1.0 print soft, l, m, Q0, Q1_m
from __future__ import print_function import numpy as np from gpaw.grid_descriptor import GridDescriptor from gpaw.localized_functions import create_localized_functions from gpaw.spline import Spline s=Spline(0, 1.2, [1, 0.6, 0.1, 0.0]) a = 4.0 n = 24 gd = GridDescriptor((n, n, n), (a, a, a)) print(gd.get_boxes((0, 0, 0), 1.2, 0)) if 0: p = create_localized_functions([s], gd, (0.0, 0.0, 0.0), cut=True) a = np.zeros((n, n, n)) p.add(a, np.array([2.0])) print(a[1,0])