Beispiel #1
0
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
Beispiel #2
0
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