def make_para_soc2e(gobj, dm0, dm10, sso_qed_fac=1): if isinstance(gobj.para_soc2e, str): with_sso = 'SSO' in gobj.para_soc2e.upper() with_soo = 'SOO' in gobj.para_soc2e.upper() with_somf = 'SOMF' in gobj.para_soc2e.upper() with_amfi = 'AMFI' in gobj.para_soc2e.upper() assert(not (with_somf and (with_sso or with_soo))) elif gobj.para_soc2e: with_sso = with_soo = True with_somf = with_amfi = False else: with_sso = with_soo = with_somf = False with_amfi = True mol = gobj.mol alpha2 = nist.ALPHA ** 2 effspin = mol.spin * .5 muB = .5 # Bohr magneton #sso_qed_fac = (nist.G_ELECTRON - 1) mf = gobj._scf ni = mf._numint omega, alpha, hyb = ni.rsh_and_hybrid_coeff(mf.xc, spin=mol.spin) if abs(omega) > 1e-10: raise NotImplementedError mem_now = lib.current_memory()[0] max_memory = max(2000, mf.max_memory*.9-mem_now) v1 = get_vxc_soc(ni, mol, mf.grids, mf.xc, dm0, max_memory=max_memory, verbose=gobj.verbose) dm10a, dm10b = dm10 if with_somf: ej = numpy.einsum('yil,xli->xy', v1[0]+v1[1], dm10a-dm10b) else: ej = numpy.einsum('yil,xli->xy', v1[0], dm10a) ej -= numpy.einsum('yil,xli->xy', v1[1], dm10b) #ej *= -2 #Veff(-2X) approximation of JCP 122 034107 gpara2e = 0 if abs(hyb) > 1e-10: if with_amfi: vj, vk = uhf_g.get_jk_amfi(mol, dm0) else: vj, vk = uhf_g.get_jk(mol, dm0) if with_sso or with_soo: ek = numpy.einsum('yil,xli->xy', vk[0], dm10a) ek -= numpy.einsum('yil,xli->xy', vk[1], dm10b) if with_sso: ej += numpy.einsum('yij,xji->xy', vj[0]+vj[1], dm10a-dm10b) gpara2e -= sso_qed_fac * (ej - hyb * ek) if with_soo: ej += numpy.einsum('yij,xji->xy', vj[0]-vj[1], dm10a+dm10b) gpara2e -= 2 * (ej - hyb * ek) else: # SOMF, see JCP 122, 034107 Eq (19) ej += numpy.einsum('yij,xji->xy', vj[0]+vj[1], dm10a-dm10b) ek = numpy.einsum('yil,xli->xy', vk[0]+vk[1], dm10a-dm10b) gpara2e -= ej - 1.5 * hyb * ek else: if with_amfi: vj = uhf_g.get_j_amfi(mol, dm0) else: vj = uhf_g.get_j(mol, dm0) if with_sso or with_soo: if with_sso: ej += numpy.einsum('yij,xji->xy', vj[0]+vj[1], dm10a-dm10b) gpara2e -= sso_qed_fac * ej if with_soo: ej += numpy.einsum('yij,xji->xy', vj[0]-vj[1], dm10a+dm10b) gpara2e -= 2 * ej else: # SOMF, see JCP 122, 034107 Eq (19) ej += numpy.einsum('yij,xji->xy', vj[0]+vj[1], dm10a-dm10b) gpara2e -= ej gpara2e *= (alpha2/4) / effspin / muB if gobj.verbose >= logger.INFO: _write(gobj, align(gpara2e)[0], 'SOC(2e)/OZ') return gpara2e