def get_pnucp(mydf, kpts=None): cell = mydf.cell if kpts is None: kpts_lst = numpy.zeros((1, 3)) else: kpts_lst = numpy.reshape(kpts, (-1, 3)) log = logger.Logger(mydf.stdout, mydf.verbose) t1 = (logger.process_clock(), logger.perf_counter()) nkpts = len(kpts_lst) nao = cell.nao_nr() nao_pair = nao * (nao + 1) // 2 Gv, Gvbase, kws = cell.get_Gv_weights(mydf.mesh) charge = -cell.atom_charges() kpt_allow = numpy.zeros(3) coulG = tools.get_coulG(cell, kpt_allow, mesh=mydf.mesh, Gv=Gv) coulG *= kws if mydf.eta == 0: wj = numpy.zeros((nkpts, nao_pair), dtype=numpy.complex128) SI = cell.get_SI(Gv) vG = numpy.einsum('i,ix->x', charge, SI) * coulG wj = numpy.zeros((nkpts, nao_pair), dtype=numpy.complex128) else: nuccell = copy.copy(cell) half_sph_norm = .5 / numpy.sqrt(numpy.pi) norm = half_sph_norm / mole.gaussian_int(2, mydf.eta) chg_env = [mydf.eta, norm] ptr_eta = cell._env.size ptr_norm = ptr_eta + 1 chg_bas = [[ia, 0, 1, 1, 0, ptr_eta, ptr_norm, 0] for ia in range(cell.natm)] nuccell._atm = cell._atm nuccell._bas = numpy.asarray(chg_bas, dtype=numpy.int32) nuccell._env = numpy.hstack((cell._env, chg_env)) wj = lib.asarray(mydf._int_nuc_vloc(nuccell, kpts_lst, 'int3c2e_pvp1')) t1 = log.timer_debug1('pnucp pass1: analytic int', *t1) aoaux = ft_ao.ft_ao(nuccell, Gv) vG = numpy.einsum('i,xi->x', charge, aoaux) * coulG if cell.dimension == 3: nucbar = sum( [z / nuccell.bas_exp(i)[0] for i, z in enumerate(charge)]) nucbar *= numpy.pi / cell.vol ovlp = cell.pbc_intor('int1e_kin', 1, lib.HERMITIAN, kpts_lst) for k in range(nkpts): s = lib.pack_tril(ovlp[k]) # *2 due to the factor 1/2 in T wj[k] -= nucbar * 2 * s max_memory = max(2000, mydf.max_memory - lib.current_memory()[0]) for aoaoks, p0, p1 in mydf.ft_loop(mydf.mesh, kpt_allow, kpts_lst, max_memory=max_memory, aosym='s2', intor='GTO_ft_pdotp'): for k, aoao in enumerate(aoaoks): if aft_jk.gamma_point(kpts_lst[k]): wj[k] += numpy.einsum('k,kx->x', vG[p0:p1].real, aoao.real) wj[k] += numpy.einsum('k,kx->x', vG[p0:p1].imag, aoao.imag) else: wj[k] += numpy.einsum('k,kx->x', vG[p0:p1].conj(), aoao) t1 = log.timer_debug1('contracting pnucp', *t1) wj_kpts = [] for k, kpt in enumerate(kpts_lst): if aft_jk.gamma_point(kpt): wj_kpts.append(lib.unpack_tril(wj[k].real.copy())) else: wj_kpts.append(lib.unpack_tril(wj[k])) if kpts is None or numpy.shape(kpts) == (3, ): wj_kpts = wj_kpts[0] return numpy.asarray(wj_kpts)
def _uncontract_mol(mol, xuncontract=False, exp_drop=0.2): '''mol._basis + uncontracted steep functions''' pmol = copy.copy(mol) _bas = [] _env = [] ptr = len(pmol._env) contr_coeff = [] for ib in range(mol.nbas): if isinstance(xuncontract, str): ia = mol.bas_atom(ib) uncontract_me = ((xuncontract == mol.atom_pure_symbol(ia)) or (xuncontract == mol.atom_symbol(ia))) elif isinstance(xuncontract, (tuple, list)): ia = mol.bas_atom(ib) uncontract_me = ((mol.atom_pure_symbol(ia) in xuncontract) or (mol.atom_symbol(ia) in xuncontract) or (ia in xuncontract)) else: uncontract_me = xuncontract nc = mol._bas[ib,mole.NCTR_OF] l = mol._bas[ib,mole.ANG_OF] if mol.cart: degen = (l + 1) * (l + 2) // 2 else: degen = l * 2 + 1 if uncontract_me: np = mol._bas[ib,mole.NPRIM_OF] pexp = mol._bas[ib,mole.PTR_EXP] # Modfied partially uncontraction to avoid potentially lindep in the # segment-contracted basis nkept = (pmol._env[pexp:pexp+np] > exp_drop).sum() if nkept > nc: b_coeff = mol.bas_ctr_coeff(ib) importance = numpy.einsum('ij->i', abs(b_coeff)) idx = numpy.argsort(importance[:nkept]) contracted = numpy.sort(idx[nkept-nc:]) primitive = numpy.sort(idx[:nkept-nc]) # part1: pGTOs that are associated with small coefficients bs = numpy.empty((nkept-nc,mol._bas.shape[1]), dtype=numpy.int32) bs[:] = mol._bas[ib] bs[:,mole.NCTR_OF] = bs[:,mole.NPRIM_OF] = 1 for k, i in enumerate(primitive): norm = mole.gto_norm(l, mol._env[pexp+i]) _env.append(mol._env[pexp+i]) _env.append(norm) bs[k,mole.PTR_EXP] = ptr bs[k,mole.PTR_COEFF] = ptr + 1 ptr += 2 _bas.append(bs) part1 = numpy.zeros((degen*(nkept-nc),degen*nc)) c = b_coeff[primitive] for i in range(degen): part1[i::degen,i::degen] = c # part2: binding the pGTOs of small exps to the pGTOs of large coefficients bs = mol._bas[ib].copy() bs[mole.NPRIM_OF] = np - nkept + nc idx = numpy.hstack((contracted, numpy.arange(nkept,np))) exps = mol._env[pexp:pexp+np][idx] cs = mol._libcint_ctr_coeff(ib)[idx] ee = mole.gaussian_int(l*2+2, exps[:,None] + exps) s1 = numpy.einsum('pi,pq,qi->i', cs, ee, cs) s1 = numpy.sqrt(s1) cs = numpy.einsum('pi,i->pi', cs, 1/s1) _env.extend(exps) _env.extend(cs.T.reshape(-1)) bs[mole.PTR_EXP] = ptr bs[mole.PTR_COEFF] = ptr + exps.size ptr += exps.size + cs.size _bas.append(bs) part2 = numpy.eye(degen*nc) for i in range(nc): part2[i*degen:(i+1)*degen,i*degen:(i+1)*degen] *= s1[i] contr_coeff.append(numpy.vstack((part1, part2))) else: _bas.append(mol._bas[ib]) contr_coeff.append(numpy.eye(degen*nc)) else: _bas.append(mol._bas[ib]) contr_coeff.append(numpy.eye(degen*nc)) pmol._bas = numpy.asarray(numpy.vstack(_bas), dtype=numpy.int32) pmol._env = numpy.hstack((mol._env, _env)) return pmol, scipy.linalg.block_diag(*contr_coeff)
def get_pbc_pvxp(cell, kpts=None): import numpy import copy import time from pyscf import lib from pyscf.lib import logger from pyscf.pbc import tools from pyscf.gto import mole from pyscf.pbc.df import ft_ao from pyscf.pbc.df import aft_jk from pyscf.pbc.df import aft if kpts is None: kpts_lst = numpy.zeros((1,3)) else: kpts_lst = numpy.reshape(kpts, (-1,3)) log = logger.Logger(cell.stdout, cell.verbose) t1 = t0 = (time.clock(), time.time()) mydf = aft.AFTDF(cell, kpts) mydf.eta = 0.2 ke_guess = aft.estimate_ke_cutoff_for_eta(cell, mydf.eta, cell.precision) mydf.mesh = tools.cutoff_to_mesh(cell.lattice_vectors(), ke_guess) log.debug('mydf.mesh %s', mydf.mesh) nkpts = len(kpts_lst) nao = cell.nao_nr() nao_pair = nao * (nao+1) // 2 Gv, Gvbase, kws = cell.get_Gv_weights(mydf.mesh) charge = -cell.atom_charges() # Apply Koseki effective charge? kpt_allow = numpy.zeros(3) coulG = tools.get_coulG(cell, kpt_allow, mesh=mydf.mesh, Gv=Gv) coulG *= kws if mydf.eta == 0: soc_mat = numpy.zeros((nkpts,3,nao*nao), dtype=numpy.complex128) SI = cell.get_SI(Gv) vG = numpy.einsum('i,ix->x', charge, SI) * coulG else: nuccell = copy.copy(cell) half_sph_norm = .5/numpy.sqrt(numpy.pi) norm = half_sph_norm/mole.gaussian_int(2, mydf.eta) chg_env = [mydf.eta, norm] ptr_eta = cell._env.size ptr_norm = ptr_eta + 1 chg_bas = [[ia, 0, 1, 1, 0, ptr_eta, ptr_norm, 0] for ia in range(cell.natm)] nuccell._atm = cell._atm nuccell._bas = numpy.asarray(chg_bas, dtype=numpy.int32) nuccell._env = numpy.hstack((cell._env, chg_env)) soc_mat = mydf._int_nuc_vloc(nuccell, kpts_lst, 'int3c2e_pvxp1_sph', aosym='s1', comp=3) soc_mat = numpy.asarray(soc_mat).reshape(nkpts,3,nao**2) t1 = log.timer_debug1('pnucp pass1: analytic int', *t1) aoaux = ft_ao.ft_ao(nuccell, Gv) vG = numpy.einsum('i,xi->x', charge, aoaux) * coulG max_memory = max(2000, mydf.max_memory-lib.current_memory()[0]) for aoaoks, p0, p1 in mydf.ft_loop(mydf.mesh, kpt_allow, kpts_lst, max_memory=max_memory, aosym='s1', intor='GTO_ft_pxp_sph', comp=3): for k, aoao in enumerate(aoaoks): aoao = aoao.reshape(3,-1,nao**2) if aft_jk.gamma_point(kpts_lst[k]): soc_mat[k] += numpy.einsum('k,ckx->cx', vG[p0:p1].real, aoao.real) soc_mat[k] += numpy.einsum('k,ckx->cx', vG[p0:p1].imag, aoao.imag) else: soc_mat[k] += numpy.einsum('k,ckx->cx', vG[p0:p1].conj(), aoao) t1 = log.timer_debug1('contracting pnucp', *t1) soc_mat_kpts = [] for k, kpt in enumerate(kpts_lst): if aft_jk.gamma_point(kpt): soc_mat_kpts.append(soc_mat[k].real.reshape(3,nao,nao)) else: soc_mat_kpts.append(soc_mat[k].reshape(3,nao,nao)) if kpts is None or numpy.shape(kpts) == (3,): soc_mat_kpts = soc_mat_kpts[0] return numpy.asarray(soc_mat_kpts)
def get_pnucp(mydf, kpts=None): cell = mydf.cell if kpts is None: kpts_lst = numpy.zeros((1,3)) else: kpts_lst = numpy.reshape(kpts, (-1,3)) log = logger.Logger(mydf.stdout, mydf.verbose) t1 = t0 = (time.clock(), time.time()) nkpts = len(kpts_lst) nao = cell.nao_nr() nao_pair = nao * (nao+1) // 2 Gv, Gvbase, kws = cell.get_Gv_weights(mydf.mesh) charge = -cell.atom_charges() kpt_allow = numpy.zeros(3) coulG = tools.get_coulG(cell, kpt_allow, mesh=mydf.mesh, Gv=Gv) coulG *= kws if mydf.eta == 0: wj = numpy.zeros((nkpts,nao_pair), dtype=numpy.complex128) SI = cell.get_SI(Gv) vG = numpy.einsum('i,ix->x', charge, SI) * coulG wj = numpy.zeros((nkpts,nao_pair), dtype=numpy.complex128) else: nuccell = copy.copy(cell) half_sph_norm = .5/numpy.sqrt(numpy.pi) norm = half_sph_norm/mole.gaussian_int(2, mydf.eta) chg_env = [mydf.eta, norm] ptr_eta = cell._env.size ptr_norm = ptr_eta + 1 chg_bas = [[ia, 0, 1, 1, 0, ptr_eta, ptr_norm, 0] for ia in range(cell.natm)] nuccell._atm = cell._atm nuccell._bas = numpy.asarray(chg_bas, dtype=numpy.int32) nuccell._env = numpy.hstack((cell._env, chg_env)) wj = lib.asarray(mydf._int_nuc_vloc(nuccell, kpts_lst, 'int3c2e_pvp1')) t1 = log.timer_debug1('pnucp pass1: analytic int', *t1) aoaux = ft_ao.ft_ao(nuccell, Gv) vG = numpy.einsum('i,xi->x', charge, aoaux) * coulG if cell.dimension == 3: nucbar = sum([z/nuccell.bas_exp(i)[0] for i,z in enumerate(charge)]) nucbar *= numpy.pi/cell.vol ovlp = cell.pbc_intor('int1e_kin', 1, lib.HERMITIAN, kpts_lst) for k in range(nkpts): s = lib.pack_tril(ovlp[k]) # *2 due to the factor 1/2 in T wj[k] -= nucbar*2 * s max_memory = max(2000, mydf.max_memory-lib.current_memory()[0]) for aoaoks, p0, p1 in mydf.ft_loop(mydf.mesh, kpt_allow, kpts_lst, max_memory=max_memory, aosym='s2', intor='GTO_ft_pdotp'): for k, aoao in enumerate(aoaoks): if aft_jk.gamma_point(kpts_lst[k]): wj[k] += numpy.einsum('k,kx->x', vG[p0:p1].real, aoao.real) wj[k] += numpy.einsum('k,kx->x', vG[p0:p1].imag, aoao.imag) else: wj[k] += numpy.einsum('k,kx->x', vG[p0:p1].conj(), aoao) t1 = log.timer_debug1('contracting pnucp', *t1) wj_kpts = [] for k, kpt in enumerate(kpts_lst): if aft_jk.gamma_point(kpt): wj_kpts.append(lib.unpack_tril(wj[k].real.copy())) else: wj_kpts.append(lib.unpack_tril(wj[k])) if kpts is None or numpy.shape(kpts) == (3,): wj_kpts = wj_kpts[0] return numpy.asarray(wj_kpts)