def kernel(mf, disp=1e-4, mo_rep=False): if not mf.converged: mf.kernel() mo_coeff = np.asarray(mf.mo_coeff) RESTRICTED = (mo_coeff.ndim == 3) cell = mf.cell cells_a, cells_b = gen_cells( cell, disp / 2.0) # generate a bunch of cells with disp/2 on each cartesion coord mfset = run_mfs(mf, cells_a, cells_b) # run mean field calculations on all these cells vmat = get_vmat(mf, mfset, disp) # extracting <u|dV|v>/dR hmat = run_hess(mfset, disp) omega, vec = solve_hmat(cell, hmat) mass = cell.atom_mass_list() * MP_ME vec = _freq_mass_weighted_vec(vec, omega, mass) if mo_rep: if RESTRICTED: vmat = np.einsum('xuv,up,vq->xpq', vmat, mo_coeff[0].conj(), mo_coeff[0]) else: vmat = np.einsum('xsuv,sup,svq->xspq', vmat, mo_coeff[:, 0].conj(), mo_coeff[:, 0]) if RESTRICTED: mat = np.einsum('xJ,xpq->Jpq', vec, vmat) else: mat = np.einsum('xJ,xspq->sJpq', vec, vmat) return mat, omega
def kernel(mf, disp=1e-4, mo_rep=False, cutoff_frequency=CUTOFF_FREQUENCY, keep_imag_frequency=KEEP_IMAG_FREQUENCY): if hasattr(mf, 'xc'): mf.grids.build() if not mf.converged: mf.kernel() RESTRICTED = (mf.mo_coeff.ndim == 2) mol = mf.mol omega, vec = get_mode(mf, cutoff_frequency, keep_imag_frequency) mass = mol.atom_mass_list() * MP_ME vec = rhf_eph._freq_mass_weighted_vec(vec, omega, mass) mols_a, mols_b = gen_moles( mol, disp / 2.0 ) # generate a bunch of molecules with disp/2 on each cartesion coord mfset = run_mfs( mf, mols_a, mols_b) # run mean field calculations on all these molecules vmat = get_vmat(mf, mfset, disp) # extracting <p|dV|q>/dR if mo_rep: if RESTRICTED: vmat = np.einsum('xuv,up,vq->xpq', vmat, mf.mo_coeff.conj(), mf.mo_coeff) else: vmat = np.einsum('xsuv,sup,svq->xspq', vmat, mf.mo_coeff.conj(), mf.mo_coeff) if RESTRICTED: mat = np.einsum('xJ,xpq->Jpq', vec, vmat) else: mat = np.einsum('xJ,xspq->sJpq', vec, vmat) return mat, omega
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 = 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() * 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])