def make_h1(hessobj, mo_coeff, mo_occ, chkfile=None, atmlst=None, verbose=None): mol = hessobj.mol if atmlst is None: atmlst = range(mol.natm) nao, nmo = mo_coeff.shape mocc = mo_coeff[:,mo_occ>0] dm0 = numpy.dot(mocc, mocc.T) * 2 hcore_deriv = hessobj.base.nuc_grad_method().hcore_generator(mol) mf = hessobj.base ni = mf._numint ni.libxc.test_deriv_order(mf.xc, 2, raise_error=True) omega, alpha, hyb = ni.rsh_and_hybrid_coeff(mf.xc, spin=mol.spin) mem_now = lib.current_memory()[0] max_memory = max(2000, mf.max_memory*.9-mem_now) h1ao = _get_vxc_deriv1(hessobj, mo_coeff, mo_occ, max_memory) aoslices = mol.aoslice_by_atom() for i0, ia in enumerate(atmlst): shl0, shl1, p0, p1 = aoslices[ia] shls_slice = (shl0, shl1) + (0, mol.nbas)*3 if abs(hyb) > 1e-10: vj1, vj2, vk1, vk2 = \ rhf_hess._get_jk(mol, 'int2e_ip1', 3, 's2kl', ['ji->s2kl', -dm0[:,p0:p1], # vj1 'lk->s1ij', -dm0 , # vj2 'li->s1kj', -dm0[:,p0:p1], # vk1 'jk->s1il', -dm0 ], # vk2 shls_slice=shls_slice) veff = vj1 - hyb * .5 * vk1 veff[:,p0:p1] += vj2 - hyb * .5 * vk2 if abs(omega) > 1e-10: with mol.with_range_coulomb(omega): vk1, vk2 = \ rhf_hess._get_jk(mol, 'int2e_ip1', 3, 's2kl', ['li->s1kj', -dm0[:,p0:p1], # vk1 'jk->s1il', -dm0 ], # vk2 shls_slice=shls_slice) veff -= (alpha-hyb) * .5 * vk1 veff[:,p0:p1] -= (alpha-hyb) * .5 * vk2 else: vj1, vj2 = rhf_hess._get_jk(mol, 'int2e_ip1', 3, 's2kl', ['ji->s2kl', -dm0[:,p0:p1], # vj1 'lk->s1ij', -dm0 ], # vj2 shls_slice=shls_slice) veff = vj1 veff[:,p0:p1] += vj2 h1ao[ia] += veff + veff.transpose(0,2,1) h1ao[ia] += hcore_deriv(ia) if chkfile is None: return h1ao else: for ia in atmlst: lib.chkfile.save(chkfile, 'scf_f1ao/%d'%ia, h1ao[ia]) return chkfile
def get_eph(ephobj, mo1, omega, vec, mo_rep): if isinstance(mo1, str): mo1 = lib.chkfile.load(mo1, 'scf_mo1') mo1 = dict([(int(k), mo1[k]) for k in mo1]) mol = ephobj.mol mf = ephobj.base ni = mf._numint ni.libxc.test_deriv_order(mf.xc, 2, raise_error=True) omg, alpha, hyb = ni.rsh_and_hybrid_coeff(mf.xc, spin=mol.spin) vnuc_deriv = ephobj.vnuc_generator(mol) aoslices = mol.aoslice_by_atom() vind = rhf_eph.rhf_deriv_generator(mf, mf.mo_coeff, mf.mo_occ) mocc = mf.mo_coeff[:,mf.mo_occ>0] dm0 = np.dot(mocc, mocc.T) * 2 natoms = mol.natm nao = mol.nao_nr() mem_now = lib.current_memory()[0] max_memory = max(2000, mf.max_memory*.9-mem_now) vxc1ao = _get_vxc_deriv1(ephobj, mf.mo_coeff, mf.mo_occ, max_memory) vcore = [] for ia in range(natoms): h1 = vnuc_deriv(ia) v1 = vind(mo1[ia]) shl0, shl1, p0, p1 = aoslices[ia] shls_slice = (shl0, shl1) + (0, mol.nbas)*3 if abs(hyb)>1e-10: vj1, vk1 = \ rhf_hess._get_jk(mol, 'int2e_ip1', 3, 's2kl', ['ji->s2kl', -dm0[:,p0:p1], #vj1 'li->s1kj', -dm0[:,p0:p1]], #vk1 shls_slice=shls_slice) veff = vj1 - hyb * .5 * vk1 if abs(omg) > 1e-10: with mol.with_range_coulomb(omg): vk1 = \ rhf_hess._get_jk(mol, 'int2e_ip1', 3, 's2kl', ['li->s1kj', -dm0[:,p0:p1]], # vk1 shls_slice=shls_slice) veff -= (alpha-hyb) * .5 * vk1 else: vj1 = rhf_hess._get_jk(mol, 'int2e_ip1', 3, 's2kl', ['ji->s2kl', -dm0[:,p0:p1]], # vj1 shls_slice=shls_slice) veff = vj1[0] vtot = h1 + v1 + veff + vxc1ao[ia] + veff.transpose(0,2,1) vcore.append(vtot) vcore = np.asarray(vcore).reshape(-1,nao,nao) mass = mol.atom_mass_list() * MP_ME vec = rhf_eph._freq_mass_weighted_vec(vec, omega, mass) mat = np.einsum('xJ,xuv->Juv', vec, vcore, optimize=True) if mo_rep: mat = np.einsum('Juv,up,vq->Jpq', mat, mf.mo_coeff.conj(), mf.mo_coeff, optimize=True) return mat
def get_eph(ephobj, mo1, omega, vec, mo_rep): if isinstance(mo1, str): mo1 = lib.chkfile.load(mo1, 'scf_mo1') mo1a = mo1['0'] mo1b = mo1['1'] mo1a = dict([(int(k), mo1a[k]) for k in mo1a]) mo1b = dict([(int(k), mo1b[k]) for k in mo1b]) mol = ephobj.mol mf = ephobj.base vnuc_deriv = ephobj.vnuc_generator(mol) aoslices = mol.aoslice_by_atom() mo_coeff, mo_occ = mf.mo_coeff, mf.mo_occ vind = uhf_deriv_generator(mf, mf.mo_coeff, mf.mo_occ) nao, nmo = mo_coeff[0].shape mocca = mo_coeff[0][:,mo_occ[0]>0] moccb = mo_coeff[1][:,mo_occ[1]>0] dm0a = np.dot(mocca, mocca.T) dm0b = np.dot(moccb, moccb.T) natoms = mol.natm vcorea = [] vcoreb = [] for ia in range(natoms): h1 = vnuc_deriv(ia) moia = np.hstack((mo1a[ia], mo1b[ia])) v1 = vind(moia) shl0, shl1, p0, p1 = aoslices[ia] shls_slice = (shl0, shl1) + (0, mol.nbas)*3 vja, vjb, vka, vkb= rhf_hess._get_jk(mol, 'int2e_ip1', 3, 's2kl', ['ji->s2kl', -dm0a[:,p0:p1], # vja 'ji->s2kl', -dm0b[:,p0:p1], # vjb 'li->s1kj', -dm0a[:,p0:p1], # vka 'li->s1kj', -dm0b[:,p0:p1]], # vkb shls_slice=shls_slice) vhfa = vja + vjb - vka vhfb = vjb + vjb - vkb vtota = h1 + v1[0] + vhfa + vhfa.transpose(0,2,1) vtotb = h1 + v1[1] + vhfb + vhfb.transpose(0,2,1) vcorea.append(vtota) vcoreb.append(vtotb) vcorea = np.asarray(vcorea).reshape(-1,nao,nao) vcoreb = np.asarray(vcoreb).reshape(-1,nao,nao) mass = mol.atom_mass_list() * MP_ME vec = rhf_eph._freq_mass_weighted_vec(vec, omega, mass) mata = np.einsum('xJ,xuv->Juv', vec, vcorea) matb = np.einsum('xJ,xuv->Juv', vec, vcoreb) if mo_rep: mata = np.einsum('Juv,up,vq->Jpq', mata, mf.mo_coeff[0].conj(), mf.mo_coeff[0], optimize=True) matb = np.einsum('Juv,up,vq->Jpq', matb, mf.mo_coeff[1].conj(), mf.mo_coeff[1], optimize=True) return np.asarray([mata,matb])
def get_eph(ephobj, mo1, omega, vec, mo_rep): if isinstance(mo1, str): mo1 = chkfile.load(mo1, 'scf_mo1') mo1 = dict([(int(k), mo1[k]) for k in mo1]) mol = ephobj.mol mf = ephobj.base vnuc_deriv = ephobj.vnuc_generator(mol) aoslices = mol.aoslice_by_atom() vind = rhf_deriv_generator(mf, mf.mo_coeff, mf.mo_occ) mocc = mf.mo_coeff[:, mf.mo_occ > 0] dm0 = np.dot(mocc, mocc.T) * 2 natoms = mol.natm nao = mol.nao_nr() vcore = [] for ia in range(natoms): h1 = vnuc_deriv(ia) v1 = vind(mo1[ia]) shl0, shl1, p0, p1 = aoslices[ia] shls_slice = (shl0, shl1) + (0, mol.nbas) * 3 vj1, vk1 = rhf._get_jk( mol, 'int2e_ip1', 3, 's2kl', [ 'ji->s2kl', -dm0[:, p0:p1], # vj1 'li->s1kj', -dm0[:, p0:p1] ], # vk1 shls_slice=shls_slice) vhf = vj1 - vk1 * .5 vtot = h1 + v1 + vhf + vhf.transpose(0, 2, 1) vcore.append(vtot) vcore = np.asarray(vcore).reshape(-1, nao, nao) mass = mol.atom_mass_list() * MP_ME vec = _freq_mass_weighted_vec(vec, omega, mass) mat = np.einsum('xJ,xuv->Juv', vec, vcore) if mo_rep: mat = np.einsum('Juv,up,vq->Jpq', mat, mf.mo_coeff.conj(), mf.mo_coeff, optimize=True) return mat
def partial_hess_elec(hessobj, mo_energy=None, mo_coeff=None, mo_occ=None, atmlst=None, max_memory=4000, verbose=None): log = logger.new_logger(hessobj, verbose) time0 = t1 = (time.clock(), time.time()) mol = hessobj.mol mf = hessobj.base if mo_energy is None: mo_energy = mf.mo_energy if mo_occ is None: mo_occ = mf.mo_occ if mo_coeff is None: mo_coeff = mf.mo_coeff if atmlst is None: atmlst = range(mol.natm) nao, nmo = mo_coeff.shape mocc = mo_coeff[:, mo_occ > 0] nocc = mocc.shape[1] dm0 = numpy.dot(mocc, mocc.T) * 2 # Energy weighted density matrix dme0 = numpy.einsum('pi,qi,i->pq', mocc, mocc, mo_energy[mo_occ > 0]) * 2 hcore_deriv = hessobj.hcore_generator(mol) s1aa, s1ab, s1a = rhf_hess.get_ovlp(mol) if mf.nlc != '': raise NotImplementedError #enabling range-separated hybrids omega, alpha, beta = mf._numint.rsh_coeff(mf.xc) if abs(omega) > 1e-10: hyb = alpha + beta else: hyb = mf._numint.hybrid_coeff(mf.xc, spin=mol.spin) mem_now = lib.current_memory()[0] max_memory = max(2000, mf.max_memory * .9 - mem_now) veff_diag = _get_vxc_diag(hessobj, mo_coeff, mo_occ, max_memory) if abs(hyb) > 1e-10: vj1, vk1 = rhf_hess._get_jk( mol, 'int2e_ipip1', 9, 's2kl', [ 'lk->s1ij', dm0, # vj1 'jk->s1il', dm0 ]) # vk1 veff_diag += (vj1 - hyb * .5 * vk1).reshape(3, 3, nao, nao) if abs(omega) > 1e-10: with mol.with_range_coulomb(omega): vk1 = rhf_hess._get_jk(mol, 'int2e_ipip1', 9, 's2kl', ['jk->s1il', dm0])[0] veff_diag -= (alpha - hyb) * .5 * vk1.reshape(3, 3, nao, nao) else: vj1 = rhf_hess._get_jk(mol, 'int2e_ipip1', 9, 's2kl', ['lk->s1ij', dm0])[0] veff_diag += vj1.reshape(3, 3, nao, nao) vj1 = vk1 = None t1 = log.timer_debug1('contracting int2e_ipip1', *t1) aoslices = mol.aoslice_by_atom() de2 = numpy.zeros((mol.natm, mol.natm, 3, 3)) # (A,B,dR_A,dR_B) vxc = _get_vxc_deriv2(hessobj, mo_coeff, mo_occ, max_memory) for i0, ia in enumerate(atmlst): shl0, shl1, p0, p1 = aoslices[ia] shls_slice = (shl0, shl1) + (0, mol.nbas) * 3 veff = vxc[ia] if abs(hyb) > 1e-10: vj1, vk1, vk2 = rhf_hess._get_jk( mol, 'int2e_ip1ip2', 9, 's1', [ 'ji->s1kl', dm0[:, p0:p1], # vj1 'li->s1kj', dm0[:, p0:p1], # vk1 'lj->s1ki', dm0 ], # vk2 shls_slice=shls_slice) veff += (vj1 * 2 - hyb * .5 * vk1).reshape(3, 3, nao, nao) veff[:, :, :, p0:p1] -= (hyb * .5 * vk2).reshape(3, 3, nao, p1 - p0) if abs(omega) > 1e-10: with mol.with_range_coulomb(omega): vk1, vk2 = rhf_hess._get_jk( mol, 'int2e_ip1ip2', 9, 's1', [ 'li->s1kj', dm0[:, p0:p1], # vk1 'lj->s1ki', dm0 ], # vk2 shls_slice=shls_slice) veff -= (alpha - hyb) * .5 * vk1.reshape(3, 3, nao, nao) veff[:, :, :, p0:p1] -= (alpha - hyb) * .5 * vk2.reshape( 3, 3, nao, p1 - p0) t1 = log.timer_debug1('contracting int2e_ip1ip2 for atom %d' % ia, *t1) vj1, vk1 = rhf_hess._get_jk( mol, 'int2e_ipvip1', 9, 's2kl', [ 'lk->s1ij', dm0, # vj1 'li->s1kj', dm0[:, p0:p1] ], # vk1 shls_slice=shls_slice) veff[:, :, :, p0:p1] += vj1.transpose(0, 2, 1).reshape(3, 3, nao, p1 - p0) veff -= hyb * .5 * vk1.transpose(0, 2, 1).reshape(3, 3, nao, nao) if abs(omega) > 1e-10: with mol.with_range_coulomb(omega): vk1 = rhf_hess._get_jk( mol, 'int2e_ipvip1', 9, 's2kl', ['li->s1kj', dm0[:, p0:p1]], # vk1 shls_slice=shls_slice)[0] veff -= (alpha - hyb) * .5 * vk1.transpose(0, 2, 1).reshape( 3, 3, nao, nao) t1 = log.timer_debug1('contracting int2e_ipvip1 for atom %d' % ia, *t1) else: vj1 = rhf_hess._get_jk(mol, 'int2e_ip1ip2', 9, 's1', ['ji->s1kl', dm0[:, p0:p1]], shls_slice=shls_slice)[0] veff += vj1.reshape(3, 3, nao, nao) * 2 t1 = log.timer_debug1('contracting int2e_ip1ip2 for atom %d' % ia, *t1) vj1 = rhf_hess._get_jk(mol, 'int2e_ipvip1', 9, 's2kl', ['lk->s1ij', dm0], shls_slice=shls_slice)[0] veff[:, :, :, p0:p1] += vj1.transpose(0, 2, 1).reshape(3, 3, nao, p1 - p0) t1 = log.timer_debug1('contracting int2e_ipvip1 for atom %d' % ia, *t1) vj1 = vk1 = vk2 = None s1ao = numpy.zeros((3, nao, nao)) s1ao[:, p0:p1] += s1a[:, p0:p1] s1ao[:, :, p0:p1] += s1a[:, p0:p1].transpose(0, 2, 1) s1oo = numpy.einsum('xpq,pi,qj->xij', s1ao, mocc, mocc) de2[i0, i0] += numpy.einsum('xypq,pq->xy', veff_diag[:, :, p0:p1], dm0[p0:p1]) * 2 de2[i0, i0] -= numpy.einsum('xypq,pq->xy', s1aa[:, :, p0:p1], dme0[p0:p1]) * 2 for j0, ja in enumerate(atmlst[:i0 + 1]): q0, q1 = aoslices[ja][2:] de2[i0, j0] += numpy.einsum('xypq,pq->xy', veff[:, :, q0:q1], dm0[q0:q1]) * 2 de2[i0, j0] -= numpy.einsum('xypq,pq->xy', s1ab[:, :, p0:p1, q0:q1], dme0[p0:p1, q0:q1]) * 2 h1ao = hcore_deriv(ia, ja) de2[i0, j0] += numpy.einsum('xypq,pq->xy', h1ao, dm0) for j0 in range(i0): de2[j0, i0] = de2[i0, j0].T log.timer('RKS partial hessian', *time0) return de2
def partial_hess_elec(hessobj, mo_energy=None, mo_coeff=None, mo_occ=None, atmlst=None, max_memory=4000, verbose=None): log = logger.new_logger(hessobj, verbose) time0 = t1 = (time.clock(), time.time()) mol = hessobj.mol mf = hessobj.base if mo_energy is None: mo_energy = mf.mo_energy if mo_occ is None: mo_occ = mf.mo_occ if mo_coeff is None: mo_coeff = mf.mo_coeff if atmlst is None: atmlst = range(mol.natm) nao, nmo = mo_coeff.shape mocc = mo_coeff[:,mo_occ>0] nocc = mocc.shape[1] dm0 = numpy.dot(mocc, mocc.T) * 2 # Energy weighted density matrix dme0 = numpy.einsum('pi,qi,i->pq', mocc, mocc, mo_energy[mo_occ>0]) * 2 hcore_deriv = hessobj.hcore_generator(mol) s1aa, s1ab, s1a = rhf_hess.get_ovlp(mol) if mf.nlc != '': raise NotImplementedError #enabling range-separated hybrids omega, alpha, beta = mf._numint.rsh_coeff(mf.xc) if abs(omega) > 1e-10: hyb = alpha + beta else: hyb = mf._numint.hybrid_coeff(mf.xc, spin=mol.spin) mem_now = lib.current_memory()[0] max_memory = max(2000, mf.max_memory*.9-mem_now) veff_diag = _get_vxc_diag(hessobj, mo_coeff, mo_occ, max_memory) if abs(hyb) > 1e-10: vj1, vk1 = rhf_hess._get_jk(mol, 'int2e_ipip1', 9, 's2kl', ['lk->s1ij', dm0, # vj1 'jk->s1il', dm0]) # vk1 veff_diag += (vj1 - hyb * .5 * vk1).reshape(3,3,nao,nao) if abs(omega) > 1e-10: with mol.with_range_coulomb(omega): vk1 = rhf_hess._get_jk(mol, 'int2e_ipip1', 9, 's2kl', ['jk->s1il', dm0])[0] veff_diag -= (alpha-hyb)*.5 * vk1.reshape(3,3,nao,nao) else: vj1 = rhf_hess._get_jk(mol, 'int2e_ipip1', 9, 's2kl', ['lk->s1ij', dm0])[0] veff_diag += vj1.reshape(3,3,nao,nao) vj1 = vk1 = None t1 = log.timer_debug1('contracting int2e_ipip1', *t1) aoslices = mol.aoslice_by_atom() de2 = numpy.zeros((mol.natm,mol.natm,3,3)) # (A,B,dR_A,dR_B) vxc = _get_vxc_deriv2(hessobj, mo_coeff, mo_occ, max_memory) for i0, ia in enumerate(atmlst): shl0, shl1, p0, p1 = aoslices[ia] shls_slice = (shl0, shl1) + (0, mol.nbas)*3 veff = vxc[ia] if abs(hyb) > 1e-10: vj1, vk1, vk2 = rhf_hess._get_jk(mol, 'int2e_ip1ip2', 9, 's1', ['ji->s1kl', dm0[:,p0:p1], # vj1 'li->s1kj', dm0[:,p0:p1], # vk1 'lj->s1ki', dm0 ], # vk2 shls_slice=shls_slice) veff += (vj1 * 2 - hyb * .5 * vk1).reshape(3,3,nao,nao) veff[:,:,:,p0:p1] -= (hyb * .5 * vk2).reshape(3,3,nao,p1-p0) if abs(omega) > 1e-10: with mol.with_range_coulomb(omega): vk1, vk2 = rhf_hess._get_jk(mol, 'int2e_ip1ip2', 9, 's1', ['li->s1kj', dm0[:,p0:p1], # vk1 'lj->s1ki', dm0 ], # vk2 shls_slice=shls_slice) veff -= (alpha-hyb)*.5 * vk1.reshape(3,3,nao,nao) veff[:,:,:,p0:p1] -= (alpha-hyb)*.5 * vk2.reshape(3,3,nao,p1-p0) t1 = log.timer_debug1('contracting int2e_ip1ip2 for atom %d'%ia, *t1) vj1, vk1 = rhf_hess._get_jk(mol, 'int2e_ipvip1', 9, 's2kl', ['lk->s1ij', dm0, # vj1 'li->s1kj', dm0[:,p0:p1]], # vk1 shls_slice=shls_slice) veff[:,:,:,p0:p1] += vj1.transpose(0,2,1).reshape(3,3,nao,p1-p0) veff -= hyb * .5 * vk1.transpose(0,2,1).reshape(3,3,nao,nao) if abs(omega) > 1e-10: with mol.with_range_coulomb(omega): vk1 = rhf_hess._get_jk(mol, 'int2e_ipvip1', 9, 's2kl', ['li->s1kj', dm0[:,p0:p1]], # vk1 shls_slice=shls_slice)[0] veff -= (alpha-hyb)*.5 * vk1.transpose(0,2,1).reshape(3,3,nao,nao) t1 = log.timer_debug1('contracting int2e_ipvip1 for atom %d'%ia, *t1) else: vj1 = rhf_hess._get_jk(mol, 'int2e_ip1ip2', 9, 's1', ['ji->s1kl', dm0[:,p0:p1]], shls_slice=shls_slice)[0] veff += vj1.reshape(3,3,nao,nao) * 2 t1 = log.timer_debug1('contracting int2e_ip1ip2 for atom %d'%ia, *t1) vj1 = rhf_hess._get_jk(mol, 'int2e_ipvip1', 9, 's2kl', ['lk->s1ij', dm0], shls_slice=shls_slice)[0] veff[:,:,:,p0:p1] += vj1.transpose(0,2,1).reshape(3,3,nao,p1-p0) t1 = log.timer_debug1('contracting int2e_ipvip1 for atom %d'%ia, *t1) vj1 = vk1 = vk2 = None s1ao = numpy.zeros((3,nao,nao)) s1ao[:,p0:p1] += s1a[:,p0:p1] s1ao[:,:,p0:p1] += s1a[:,p0:p1].transpose(0,2,1) s1oo = numpy.einsum('xpq,pi,qj->xij', s1ao, mocc, mocc) de2[i0,i0] += numpy.einsum('xypq,pq->xy', veff_diag[:,:,p0:p1], dm0[p0:p1])*2 de2[i0,i0] -= numpy.einsum('xypq,pq->xy', s1aa[:,:,p0:p1], dme0[p0:p1])*2 for j0, ja in enumerate(atmlst[:i0+1]): q0, q1 = aoslices[ja][2:] de2[i0,j0] += numpy.einsum('xypq,pq->xy', veff[:,:,q0:q1], dm0[q0:q1])*2 de2[i0,j0] -= numpy.einsum('xypq,pq->xy', s1ab[:,:,p0:p1,q0:q1], dme0[p0:p1,q0:q1])*2 h1ao = hcore_deriv(ia, ja) de2[i0,j0] += numpy.einsum('xypq,pq->xy', h1ao, dm0) for j0 in range(i0): de2[j0,i0] = de2[i0,j0].T log.timer('RKS partial hessian', *time0) return de2
def get_eph(ephobj, mo1, omega, vec, mo_rep): if isinstance(mo1, str): mo1 = lib.chkfile.load(mo1, 'scf_mo1') mo1a = mo1['0'] mo1b = mo1['1'] mo1a = dict([(int(k), mo1a[k]) for k in mo1a]) mo1b = dict([(int(k), mo1b[k]) for k in mo1b]) mol = ephobj.mol mf = ephobj.base ni = mf._numint ni.libxc.test_deriv_order(mf.xc, 2, raise_error=True) omg, alpha, hyb = ni.rsh_and_hybrid_coeff(mf.xc, spin=mol.spin) vnuc_deriv = ephobj.vnuc_generator(mol) aoslices = mol.aoslice_by_atom() mo_coeff, mo_occ = mf.mo_coeff, mf.mo_occ vind = uhf_deriv_generator(mf, mf.mo_coeff, mf.mo_occ) mem_now = lib.current_memory()[0] max_memory = max(2000, mf.max_memory*.9-mem_now) vxc1aoa, vxc1aob = _get_vxc_deriv1(ephobj, mf.mo_coeff, mf.mo_occ, max_memory) nao, nmo = mo_coeff[0].shape mocca = mo_coeff[0][:,mo_occ[0]>0] moccb = mo_coeff[1][:,mo_occ[1]>0] dm0a = np.dot(mocca, mocca.T) dm0b = np.dot(moccb, moccb.T) natoms = mol.natm vcorea = [] vcoreb = [] for ia in range(natoms): h1 = vnuc_deriv(ia) moia = np.hstack((mo1a[ia], mo1b[ia])) v1 = vind(moia) shl0, shl1, p0, p1 = aoslices[ia] shls_slice = (shl0, shl1) + (0, mol.nbas)*3 if abs(hyb)>1e-10: vja, vjb, vka, vkb = \ rhf_hess._get_jk(mol, 'int2e_ip1', 3, 's2kl', ['ji->s2kl', -dm0a[:,p0:p1], #vja 'ji->s2kl', -dm0b[:,p0:p1], #vjb 'li->s1kj', -dm0a[:,p0:p1], 'li->s1kj', -dm0b[:,p0:p1]], #vka shls_slice=shls_slice) vhfa = vja + vjb - hyb * vka vhfb = vjb + vja - hyb * vkb if abs(omg) > 1e-10: with mol.with_range_coulomb(omg): vka, vkb = \ rhf_hess._get_jk(mol, 'int2e_ip1', 3, 's2kl', ['li->s1kj', -dm0a[:,p0:p1], 'li->s1kj', -dm0b[:,p0:p1]], # vk1 shls_slice=shls_slice) vhfa -= (alpha-hyb) * vka vhfb -= (alpha-hyb) * vkb else: vja, vjb = rhf_hess._get_jk(mol, 'int2e_ip1', 3, 's2kl', ['ji->s2kl', -dm0a[:,p0:p1], 'ji->s2kl', -dm0b[:,p0:p1]], # vj1 shls_slice=shls_slice) vhfa = vhfb = vja + vjb vtota = h1 + v1[0] + vxc1aoa[ia] + vhfa + vhfa.transpose(0,2,1) vtotb = h1 + v1[1] + vxc1aob[ia] + vhfb + vhfb.transpose(0,2,1) vcorea.append(vtota) vcoreb.append(vtotb) vcorea = np.asarray(vcorea).reshape(-1,nao,nao) vcoreb = np.asarray(vcoreb).reshape(-1,nao,nao) mass = mol.atom_mass_list() * 1836.15 nmodes, natoms = len(omega), len(mass) vec = vec.reshape(natoms, 3, nmodes) for i in range(natoms): for j in range(nmodes): vec[i,:,j] /= np.sqrt(2*mass[i]*omega[j]) vec = vec.reshape(3*natoms,nmodes) mata = np.einsum('xJ,xuv->Juv', vec, vcorea) matb = np.einsum('xJ,xuv->Juv', vec, vcoreb) if mo_rep: mata = np.einsum('Juv,up,vq->Jpq', mata, mf.mo_coeff[0].conj(), mf.mo_coeff[0], optimize=True) matb = np.einsum('Juv,up,vq->Jpq', matb, mf.mo_coeff[1].conj(), mf.mo_coeff[1], optimize=True) return np.asarray([mata,matb])
def partial_hess_elec(hessobj, mo_energy=None, mo_coeff=None, mo_occ=None, atmlst=None, max_memory=4000, verbose=None): log = logger.new_logger(hessobj, verbose) time0 = t1 = (logger.process_clock(), logger.perf_counter()) mol = hessobj.mol mf = hessobj.base if mo_energy is None: mo_energy = mf.mo_energy if mo_occ is None: mo_occ = mf.mo_occ if mo_coeff is None: mo_coeff = mf.mo_coeff if atmlst is None: atmlst = range(mol.natm) nao, nmo = mo_coeff.shape mocc = mo_coeff[:, mo_occ > 0] dm0 = numpy.dot(mocc, mocc.T) * 2 if mf.nlc != '': raise NotImplementedError #enabling range-separated hybrids omega, alpha, beta = mf._numint.rsh_coeff(mf.xc) if abs(omega) > 1e-10: hyb = alpha + beta else: hyb = mf._numint.hybrid_coeff(mf.xc, spin=mol.spin) de2, ej, ek = rhf_hess._partial_hess_ejk(hessobj, mo_energy, mo_coeff, mo_occ, atmlst, max_memory, verbose, abs(hyb) > 1e-10) de2 += ej - hyb * ek # (A,B,dR_A,dR_B) mem_now = lib.current_memory()[0] max_memory = max(2000, mf.max_memory * .9 - mem_now) veff_diag = _get_vxc_diag(hessobj, mo_coeff, mo_occ, max_memory) if abs(omega) > 1e-10: with mol.with_range_coulomb(omega): vk1 = rhf_hess._get_jk(mol, 'int2e_ipip1', 9, 's2kl', ['jk->s1il', dm0])[0] veff_diag -= (alpha - hyb) * .5 * vk1.reshape(3, 3, nao, nao) vk1 = None t1 = log.timer_debug1('contracting int2e_ipip1', *t1) aoslices = mol.aoslice_by_atom() vxc = _get_vxc_deriv2(hessobj, mo_coeff, mo_occ, max_memory) for i0, ia in enumerate(atmlst): shl0, shl1, p0, p1 = aoslices[ia] shls_slice = (shl0, shl1) + (0, mol.nbas) * 3 veff = vxc[ia] if abs(omega) > 1e-10: with mol.with_range_coulomb(omega): vk1, vk2 = rhf_hess._get_jk( mol, 'int2e_ip1ip2', 9, 's1', [ 'li->s1kj', dm0[:, p0:p1], # vk1 'lj->s1ki', dm0 ], # vk2 shls_slice=shls_slice) veff -= (alpha - hyb) * .5 * vk1.reshape(3, 3, nao, nao) veff[:, :, :, p0:p1] -= (alpha - hyb) * .5 * vk2.reshape( 3, 3, nao, p1 - p0) t1 = log.timer_debug1( 'range-separated int2e_ip1ip2 for atom %d' % ia, *t1) with mol.with_range_coulomb(omega): vk1 = rhf_hess._get_jk( mol, 'int2e_ipvip1', 9, 's2kl', ['li->s1kj', dm0[:, p0:p1]], # vk1 shls_slice=shls_slice)[0] veff -= (alpha - hyb) * .5 * vk1.transpose(0, 2, 1).reshape( 3, 3, nao, nao) t1 = log.timer_debug1( 'range-separated int2e_ipvip1 for atom %d' % ia, *t1) vk1 = vk2 = None de2[i0, i0] += numpy.einsum('xypq,pq->xy', veff_diag[:, :, p0:p1], dm0[p0:p1]) * 2 for j0, ja in enumerate(atmlst[:i0 + 1]): q0, q1 = aoslices[ja][2:] de2[i0, j0] += numpy.einsum('xypq,pq->xy', veff[:, :, q0:q1], dm0[q0:q1]) * 2 for j0 in range(i0): de2[j0, i0] = de2[i0, j0].T log.timer('RKS partial hessian', *time0) return de2