Ejemplo n.º 1
0
def make_fc(sscobj, nuc_pair=None):
    '''Only Fermi-contact'''
    if nuc_pair is None: nuc_pair = sscobj.nuc_pair
    mol = sscobj.mol
    mo_coeff = sscobj._scf.mo_coeff
    mo_occ = sscobj._scf.mo_occ
    atm1dic, atm2dic = _uniq_atoms(nuc_pair)

    h1 = make_h1_fc(mol, mo_coeff, mo_occ, sorted(atm2dic.keys()))
    mo1aa, mo1ab, mo1ba, mo1bb = solve_mo1_fc(sscobj, h1)
    h1 = None
    h1aa, h1ab, h1ba, h1bb = make_h1_fc(mol, mo_coeff, mo_occ, sorted(atm1dic.keys()))
    para = []
    for i,j in nuc_pair:
        at1 = atm1dic[i]
        at2 = atm2dic[j]
        # If GHF orbitals are considered, spin matrices of FC+SD part can be
        # explicitly considered as below. However, it is inconsistent to RHF
        # results for closed shell systems. To make UHF and RHF code
        # consistent, only z-component is considered.
        # [See Eq. (19) of JCP 113, 3530 (2000); DOI:10.1063/1.1286806]
        if ZZ_ONLY:
            ez  = numpy.einsum('ij,ij', h1aa[at1], mo1aa[at2]) * 2  # *2 for +c.c.
            ez += numpy.einsum('ij,ij', h1bb[at1], mo1bb[at2]) * 2
            para.append(ez * numpy.eye(3))
        else:
            ez  = numpy.einsum('ij,ij', h1aa[at1], mo1aa[at2]) * 2  # *2 for +c.c.
            ez += numpy.einsum('ij,ij', h1bb[at1], mo1bb[at2]) * 2
            ex  = numpy.einsum('ij,ij', h1ab[at1], mo1ab[at2]) * 2
            ex += numpy.einsum('ij,ij', h1ba[at1], mo1ba[at2]) * 2
            ey = ex
            para.append((ex + ey + ez) / 3 * numpy.eye(3))
    return numpy.asarray(para) * nist.ALPHA**4
Ejemplo n.º 2
0
def make_fc(sscobj, nuc_pair=None):
    '''Only Fermi-contact'''
    if nuc_pair is None: nuc_pair = sscobj.nuc_pair
    mol = sscobj.mol
    mo_coeff = sscobj._scf.mo_coeff
    mo_occ = sscobj._scf.mo_occ
    atm1dic, atm2dic = _uniq_atoms(nuc_pair)

    h1 = make_h1_fc(mol, mo_coeff, mo_occ, sorted(atm2dic.keys()))
    mo1aa, mo1ab, mo1ba, mo1bb = solve_mo1_fc(sscobj, h1)
    h1 = None
    h1aa, h1ab, h1ba, h1bb = make_h1_fc(mol, mo_coeff, mo_occ, sorted(atm1dic.keys()))
    para = []
    for i,j in nuc_pair:
        at1 = atm1dic[i]
        at2 = atm2dic[j]
        # If GHF orbitals are considered, spin matrices of FC+SD part can be
        # explicitly considered as below. However, it is inconsistent to RHF
        # results for closed shell systems. To make UHF and RHF code
        # consistent, only z-component is considered.
        # (See Eq. (19) of JCP, 113, 3530)
        if ZZ_ONLY:
            ez  = numpy.einsum('ij,ij', h1aa[at1], mo1aa[at2]) * 2  # *2 for +c.c.
            ez += numpy.einsum('ij,ij', h1bb[at1], mo1bb[at2]) * 2
            para.append(ez * numpy.eye(3))
        else:
            ez  = numpy.einsum('ij,ij', h1aa[at1], mo1aa[at2]) * 2  # *2 for +c.c.
            ez += numpy.einsum('ij,ij', h1bb[at1], mo1bb[at2]) * 2
            ex  = numpy.einsum('ij,ij', h1ab[at1], mo1ab[at2]) * 2
            ex += numpy.einsum('ij,ij', h1ba[at1], mo1ba[at2]) * 2
            ey = ex
            para.append((ex + ey + ez) / 3 * numpy.eye(3))
    return numpy.asarray(para) * nist.ALPHA**4
Ejemplo n.º 3
0
def make_pso(sscobj, mol, mo1, mo_coeff, mo_occ, nuc_pair=None):
    if nuc_pair is None: nuc_pair = sscobj.nuc_pair
    atm1dic, atm2dic = _uniq_atoms(nuc_pair)
    h1a, h1b = make_h1_pso(mol, mo_coeff, mo_occ, sorted(atm1dic.keys()))
    mo1a, mo1b = mo1
    nvira, nocca = h1a[0].shape
    nvirb, noccb = h1b[0].shape
    mo1a = mo1a.reshape(len(atm2dic), 3, nvira, nocca)
    mo1b = mo1b.reshape(len(atm2dic), 3, nvirb, noccb)
    h1a = numpy.asarray(h1a).reshape(len(atm1dic), 3, nvira, nocca)
    h1b = numpy.asarray(h1b).reshape(len(atm1dic), 3, nvirb, noccb)
    para = []
    for i, j in nuc_pair:
        # PSO = -Tr(Im[h1_ov], Im[mo1_vo]) + cc = 2 * Tr(Im[h1_vo], Im[mo1_vo])
        e = numpy.einsum('xij,yij->xy', h1a[atm1dic[i]], mo1a[atm2dic[j]]) * 2
        e += numpy.einsum('xij,yij->xy', h1b[atm1dic[i]], mo1b[atm2dic[j]]) * 2
        para.append(e)
    return numpy.asarray(para) * nist.ALPHA**4
Ejemplo n.º 4
0
def make_pso(sscobj, mol, mo1, mo_coeff, mo_occ, nuc_pair=None):
    if nuc_pair is None: nuc_pair = sscobj.nuc_pair
    atm1dic, atm2dic = _uniq_atoms(nuc_pair)
    h1a, h1b = make_h1_pso(mol, mo_coeff, mo_occ, sorted(atm1dic.keys()))
    mo1a, mo1b = mo1
    nvira, nocca = h1a[0].shape
    nvirb, noccb = h1b[0].shape
    mo1a = mo1a.reshape(len(atm2dic),3,nvira,nocca)
    mo1b = mo1b.reshape(len(atm2dic),3,nvirb,noccb)
    h1a = numpy.asarray(h1a).reshape(len(atm1dic),3,nvira,nocca)
    h1b = numpy.asarray(h1b).reshape(len(atm1dic),3,nvirb,noccb)
    para = []
    for i,j in nuc_pair:
        # PSO = -Tr(Im[h1_ov], Im[mo1_vo]) + cc = 2 * Tr(Im[h1_vo], Im[mo1_vo])
        e = numpy.einsum('xij,yij->xy', h1a[atm1dic[i]], mo1a[atm2dic[j]]) * 2
        e+= numpy.einsum('xij,yij->xy', h1b[atm1dic[i]], mo1b[atm2dic[j]]) * 2
        para.append(e)
    return numpy.asarray(para) * nist.ALPHA**4
Ejemplo n.º 5
0
def make_fcsd(sscobj, nuc_pair=None):
    '''FC + SD contributions to 2nd order energy'''
    if nuc_pair is None: nuc_pair = sscobj.nuc_pair
    mol = sscobj.mol
    mo_coeff = sscobj._scf.mo_coeff
    mo_occ = sscobj._scf.mo_occ
    atm1dic, atm2dic = _uniq_atoms(nuc_pair)

    h1 = make_h1_fcsd(mol, mo_coeff, mo_occ, sorted(atm2dic.keys()))
    mo1aa, mo1ab, mo1ba, mo1bb = solve_mo1_fc(sscobj, h1)
    h1 = None
    h1aa, h1ab, h1ba, h1bb = make_h1_fcsd(mol, mo_coeff, mo_occ,
                                          sorted(atm1dic.keys()))
    mo1aa = mo1aa.reshape(h1aa.shape)
    mo1ab = mo1ab.reshape(h1ab.shape)
    mo1ba = mo1ba.reshape(h1ba.shape)
    mo1bb = mo1bb.reshape(h1bb.shape)
    para = []
    for i, j in nuc_pair:
        at1 = atm1dic[i]
        at2 = atm2dic[j]
        # If GHF orbitals are considered, spin matrices of FC+SD part can be
        # explicitly considered as below. However, it is inconsistent to RHF
        # results for closed shell systems. To make UHF and RHF code
        # consistent, only z-component is considered.
        if ZZ_ONLY:
            e = numpy.einsum('xwij,ywij->xy', h1aa[at1], mo1aa[at2])
            e += numpy.einsum('xwij,ywij->xy', h1bb[at1], mo1bb[at2])
        else:
            # x contributions
            e = numpy.einsum('xij,yij->xy', h1ab[at1, 0], mo1ab[at2, 0])
            e += numpy.einsum('xij,yij->xy', h1ba[at1, 0], mo1ba[at2, 0])
            # y contributions
            e += numpy.einsum('xij,yij->xy', h1ab[at1, 1], mo1ab[at2, 1])
            e += numpy.einsum('xij,yij->xy', h1ba[at1, 1], mo1ba[at2, 1])
            # z contribution
            e += numpy.einsum('xij,yij->xy', h1aa[at1, 2], mo1aa[at2, 2])
            e += numpy.einsum('xij,yij->xy', h1bb[at1, 2], mo1bb[at2, 2])
        para.append(e * 2)  # *2 for +c.c.
    return numpy.asarray(para) * nist.ALPHA**4
Ejemplo n.º 6
0
def make_fcsd(sscobj, nuc_pair=None):
    '''FC + SD contributions to 2nd order energy'''
    if nuc_pair is None: nuc_pair = sscobj.nuc_pair
    mol = sscobj.mol
    mo_coeff = sscobj._scf.mo_coeff
    mo_occ = sscobj._scf.mo_occ
    atm1dic, atm2dic = _uniq_atoms(nuc_pair)

    h1 = make_h1_fcsd(mol, mo_coeff, mo_occ, sorted(atm2dic.keys()))
    mo1aa, mo1ab, mo1ba, mo1bb = solve_mo1_fc(sscobj, h1)
    h1 = None
    h1aa, h1ab, h1ba, h1bb = make_h1_fcsd(mol, mo_coeff, mo_occ,
                                          sorted(atm1dic.keys()))
    nocca = numpy.count_nonzero(mo_occ[0] > 0)
    nvira = numpy.count_nonzero(mo_occ[0] == 0)
    noccb = numpy.count_nonzero(mo_occ[1] > 0)
    nvirb = numpy.count_nonzero(mo_occ[1] == 0)
    mo1aa = numpy.asarray(mo1aa).reshape(-1, 3, 3, nvira, nocca)
    mo1ab = numpy.asarray(mo1ab).reshape(-1, 3, 3, nvira, noccb)
    mo1ba = numpy.asarray(mo1ba).reshape(-1, 3, 3, nvirb, nocca)
    mo1bb = numpy.asarray(mo1bb).reshape(-1, 3, 3, nvirb, noccb)
    h1aa = numpy.asarray(h1aa).reshape(-1, 3, 3, nvira, nocca)
    h1ab = numpy.asarray(h1ab).reshape(-1, 3, 3, nvira, noccb)
    h1ba = numpy.asarray(h1ba).reshape(-1, 3, 3, nvirb, nocca)
    h1bb = numpy.asarray(h1bb).reshape(-1, 3, 3, nvirb, noccb)
    para = []
    for i, j in nuc_pair:
        at1 = atm1dic[i]
        at2 = atm2dic[j]
        # x contributions
        e = numpy.einsum('xij,yij->xy', h1ab[at1, 0], mo1ab[at2, 0])
        e += numpy.einsum('xij,yij->xy', h1ba[at1, 0], mo1ba[at2, 0])
        # y contributions
        e += numpy.einsum('xij,yij->xy', h1ab[at1, 1], mo1ab[at2, 1])
        e += numpy.einsum('xij,yij->xy', h1ba[at1, 1], mo1ba[at2, 1])
        # z contribution
        e += numpy.einsum('xij,yij->xy', h1aa[at1, 2], mo1aa[at2, 2])
        e += numpy.einsum('xij,yij->xy', h1bb[at1, 2], mo1bb[at2, 2])
        para.append(e * 2)  # *2 for +c.c.
    return numpy.asarray(para) * nist.ALPHA**4
Ejemplo n.º 7
0
def make_fcsd(sscobj, nuc_pair=None):
    '''FC + SD contributions to 2nd order energy'''
    if nuc_pair is None: nuc_pair = sscobj.nuc_pair
    mol = sscobj.mol
    mo_coeff = sscobj._scf.mo_coeff
    mo_occ = sscobj._scf.mo_occ
    atm1dic, atm2dic = _uniq_atoms(nuc_pair)

    h1 = make_h1_fcsd(mol, mo_coeff, mo_occ, sorted(atm2dic.keys()))
    mo1aa, mo1ab, mo1ba, mo1bb = solve_mo1_fc(sscobj, h1)
    h1 = None
    h1aa, h1ab, h1ba, h1bb = make_h1_fcsd(mol, mo_coeff, mo_occ, sorted(atm1dic.keys()))
    mo1aa = mo1aa.reshape(h1aa.shape)
    mo1ab = mo1ab.reshape(h1ab.shape)
    mo1ba = mo1ba.reshape(h1ba.shape)
    mo1bb = mo1bb.reshape(h1bb.shape)
    para = []
    for i,j in nuc_pair:
        at1 = atm1dic[i]
        at2 = atm2dic[j]
        # If GHF orbitals are considered, spin matrices of FC+SD part can be
        # explicitly considered as below. However, it is inconsistent to RHF
        # results for closed shell systems. To make UHF and RHF code
        # consistent, only z-component is considered.
        if ZZ_ONLY:
            e = numpy.einsum('xwij,ywij->xy', h1aa[at1], mo1aa[at2])
            e+= numpy.einsum('xwij,ywij->xy', h1bb[at1], mo1bb[at2])
        else:
            # x contributions
            e = numpy.einsum('xij,yij->xy', h1ab[at1,0], mo1ab[at2,0])
            e+= numpy.einsum('xij,yij->xy', h1ba[at1,0], mo1ba[at2,0])
            # y contributions
            e+= numpy.einsum('xij,yij->xy', h1ab[at1,1], mo1ab[at2,1])
            e+= numpy.einsum('xij,yij->xy', h1ba[at1,1], mo1ba[at2,1])
            # z contribution
            e+= numpy.einsum('xij,yij->xy', h1aa[at1,2], mo1aa[at2,2])
            e+= numpy.einsum('xij,yij->xy', h1bb[at1,2], mo1bb[at2,2])
        para.append(e*2)  # *2 for +c.c.
    return numpy.asarray(para) * nist.ALPHA**4
Ejemplo n.º 8
0
def make_fc(sscobj, nuc_pair=None):
    '''Only Fermi-contact'''
    if nuc_pair is None: nuc_pair = sscobj.nuc_pair
    mol = sscobj.mol
    mo_coeff = sscobj._scf.mo_coeff
    mo_occ = sscobj._scf.mo_occ
    atm1dic, atm2dic = _uniq_atoms(nuc_pair)

    h1 = make_h1_fc(mol, mo_coeff, mo_occ, sorted(atm2dic.keys()))
    mo1aa, mo1ab, mo1ba, mo1bb = solve_mo1_fc(sscobj, h1)
    h1 = None
    h1aa, h1ab, h1ba, h1bb = make_h1_fc(mol, mo_coeff, mo_occ, sorted(atm1dic.keys()))
    para = []
    for i,j in nuc_pair:
        at1 = atm1dic[i]
        at2 = atm2dic[j]
        ez  = numpy.einsum('ij,ij', h1aa[at1], mo1aa[at2]) * 2  # *2 for +c.c.
        ez += numpy.einsum('ij,ij', h1bb[at1], mo1bb[at2]) * 2
        ex  = numpy.einsum('ij,ij', h1ab[at1], mo1ab[at2]) * 2
        ex += numpy.einsum('ij,ij', h1ba[at1], mo1ba[at2]) * 2
        ey = ex
        para.append(numpy.diag([ex,ey,ez]))
    return numpy.asarray(para) * lib.param.ALPHA**4