def _uncontract_mol(mol, xuncontract=False): pmol = mol.copy() _bas = [] _env = [] ptr = len(pmol._env) contr_coeff = [] for ib in range(mol.nbas): if isinstance(xuncontract, bool): uncontract_me = xuncontract elif 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: raise RuntimeError('xuncontract needs to be bool, str, tuple or list type') if uncontract_me: np = mol._bas[ib,mole.NPRIM_OF] nc = mol._bas[ib,mole.NCTR_OF] pexp = mol._bas[ib,mole.PTR_EXP] # Bypass diffuse functions to avoid linear dependence large = (pmol._env[pexp:pexp+np-nc] > EXP_DROP).sum() if large > 0: l = mol._bas[ib,mole.ANG_OF] bs = numpy.empty((large,mol._bas.shape[1]), dtype=numpy.int32) bs[:] = mol._bas[ib] bs[:,mole.NCTR_OF] = bs[:,mole.NPRIM_OF] = 1 bs[:,mole.PTR_EXP] = numpy.arange(pexp, pexp+large) for i in range(large): nn = mole._gaussian_int(l*2+2, mol._env[pexp+i]*2) _env.append(1/numpy.sqrt(nn)) bs[i,mole.PTR_COEFF] = ptr ptr += 1 _bas.append(bs) _bas.append(mol._bas[ib]) l = mol.bas_angular(ib) d = l * 2 + 1 c1 = numpy.zeros((d*large,d*mol.bas_nctr(ib))) c2 = numpy.eye(d*mol.bas_nctr(ib)) contr_coeff.append(numpy.vstack((c1,c2))) else: _bas.append(mol._bas[ib]) l = mol.bas_angular(ib) d = l * 2 + 1 contr_coeff.append(numpy.eye(d*mol.bas_nctr(ib))) pmol._bas = numpy.vstack(_bas) pmol._env = numpy.hstack((mol._env, _env)) return pmol, scipy.linalg.block_diag(*contr_coeff)
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.gs) kpt_allow = numpy.zeros(3) if mydf.eta == 0: charge = -cell.atom_charges() #coulG=4*numpy.pi/G^2 is cancelled with (sigma dot p i, sigma dot p j) SI = cell.get_SI(Gv) vGR = numpy.einsum('i,ix->x', 4 * numpy.pi * charge, SI.real) * kws vGI = numpy.einsum('i,ix->x', 4 * numpy.pi * charge, SI.imag) * kws wjR = numpy.zeros((nkpts, nao_pair)) wjI = numpy.zeros((nkpts, nao_pair)) 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_sph')) wjR = wj.real wjI = wj.imag t1 = log.timer_debug1('pnucp pass1: analytic int', *t1) charge = -cell.atom_charges() #coulG=4*numpy.pi/G^2 is cancelled with (sigma dot p i, sigma dot p j) aoaux = ft_ao.ft_ao(nuccell, Gv) vGR = numpy.einsum('i,xi->x', 4 * numpy.pi * charge, aoaux.real) * kws vGI = numpy.einsum('i,xi->x', 4 * numpy.pi * charge, aoaux.imag) * kws max_memory = max(2000, mydf.max_memory - lib.current_memory()[0]) for k, pqkR, pqkI, p0, p1 \ in mydf.ft_loop(mydf.gs, kpt_allow, kpts_lst, max_memory=max_memory, aosym='s2'): # rho_ij(G) nuc(-G) / G^2 # = [Re(rho_ij(G)) + Im(rho_ij(G))*1j] [Re(nuc(G)) - Im(nuc(G))*1j] / G^2 if not aft_jk.gamma_point(kpts_lst[k]): wjI[k] += numpy.einsum('k,xk->x', vGR[p0:p1], pqkI) wjI[k] -= numpy.einsum('k,xk->x', vGI[p0:p1], pqkR) wjR[k] += numpy.einsum('k,xk->x', vGR[p0:p1], pqkR) wjR[k] += numpy.einsum('k,xk->x', vGI[p0:p1], pqkI) t1 = log.timer_debug1('contracting Vnuc', *t1) if mydf.eta != 0 and cell.dimension == 3: nucbar = sum([z / nuccell.bas_exp(i)[0] for i, z in enumerate(charge)]) nucbar *= numpy.pi / cell.vol * 2 ovlp = cell.pbc_intor('int1e_kin_sph', 1, lib.HERMITIAN, kpts_lst) for k in range(nkpts): s = lib.pack_tril(ovlp[k]) wjR[k] -= nucbar * s.real wjI[k] -= nucbar * s.imag wj = [] for k, kpt in enumerate(kpts_lst): if aft_jk.gamma_point(kpt): wj.append(lib.unpack_tril(wjR[k])) else: wj.append(lib.unpack_tril(wjR[k] + wjI[k] * 1j)) if kpts is None or numpy.shape(kpts) == (3, ): wj = wj[0] return wj
def _uncontract_mol(mol, xuncontract=False): '''mol._basis + uncontracted steep functions''' pmol = mol.copy() _bas = [] _env = [] ptr = len(pmol._env) contr_coeff = [] for ib in range(mol.nbas): if isinstance(xuncontract, bool): uncontract_me = xuncontract elif 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: raise RuntimeError( 'xuncontract needs to be bool, str, tuple or list type') if uncontract_me: np = mol._bas[ib, mole.NPRIM_OF] nc = mol._bas[ib, mole.NCTR_OF] l = mol.bas_angular(ib) 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) norms = mole.gto_norm(l, mol._env[pexp:pexp + np]) importance = numpy.einsum('i,ij->i', 1 / norms, 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 norms = numpy.empty(nkept - nc) for k, i in enumerate(primitive): norms[k] = mole.gto_norm(l, mol._env[pexp + i]) _env.append(mol._env[pexp + i]) _env.append(norms[k]) bs[k, mole.PTR_EXP] = ptr bs[k, mole.PTR_COEFF] = ptr + 1 ptr += 2 _bas.append(bs) d = l * 2 + 1 part1 = numpy.zeros((d * (nkept - nc), d * nc)) c = numpy.einsum('i,ij->ij', 1 / norms, b_coeff[primitive]) for i in range(d): part1[i::d, i::d] = 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 = b_coeff[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(d * nc) for i in range(nc): part2[i * d:(i + 1) * d, i * d:(i + 1) * d] *= s1[i] contr_coeff.append(numpy.vstack((part1, part2))) else: _bas.append(mol._bas[ib]) contr_coeff.append(numpy.eye((l * 2 + 1) * nc)) else: _bas.append(mol._bas[ib]) l = mol.bas_angular(ib) d = l * 2 + 1 contr_coeff.append(numpy.eye(d * mol.bas_nctr(ib))) pmol._bas = numpy.vstack(_bas) pmol._env = numpy.hstack((mol._env, _env)) return pmol, scipy.linalg.block_diag(*contr_coeff)
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.gs) charge = -cell.atom_charges() kpt_allow = numpy.zeros(3) coulG = tools.get_coulG(cell, kpt_allow, gs=mydf.gs, Gv=Gv) coulG *= kws if mydf.eta == 0: wj = numpy.zeros((nkpts, nao_pair), dtype=numpy.complex128) wjI = numpy.zeros((nkpts, nao_pair)) 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)) wj = lib.asarray( mydf._int_nuc_vloc(nuccell, kpts_lst, 'int3c2e_pvp1_sph')) 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.gs, kpt_allow, kpts_lst, max_memory=max_memory, aosym='s2', intor='GTO_ft_pdotp_sph'): 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) if mydf.eta != 0 and cell.dimension == 3: nucbar = sum( [-z / nuccell.bas_exp(i)[0] for i, z in enumerate(charge)]) nucbar *= numpy.pi / cell.vol * 2 # 2 due to the factor 1/2 in T ovlp = cell.pbc_intor('int1e_kin_sph', 1, lib.HERMITIAN, kpts_lst) for k in range(nkpts): s = lib.pack_tril(ovlp[k]) wj[k] += nucbar * s 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 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.gs) kpt_allow = numpy.zeros(3) if mydf.eta == 0: charge = -cell.atom_charges() #coulG=4*numpy.pi/G^2 is cancelled with (sigma dot p i, sigma dot p j) SI = cell.get_SI(Gv) vGR = numpy.einsum('i,ix->x', 4*numpy.pi*charge, SI.real) * kws vGI = numpy.einsum('i,ix->x', 4*numpy.pi*charge, SI.imag) * kws wjR = numpy.zeros((nkpts,nao_pair)) wjI = numpy.zeros((nkpts,nao_pair)) 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, 'cint3c2e_pvp1_sph')) wjR = wj.real wjI = wj.imag t1 = log.timer_debug1('pnucp pass1: analytic int', *t1) charge = -cell.atom_charges() #coulG=4*numpy.pi/G^2 is cancelled with (sigma dot p i, sigma dot p j) aoaux = ft_ao.ft_ao(nuccell, Gv) vGR = numpy.einsum('i,xi->x', 4*numpy.pi*charge, aoaux.real) * kws vGI = numpy.einsum('i,xi->x', 4*numpy.pi*charge, aoaux.imag) * kws max_memory = max(2000, mydf.max_memory-lib.current_memory()[0]) for k, pqkR, pqkI, p0, p1 \ in mydf.ft_loop(mydf.gs, kpt_allow, kpts_lst, max_memory=max_memory, aosym='s2'): # rho_ij(G) nuc(-G) / G^2 # = [Re(rho_ij(G)) + Im(rho_ij(G))*1j] [Re(nuc(G)) - Im(nuc(G))*1j] / G^2 if not pwdf_jk.gamma_point(kpts_lst[k]): wjI[k] += numpy.einsum('k,xk->x', vGR[p0:p1], pqkI) wjI[k] -= numpy.einsum('k,xk->x', vGI[p0:p1], pqkR) wjR[k] += numpy.einsum('k,xk->x', vGR[p0:p1], pqkR) wjR[k] += numpy.einsum('k,xk->x', vGI[p0:p1], pqkI) t1 = log.timer_debug1('contracting Vnuc', *t1) if mydf.eta != 0 and cell.dimension == 3: nucbar = sum([z/nuccell.bas_exp(i)[0] for i,z in enumerate(charge)]) nucbar *= numpy.pi/cell.vol * 2 ovlp = cell.pbc_intor('cint1e_kin_sph', 1, lib.HERMITIAN, kpts_lst) for k in range(nkpts): s = lib.pack_tril(ovlp[k]) wjR[k] -= nucbar * s.real wjI[k] -= nucbar * s.imag wj = [] for k, kpt in enumerate(kpts_lst): if pwdf_jk.gamma_point(kpt): wj.append(lib.unpack_tril(wjR[k])) else: wj.append(lib.unpack_tril(wjR[k]+wjI[k]*1j)) if kpts is None or numpy.shape(kpts) == (3,): wj = wj[0] return wj
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, bool): uncontract_me = xuncontract elif 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: raise RuntimeError('xuncontract needs to be bool, str, tuple or list type') if uncontract_me: np = mol._bas[ib,mole.NPRIM_OF] nc = mol._bas[ib,mole.NCTR_OF] l = mol._bas[ib,mole.ANG_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) d = l * 2 + 1 part1 = numpy.zeros((d*(nkept-nc),d*nc)) c = b_coeff[primitive] for i in range(d): part1[i::d,i::d] = 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(d*nc) for i in range(nc): part2[i*d:(i+1)*d,i*d:(i+1)*d] *= s1[i] contr_coeff.append(numpy.vstack((part1, part2))) else: _bas.append(mol._bas[ib]) contr_coeff.append(numpy.eye((l*2+1)*nc)) else: _bas.append(mol._bas[ib]) l = mol.bas_angular(ib) d = l * 2 + 1 contr_coeff.append(numpy.eye(d*mol.bas_nctr(ib))) 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)