def __init__(self, ecut, diagksl, orthoksl, initksl, gd, nvalence, setups, bd, world, kd, timer): self.ecut = ecut / units.Hartree # Set dtype=complex and gamma=False: kd.gamma = False FDPWWaveFunctions.__init__(self, diagksl, orthoksl, initksl, gd, nvalence, setups, bd, complex, world, kd, timer) orthoksl.gd = self.pd self.matrixoperator = MatrixOperator(orthoksl) self.wd = self.pd
def __init__(self, stencil, diagksl, orthoksl, initksl, gd, nvalence, setups, bd, dtype, world, kd, kptband_comm, timer): FDPWWaveFunctions.__init__(self, diagksl, orthoksl, initksl, gd, nvalence, setups, bd, dtype, world, kd, kptband_comm, timer) # Kinetic energy operator: self.kin = Laplace(self.gd, -0.5, stencil, self.dtype) self.matrixoperator = MatrixOperator(self.orthoksl) self.taugrad_v = None # initialized by MGGA functional
def __init__(self, ecut, fftwflags, diagksl, orthoksl, initksl, gd, nvalence, setups, bd, dtype, world, kd, kptband_comm, timer): self.ecut = ecut self.fftwflags = fftwflags self.ng_k = None # number of G-vectors for all IBZ k-points FDPWWaveFunctions.__init__(self, diagksl, orthoksl, initksl, gd, nvalence, setups, bd, dtype, world, kd, kptband_comm, timer) self.orthoksl.gd = self.pd self.matrixoperator = MatrixOperator(self.orthoksl)
def run(psit_mG): overlap = MatrixOperator(ksl, K) if 0: overlap.work1_xG = work1_xG overlap.work2_xG = work2_xG #S_nn = np.empty((N, N)) def S(x): return x dS_aii = {0: np.ones((2, 2)) * 0.123, 1: np.ones((3, 3)) * 0.321} def dS(a, P_ni): return np.dot(P_ni, dS_aii[a]) S_nn = overlap.calculate_matrix_elements(psit_mG, P_ani, S, dS) t1 = time() if world.rank == 0: print(S_nn.round(5)) inverse_cholesky(S_nn) C_nn = S_nn t2 = time() if world.rank == 0: print('Cholesky Time %f' % (t2 - t1)) # Distribute matrix: world.broadcast(C_nn, 0) psit_mG = overlap.matrix_multiply(C_nn, psit_mG, P_ani) if world.rank == 0: print('Made it past matrix multiply') # Check: S_nn = overlap.calculate_matrix_elements(psit_mG, P_ani, S, dS) assert not (P_ani[0] - psit_mG[:, :2, 0, 0]).round(10).any() assert not (P_ani[1] - psit_mG[:, -1, -1, -3:]).round(10).any() if world.rank == 0: for n in range(N): assert abs(S_nn[n, n] - 1.0) < 1e-10 assert not S_nn[n + 1:, n].round(10).any() return psit_mG
def run(psit_mG): overlap = MatrixOperator(ksl, J) def H(psit_xG): Htpsit_xG = np.empty_like(psit_xG) kin(psit_xG, Htpsit_xG) for psit_G, y_G in zip(psit_xG, Htpsit_xG): y_G += vt_G * psit_G return Htpsit_xG dH_aii = {0: np.ones((2, 2)) * 0.123, 1: np.ones((3, 3)) * 0.321} def dH(a, P_ni): return np.dot(P_ni, dH_aii[a]) H_nn = overlap.calculate_matrix_elements(psit_mG, P_ani, H, dH) t1 = time() if world.rank == 0: eps_n, H_nn = np.linalg.eigh(H_nn) H_nn = np.ascontiguousarray(H_nn.T) t2 = time() if world.rank == 0: print('Diagonalization Time %f' % (t2 - t1)) print(eps_n) # Distribute matrix: world.broadcast(H_nn, 0) psit_mG = overlap.matrix_multiply(H_nn, psit_mG, P_ani) if world.rank == 0: print('Made it past matrix multiply') # Check: assert not (P_ani[0] - psit_mG[:, :2, 0, 0]).round(10).any() assert not (P_ani[1] - psit_mG[:, -1, -1, -3:]).round(10).any() H_nn = overlap.calculate_matrix_elements(psit_mG, P_ani, H, dH) if world.rank == 0: for n in range(N): assert abs(H_nn[n, n] - eps_n[n]) < 2e-8 assert not H_nn[n + 1:, n].round(8).any() return psit_mG
def __init__(self, stencil, diagksl, orthoksl, initksl, gd, nvalence, setups, bd, dtype, world, kd, timer=None): FDPWWaveFunctions.__init__(self, diagksl, orthoksl, initksl, gd, nvalence, setups, bd, dtype, world, kd, timer) self.wd = self.gd # wave function descriptor # Kinetic energy operator: self.kin = Laplace(self.gd, -0.5, stencil, self.dtype, allocate=False) self.matrixoperator = MatrixOperator(orthoksl)
def dscf_kpoint_overlaps(paw, phasemod=True, broadcast=True): bd = paw.wfs.bd gd = paw.wfs.gd kd = paw.wfs.kd operator = MatrixOperator(paw.wfs.orthoksl, hermitian=False) atoms = paw.get_atoms() # Find the kpoint with lowest kpt.k_c (closest to gamma point) k0 = np.argmin(np.sum(paw.wfs.kd.ibzk_kc**2,axis=1)**0.5) # Maintain list of a single global reference kpoint for each spin kpt0_s = [] for s0 in range(kd.nspins): q0 = k0 - kd.get_offset() % kd.nibzkpts kpt0 = GlobalKPoint(None, s0, k0, q0, None) kpt0.update(paw.wfs) kpt0_s.append(kpt0) if phasemod: # Scaled grid point positions used for exponential with ibzk_kc # cf. wavefunctions.py lines 90-91 rev 4500(ca) # phase_cd = np.exp(2j * np.pi * sdisp_cd * ibzk_kc[k, :, np.newaxis]) r_cG = gd.empty(3) for c, r_G in enumerate(r_cG): slice_c2G = [np.newaxis, np.newaxis, np.newaxis] slice_c2G[c] = slice(None) #this means ':' r_G[:] = np.arange(gd.beg_c[c], gd.end_c[c], \ dtype=float)[slice_c2G] / gd.N_c[c] X_unn = np.empty((kd.mynks, bd.nbands, bd.nbands), dtype=paw.wfs.dtype) for myu, kpt in enumerate(paw.wfs.kpt_u): u = kd.global_index(myu) s, k = kd.what_is(u) kpt0 = kpt0_s[s] X_nn = X_unn[myu] if phasemod: assert paw.wfs.dtype == complex, 'Phase modification is complex!' k0_c = kd.ibzk_kc[k0] k_c = kd.ibzk_kc[k] eirk_G = np.exp(2j*np.pi*np.sum(r_cG*(k_c-k0_c)[:,np.newaxis,np.newaxis,np.newaxis], axis=0)) psit0_nG = eirk_G[np.newaxis,...]*kpt0.psit_nG P0_ani = paw.wfs.pt.dict(bd.mynbands) spos_ac = atoms.get_scaled_positions() % 1.0 for a, P0_ni in P0_ani.items(): # Expanding the exponential exp(ikr)=exp(ikR)*exp(ik(r-R)) # and neglecting the changed P_ani integral exp(ik(r-R))~1 P0_ni[:] = np.exp(2j*np.pi*np.sum(spos_ac[a]*(k_c-k0_c), axis=0)) * kpt0.P_ani[a] ## NB: No exp(ikr) approximate here, but has a parallelization bug #kpt0_rank, myu0 = kd.get_rank_and_index(kpt0.s, kpt0.k) #if kd.comm.rank == kpt0_rank: # paw.wfs.pt.integrate(psit0_nG, P0_ani, kpt0.q) #for a, P0_ni in P0_ani.items(): # kd.comm.broadcast(P0_ni, kpt0_rank) else: psit0_nG = kpt0.psit_nG P0_ani = kpt0.P_ani """ if paw.wfs.world.size == 1: for n, psit_G in enumerate(kpt.psit_nG): for n0, psit0_G in enumerate(psit0_nG): X_nn[n,n0] = np.vdot(psit_G, psit0_G)*gd.dv for a in range(len(paw.get_atoms())): P_ni, P0_ni, dO_ii = kpt.P_ani[a], P0_ani[a], paw.wfs.setups[a].dO_ii for n, P_i in enumerate(P_ni): for n0, P0_i in enumerate(P0_ni): X_nn[n,n0] += np.vdot(P_i, np.dot(dO_ii, P0_i)) """ X = lambda psit_nG, g=SliceGen(psit0_nG, operator): next(g) dX = lambda a, P_ni: np.dot(P0_ani[a], paw.wfs.setups[a].dO_ii) X_nn[:] = operator.calculate_matrix_elements(kpt.psit_nG, kpt.P_ani, X, dX).T if broadcast: if bd.comm.rank == 0: gd.comm.broadcast(X_unn, 0) bd.comm.broadcast(X_unn, 0) return kpt0_s, X_unn