Beispiel #1
0
    def test_shls_slice1(self):
        mol = gto.M(atom='H 0 -.5 0; H 0 .5 0', basis='cc-pvdz')
        nao = mol.nao_nr()
        dm = numpy.random.random((nao,nao))
        mol1 = gto.M(atom='He 2 0 0', basis='6-31g')
        nao1 = mol1.nao_nr()
        dm1 = numpy.random.random((nao1,nao1))
        eri0 = gto.conc_mol(mol, mol1).intor('int2e_sph').reshape([nao+nao1]*4)

        j1part = jk.get_jk((mol1,mol1,mol,mol), dm1[:1,:1], scripts='ijkl,ji->kl', intor='int2e',
                           shls_slice=(0,1,0,1,0,mol.nbas,0,mol.nbas))
        j1ref = numpy.einsum('ijkl,ji->kl', eri0[nao:nao+1,nao:nao+1,:nao,:nao], dm1[:1,:1])
        self.assertAlmostEqual(abs(j1part - j1ref).max(), 0, 12)

        k1part = jk.get_jk((mol1,mol,mol,mol1), dm1[:,:1], scripts='ijkl,li->kj', intor='int2e',
                           shls_slice=(0,1,0,1,0,mol.nbas,0,mol1.nbas))
        k1ref = numpy.einsum('ijkl,li->kj', eri0[nao:nao+1,:1,:nao,nao:], dm1[:,:1])
        self.assertAlmostEqual(abs(k1part - k1ref).max(), 0, 12)

        j1part = jk.get_jk(mol, dm[:1,1:2], scripts='ijkl,ji->kl', intor='int2e',
                           shls_slice=(1,2,0,1,0,mol.nbas,0,mol.nbas))
        j1ref = numpy.einsum('ijkl,ji->kl', eri0[1:2,:1,:nao,:nao], dm[:1,1:2])
        self.assertAlmostEqual(abs(j1part - j1ref).max(), 0, 12)

        k1part = jk.get_jk(mol, dm[:,1:2], scripts='ijkl,li->kj', intor='int2e',
                           shls_slice=(1,2,0,1,0,mol.nbas,0,mol.nbas))
        k1ref = numpy.einsum('ijkl,li->kj', eri0[:1,1:2,:nao,:nao], dm[:,1:2])
        self.assertAlmostEqual(abs(k1part - k1ref).max(), 0, 12)
Beispiel #2
0
def dia(magobj, gauge_orig=None):
    mol = magobj.mol
    mf = magobj._scf
    mo_energy = magobj._scf.mo_energy
    mo_coeff = magobj._scf.mo_coeff
    mo_occ = magobj._scf.mo_occ
    orboa = mo_coeff[0][:,mo_occ[0] > 0]
    orbob = mo_coeff[1][:,mo_occ[1] > 0]
    dm0a = numpy.dot(orboa, orboa.T)
    dm0b = numpy.dot(orbob, orbob.T)
    dm0 = dm0a + dm0b
    dme0a = numpy.dot(orboa * mo_energy[0][mo_occ[0] > 0], orboa.T)
    dme0b = numpy.dot(orbob * mo_energy[1][mo_occ[1] > 0], orbob.T)
    dme0 = dme0a + dme0b

    e2 = rhf_mag._get_dia_1e(magobj, gauge_orig, dm0, dme0).ravel()

    if gauge_orig is None:
        vs = jk.get_jk(mol, [dm0, dm0a, dm0a, dm0b, dm0b],
                       ['ijkl,ji->s2kl',
                        'ijkl,jk->s1il', 'ijkl,li->s1kj',
                        'ijkl,jk->s1il', 'ijkl,li->s1kj'],
                       'int2e_gg1', 's4', 9, hermi=1)
        e2 += numpy.einsum('xpq,qp->x', vs[0], dm0)
        e2 -= numpy.einsum('xpq,qp->x', vs[1], dm0a) * .5
        e2 -= numpy.einsum('xpq,qp->x', vs[2], dm0a) * .5
        e2 -= numpy.einsum('xpq,qp->x', vs[3], dm0b) * .5
        e2 -= numpy.einsum('xpq,qp->x', vs[4], dm0b) * .5

        vk = jk.get_jk(mol, [dm0a, dm0b], ['ijkl,jk->s1il', 'ijkl,jk->s1il'],
                       'int2e_g1g2', 'aa4', 9, hermi=0)
        e2 -= numpy.einsum('xpq,qp->x', vk[0], dm0a)
        e2 -= numpy.einsum('xpq,qp->x', vk[1], dm0b)

    return -e2.reshape(3, 3)
Beispiel #3
0
    def test_shls_slice1(self):
        mol = gto.M(atom='H 0 -.5 0; H 0 .5 0', basis='cc-pvdz')
        nao = mol.nao_nr()
        dm = numpy.random.random((nao,nao))
        mol1 = gto.M(atom='He 2 0 0', basis='6-31g')
        nao1 = mol1.nao_nr()
        dm1 = numpy.random.random((nao1,nao1))
        eri0 = gto.conc_mol(mol, mol1).intor('int2e_sph').reshape([nao+nao1]*4)

        j1part = jk.get_jk((mol1,mol1,mol,mol), dm1[:1,:1], scripts='ijkl,ji->kl', intor='int2e',
                           shls_slice=(0,1,0,1,0,mol.nbas,0,mol.nbas))
        j1ref = numpy.einsum('ijkl,ji->kl', eri0[nao:nao+1,nao:nao+1,:nao,:nao], dm1[:1,:1])
        self.assertAlmostEqual(abs(j1part - j1ref).max(), 0, 12)

        k1part = jk.get_jk((mol1,mol,mol,mol1), dm1[:,:1], scripts='ijkl,li->kj', intor='int2e',
                           shls_slice=(0,1,0,1,0,mol.nbas,0,mol1.nbas))
        k1ref = numpy.einsum('ijkl,li->kj', eri0[nao:nao+1,:1,:nao,nao:], dm1[:,:1])
        self.assertAlmostEqual(abs(k1part - k1ref).max(), 0, 12)

        j1part = jk.get_jk(mol, dm[:1,1:2], scripts='ijkl,ji->kl', intor='int2e',
                           shls_slice=(1,2,0,1,0,mol.nbas,0,mol.nbas))
        j1ref = numpy.einsum('ijkl,ji->kl', eri0[1:2,:1,:nao,:nao], dm[:1,1:2])
        self.assertAlmostEqual(abs(j1part - j1ref).max(), 0, 12)

        k1part = jk.get_jk(mol, dm[:,1:2], scripts='ijkl,li->kj', intor='int2e',
                           shls_slice=(1,2,0,1,0,mol.nbas,0,mol.nbas))
        k1ref = numpy.einsum('ijkl,li->kj', eri0[:1,1:2,:nao,:nao], dm[:,1:2])
        self.assertAlmostEqual(abs(k1part - k1ref).max(), 0, 12)
Beispiel #4
0
def dia(magobj, gauge_orig=None):
    '''Diamagnetic term of magnetizability.

    See also J. Olsen et al., Theor. Chem. Acc., 90, 421 (1995)
    '''
    mol = magobj.mol
    mf = magobj._scf
    mo_energy = mf.mo_energy
    mo_coeff = mf.mo_coeff
    mo_occ = mf.mo_occ
    orbo = mo_coeff[:, mo_occ > 0]
    dm0 = numpy.dot(orbo, orbo.T) * 2
    # Energy weighted density matrix
    dme0 = numpy.dot(orbo * mo_energy[mo_occ > 0], orbo.T) * 2

    e2 = _get_dia_1e(magobj, gauge_orig, dm0, dme0)

    # Add the contributions from two-electron interactions
    if gauge_orig is None:
        e2 = e2.ravel()
        # + 1/2 Tr[(J^{[20]} - K^{[20]}), DM]
        # Symmetry between 'ijkl,ji->s2kl' and 'ijkl,lk->s2ij' can be used.
        #vs = jk.get_jk(mol, [dm0]*4, ['ijkl,ji->s2kl',
        #                              'ijkl,lk->s2ij',
        #                              'ijkl,jk->s1il',
        #                              'ijkl,li->s1kj'],
        #               'int2e_gg1', 's4', 9, hermi=1)
        #e2 += numpy.einsum('xpq,qp->x', vs[0], dm0) * .5
        #e2 += numpy.einsum('xpq,qp->x', vs[1], dm0) * .5
        #e2 -= numpy.einsum('xpq,qp->x', vs[2], dm0) * .25
        #e2 -= numpy.einsum('xpq,qp->x', vs[3], dm0) * .25
        vs = jk.get_jk(mol, [dm0] * 3,
                       ['ijkl,ji->s2kl', 'ijkl,jk->s1il', 'ijkl,li->s1kj'],
                       'int2e_gg1',
                       's4',
                       9,
                       hermi=1)
        e2 += numpy.einsum('xpq,qp->x', vs[0], dm0)
        e2 -= numpy.einsum('xpq,qp->x', vs[1], dm0) * .25
        e2 -= numpy.einsum('xpq,qp->x', vs[2], dm0) * .25

        # J does not have contribution because integrals are anti-symmetric
        #vs = jk.get_jk(mol, [dm0]*2, ['ijkl,ji->s2kl',
        #                              'ijkl,jk->s1il'],
        #               'int2e_g1g2', 'aa4', 9, hermi=0)
        #e2 += numpy.einsum('xpq,qp->x', vs[0], dm0)
        #e2 -= numpy.einsum('xpq,qp->x', vs[1], dm0) * .5
        vk = jk.get_jk(mol,
                       dm0,
                       'ijkl,jk->s1il',
                       'int2e_g1g2',
                       'aa4',
                       9,
                       hermi=0)
        e2 -= numpy.einsum('xpq,qp->x', vk, dm0) * .5

    # Note the sign of magnetizability (ksi) in the Talyor expansion
    #   E(B) = E0 - m * B - 1/2 B ksi B + ...
    # Magnetic susceptibility chi = mu0 * ksi
    return -e2.reshape(3, 3)
Beispiel #5
0
def get_vk_s4(mol, dm):
    ao_loc = mol.ao_loc_nr()
    nao = ao_loc[-1]
    vk = numpy.zeros((nao,nao))
    bas_groups = list(lib.prange(0, mol.nbas, 3))
    for ip, (ish0, ish1) in enumerate(bas_groups):
        for jp, (jsh0, jsh1) in enumerate(bas_groups[:ip]):
            for kp, (ksh0, ksh1) in enumerate(bas_groups):
                for lp, (lsh0, lsh1) in enumerate(bas_groups[:kp]):
                    shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
                    i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
                    dms = [dm[j0:j1,k0:k1],
                           dm[i0:i1,k0:k1],
                           dm[j0:j1,l0:l1],
                           dm[i0:i1,l0:l1]]
                    scripts = ['ijkl,jk->il',
                               'ijkl,ik->jl',
                               'ijkl,jl->ik',
                               'ijkl,il->jk']
                    kparts = jk.get_jk(mol, dms, scripts, shls_slice=shls_slice)
                    vk[i0:i1,l0:l1] += kparts[0]
                    vk[j0:j1,l0:l1] += kparts[1]
                    vk[i0:i1,k0:k1] += kparts[2]
                    vk[j0:j1,k0:k1] += kparts[3]

                lsh0, lsh1 = ksh0, ksh1
                shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
                i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
                kparts = jk.get_jk(mol,
                                   [dm[j0:j1,k0:k1], dm[i0:i1,k0:k1]],
                                   scripts=['ijkl,jk->il', 'ijkl,ik->jl'],
                                   shls_slice=shls_slice)
                vk[i0:i1,l0:l1] += kparts[0]
                vk[j0:j1,l0:l1] += kparts[1]

        jsh0, jsh1 = ish0, ish1
        for kp, (ksh0, ksh1) in enumerate(bas_groups):
            for lp, (lsh0, lsh1) in enumerate(bas_groups[:kp]):
                shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
                i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
                kparts = jk.get_jk(mol,
                                   [dm[j0:j1,k0:k1], dm[j0:j1,l0:l1]],
                                   scripts=['ijkl,jk->il', 'ijkl,jl->ik'],
                                   shls_slice=shls_slice)
                vk[i0:i1,l0:l1] += kparts[0]
                vk[j0:j1,k0:k1] += kparts[1]

            lsh0, lsh1 = ksh0, ksh1
            shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
            i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
            kparts = jk.get_jk(mol,
                               [dm[j0:j1,k0:k1]],
                               scripts=['ijkl,jk->il'],
                               shls_slice=shls_slice)
            vk[i0:i1,l0:l1] += kparts[0]
    return vk
Beispiel #6
0
def get_vk_s4(mol, dm):
    ao_loc = mol.ao_loc_nr()
    nao = ao_loc[-1]
    vk = numpy.zeros((nao,nao))
    bas_groups = list(lib.prange(0, mol.nbas, 3))
    for ip, (ish0, ish1) in enumerate(bas_groups):
        for jp, (jsh0, jsh1) in enumerate(bas_groups[:ip]):
            for kp, (ksh0, ksh1) in enumerate(bas_groups):
                for lp, (lsh0, lsh1) in enumerate(bas_groups[:kp]):
                    shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
                    i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
                    dms = [dm[j0:j1,k0:k1],
                           dm[i0:i1,k0:k1],
                           dm[j0:j1,l0:l1],
                           dm[i0:i1,l0:l1]]
                    scripts = ['ijkl,jk->il',
                               'ijkl,ik->jl',
                               'ijkl,jl->ik',
                               'ijkl,il->jk']
                    kparts = jk.get_jk(mol, dms, scripts, shls_slice=shls_slice)
                    vk[i0:i1,l0:l1] += kparts[0]
                    vk[j0:j1,l0:l1] += kparts[1]
                    vk[i0:i1,k0:k1] += kparts[2]
                    vk[j0:j1,k0:k1] += kparts[3]

                lsh0, lsh1 = ksh0, ksh1
                shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
                i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
                kparts = jk.get_jk(mol,
                                   [dm[j0:j1,k0:k1], dm[i0:i1,k0:k1]],
                                   scripts=['ijkl,jk->il', 'ijkl,ik->jl'],
                                   shls_slice=shls_slice)
                vk[i0:i1,l0:l1] += kparts[0]
                vk[j0:j1,l0:l1] += kparts[1]

        jsh0, jsh1 = ish0, ish1
        for kp, (ksh0, ksh1) in enumerate(bas_groups):
            for lp, (lsh0, lsh1) in enumerate(bas_groups[:kp]):
                shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
                i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
                kparts = jk.get_jk(mol,
                                   [dm[j0:j1,k0:k1], dm[j0:j1,l0:l1]],
                                   scripts=['ijkl,jk->il', 'ijkl,jl->ik'],
                                   shls_slice=shls_slice)
                vk[i0:i1,l0:l1] += kparts[0]
                vk[j0:j1,k0:k1] += kparts[1]

            lsh0, lsh1 = ksh0, ksh1
            shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
            i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
            kparts = jk.get_jk(mol,
                               [dm[j0:j1,k0:k1]],
                               scripts=['ijkl,jk->il'],
                               shls_slice=shls_slice)
            vk[i0:i1,l0:l1] += kparts[0]
    return vk
Beispiel #7
0
def dia(magobj, gauge_orig=None):
    '''Diamagnetic term of magnetizability.

    See also J. Olsen et al., Theor. Chem. Acc., 90, 421 (1995)
    '''
    mol = magobj.mol
    mf = magobj._scf
    mo_energy = mf.mo_energy
    mo_coeff = mf.mo_coeff
    mo_occ = mf.mo_occ
    orbo = mo_coeff[:,mo_occ > 0]
    dm0 = numpy.dot(orbo, orbo.T) * 2
    # Energy weighted density matrix
    dme0 = numpy.dot(orbo * mo_energy[mo_occ > 0], orbo.T) * 2

    e2 = _get_dia_1e(magobj, gauge_orig, dm0, dme0)

    # Add the contributions from two-electron interactions
    if gauge_orig is None:
        e2 = e2.ravel()
        # + 1/2 Tr[(J^{[20]} - K^{[20]}), DM]
        # Symmetry between 'ijkl,ji->s2kl' and 'ijkl,lk->s2ij' can be used.
        #vs = jk.get_jk(mol, [dm0]*4, ['ijkl,ji->s2kl',
        #                              'ijkl,lk->s2ij',
        #                              'ijkl,jk->s1il',
        #                              'ijkl,li->s1kj'],
        #               'int2e_gg1', 's4', 9, hermi=1)
        #e2 += numpy.einsum('xpq,qp->x', vs[0], dm0) * .5
        #e2 += numpy.einsum('xpq,qp->x', vs[1], dm0) * .5
        #e2 -= numpy.einsum('xpq,qp->x', vs[2], dm0) * .25
        #e2 -= numpy.einsum('xpq,qp->x', vs[3], dm0) * .25
        vs = jk.get_jk(mol, [dm0]*3, ['ijkl,ji->s2kl',
                                      'ijkl,jk->s1il',
                                      'ijkl,li->s1kj'],
                       'int2e_gg1', 's4', 9, hermi=1)
        e2 += numpy.einsum('xpq,qp->x', vs[0], dm0)
        e2 -= numpy.einsum('xpq,qp->x', vs[1], dm0) * .25
        e2 -= numpy.einsum('xpq,qp->x', vs[2], dm0) * .25

        # J does not have contribution because integrals are anti-symmetric
        #vs = jk.get_jk(mol, [dm0]*2, ['ijkl,ji->s2kl',
        #                              'ijkl,jk->s1il'],
        #               'int2e_g1g2', 'aa4', 9, hermi=0)
        #e2 += numpy.einsum('xpq,qp->x', vs[0], dm0)
        #e2 -= numpy.einsum('xpq,qp->x', vs[1], dm0) * .5
        vk = jk.get_jk(mol, dm0, 'ijkl,jk->s1il',
                       'int2e_g1g2', 'aa4', 9, hermi=0)
        e2 -= numpy.einsum('xpq,qp->x', vk, dm0) * .5

    # Note the sign of magnetizability (ksi) in the Talyor expansion
    #   E(B) = E0 - m * B - 1/2 B ksi B + ...
    # Magnetic susceptibility chi = mu0 * ksi
    return -e2.reshape(3, 3)
Beispiel #8
0
    def test_range_separated_Coulomb(self):
        '''test range-separated Coulomb'''
        with mol.with_range_coulomb(0.2):
            dm = mf.make_rdm1()
            vk0 = jk.get_jk(mol, dm, 'ijkl,jk->il', hermi=0)
            vk1 = jk.get_jk(mol, (dm,dm), ['ijkl,jk->il','ijkl,li->kj'], hermi=1)
            self.assertAlmostEqual(abs(vk1[0]-vk0).max(), 0, 9)
            self.assertAlmostEqual(abs(vk1[1]-vk0).max(), 0, 9)
            self.assertAlmostEqual(lib.finger(vk0), 0.87325708945599279, 9)

            vk = scf.hf.get_jk(mol, dm)[1]
            self.assertAlmostEqual(abs(vk-vk0).max(), 0, 12)
        vk = scf.hf.get_jk(mol, dm)[1]
        self.assertTrue(abs(vk-vk0).max() > 0.1)
Beispiel #9
0
    def test_range_separated_Coulomb(self):
        '''test range-separated Coulomb'''
        with mol.with_range_coulomb(0.2):
            dm = mf.make_rdm1()
            vk0 = jk.get_jk(mol, dm, 'ijkl,jk->il', hermi=0)
            vk1 = jk.get_jk(mol, (dm,dm), ['ijkl,jk->il','ijkl,li->kj'], hermi=1)
            self.assertAlmostEqual(abs(vk1[0]-vk0).max(), 0, 9)
            self.assertAlmostEqual(abs(vk1[1]-vk0).max(), 0, 9)
            self.assertAlmostEqual(lib.finger(vk0), 0.87325708945599279, 9)

            vk = scf.hf.get_jk(mol, dm)[1]
            self.assertAlmostEqual(abs(vk-vk0).max(), 0, 12)
        vk = scf.hf.get_jk(mol, dm)[1]
        self.assertTrue(abs(vk-vk0).max() > 0.1)
Beispiel #10
0
def _get_k_lr(mol, dm, omega=0, hermi=0, vhfopt=None):
    import sys
    sys.stderr.write('This function is deprecated. '
                     'It is replaced by mol.get_k(mol, dm, omege=omega)')
    dm = numpy.asarray(dm)
    # Note, ks object caches the ERIs for small systems. The cached eris are
    # computed with regular Coulomb operator. ks.get_jk or ks.get_k do not evalute
    # the K matrix with the range separated Coulomb operator.  Here jk.get_jk
    # function computes the K matrix with the modified Coulomb operator.
    nao = dm.shape[-1]
    dms = dm.reshape(-1, nao, nao)
    with mol.with_range_coulomb(omega):
        # Compute the long range part of ERIs temporarily with omega. Restore
        # the original omega when the block ends
        if vhfopt is None:
            contents = lambda: None  # just a place_holder
        else:
            contents = vhfopt._this.contents
        with lib.temporary_env(
                contents, fprescreen=_vhf._fpointer('CVHFnrs8_vk_prescreen')):
            intor = mol._add_suffix('int2e')
            vklr = jk.get_jk(mol,
                             dms, ['ijkl,jk->il'] * len(dms),
                             intor=intor,
                             vhfopt=vhfopt)
    return numpy.asarray(vklr).reshape(dm.shape)
Beispiel #11
0
    def test_vk_s8(self):
        mol = gto.M(atom='H 0 -.5 0; H 0 .5 0; H 1.1 0.2 0.2; H 0.6 0.5 0.4',
                    basis='cc-pvdz')
        ao_loc = mol.ao_loc_nr()
        eri0 = mol.intor('int2e')
        nao = mol.nao
        numpy.random.seed(1)
        dm = numpy.random.random((nao,nao))

        vk0 = numpy.einsum('ijkl,jk->il', eri0, dm)
        self.assertAlmostEqual(abs(vk0-get_vk_s4(mol, dm)).max(), 0, 12)
        self.assertAlmostEqual(abs(vk0-get_vk_s8(mol, dm)).max(), 0, 12)

        shls_slice = (2,4,0,2,0,8,0,5)
        i0,i1,j0,j1,k0,k1,l0,l1 = [ao_loc[x] for x in shls_slice]
        vk0 = numpy.einsum('ijkl,jk->il', eri0[i0:i1,j0:j1,k0:k1,l0:l1], dm[j0:j1,k0:k1])
        vk1 = numpy.einsum('ijkl,jl->ik', eri0[i0:i1,j0:j1,k0:k1,l0:l1], dm[j0:j1,l0:l1])
        vk2 = numpy.einsum('ijkl,ik->jl', eri0[i0:i1,j0:j1,k0:k1,l0:l1], dm[i0:i1,k0:k1])
        vk3 = numpy.einsum('ijkl,il->jk', eri0[i0:i1,j0:j1,k0:k1,l0:l1], dm[i0:i1,l0:l1])
        vk = jk.get_jk(mol,
                       [dm[j0:j1,k0:k1], dm[j0:j1,l0:l1], dm[i0:i1,k0:k1], dm[i0:i1,l0:l1]],
                       scripts=['ijkl,jk->il', 'ijkl,jl->ik', 'ijkl,ik->jl', 'ijkl,il->jk'],
                       shls_slice=shls_slice)
        self.assertAlmostEqual(abs(vk0-vk[0]).max(), 0, 12)
        self.assertAlmostEqual(abs(vk1-vk[1]).max(), 0, 12)
        self.assertAlmostEqual(abs(vk2-vk[2]).max(), 0, 12)
        self.assertAlmostEqual(abs(vk3-vk[3]).max(), 0, 12)
Beispiel #12
0
    def test_vk_s8(self):
        mol = gto.M(atom='H 0 -.5 0; H 0 .5 0; H 1.1 0.2 0.2; H 0.6 0.5 0.4',
                    basis='cc-pvdz')
        ao_loc = mol.ao_loc_nr()
        eri0 = mol.intor('int2e')
        nao = mol.nao
        numpy.random.seed(1)
        dm = numpy.random.random((nao,nao))

        vk0 = numpy.einsum('ijkl,jk->il', eri0, dm)
        self.assertAlmostEqual(abs(vk0-get_vk_s4(mol, dm)).max(), 0, 12)
        self.assertAlmostEqual(abs(vk0-get_vk_s8(mol, dm)).max(), 0, 12)

        shls_slice = (2,4,0,2,0,8,0,5)
        i0,i1,j0,j1,k0,k1,l0,l1 = [ao_loc[x] for x in shls_slice]
        vk0 = numpy.einsum('ijkl,jk->il', eri0[i0:i1,j0:j1,k0:k1,l0:l1], dm[j0:j1,k0:k1])
        vk1 = numpy.einsum('ijkl,jl->ik', eri0[i0:i1,j0:j1,k0:k1,l0:l1], dm[j0:j1,l0:l1])
        vk2 = numpy.einsum('ijkl,ik->jl', eri0[i0:i1,j0:j1,k0:k1,l0:l1], dm[i0:i1,k0:k1])
        vk3 = numpy.einsum('ijkl,il->jk', eri0[i0:i1,j0:j1,k0:k1,l0:l1], dm[i0:i1,l0:l1])
        vk = jk.get_jk(mol,
                       [dm[j0:j1,k0:k1], dm[j0:j1,l0:l1], dm[i0:i1,k0:k1], dm[i0:i1,l0:l1]],
                       scripts=['ijkl,jk->il', 'ijkl,jl->ik', 'ijkl,ik->jl', 'ijkl,il->jk'],
                       shls_slice=shls_slice)
        self.assertAlmostEqual(abs(vk0-vk[0]).max(), 0, 12)
        self.assertAlmostEqual(abs(vk1-vk[1]).max(), 0, 12)
        self.assertAlmostEqual(abs(vk2-vk[2]).max(), 0, 12)
        self.assertAlmostEqual(abs(vk3-vk[3]).max(), 0, 12)
Beispiel #13
0
 def test_mols(self):
     pmol = copy.copy(mol)
     mols = (mol, pmol, pmol, mol)
     dm = mf.make_rdm1()
     vj0 = jk.get_jk(mols, dm, 'ijkl,lk->ij')
     vj1 = scf.hf.get_jk(mol, dm)[0]
     self.assertAlmostEqual(abs(vj1-vj0).max(), 0, 9)
     self.assertAlmostEqual(lib.finger(vj0), 28.36214139459754, 9)
Beispiel #14
0
def jk_ints(molA, molB, dm_ia, dm_jb):
    from pyscf.scf import jk, _vhf
    naoA = molA.nao
    naoB = molB.nao
    assert (dm_ia.shape == (naoA, naoA))
    assert (dm_jb.shape == (naoB, naoB))

    molAB = molA + molB
    vhfopt = _vhf.VHFOpt(molAB, 'int2e', 'CVHFnrs8_prescreen',
                         'CVHFsetnr_direct_scf', 'CVHFsetnr_direct_scf_dm')
    dmAB = scipy.linalg.block_diag(dm_ia, dm_jb)
    # The prescreen function CVHFnrs8_prescreen indexes q_cond and dm_cond
    # over the entire basis.  "set_dm" in function jk.get_jk/direct_bindm only
    # creates a subblock of dm_cond which is not compatible with
    # CVHFnrs8_prescreen.
    vhfopt.set_dm(dmAB, molAB._atm, molAB._bas, molAB._env)
    # Then skip the "set_dm" initialization in function jk.get_jk/direct_bindm.
    vhfopt._dmcondname = None

    with lib.temporary_env(vhfopt._this.contents,
                           fprescreen=_vhf._fpointer('CVHFnrs8_vj_prescreen')):
        shls_slice = (0, molA.nbas, 0, molA.nbas, molA.nbas, molAB.nbas,
                      molA.nbas, molAB.nbas)  # AABB
        vJ = jk.get_jk(molAB,
                       dm_jb,
                       'ijkl,lk->s2ij',
                       shls_slice=shls_slice,
                       vhfopt=vhfopt,
                       aosym='s4',
                       hermi=1)
        cJ = np.einsum('ia,ia->', vJ, dm_ia)

    with lib.temporary_env(vhfopt._this.contents,
                           fprescreen=_vhf._fpointer('CVHFnrs8_vk_prescreen')):
        shls_slice = (0, molA.nbas, molA.nbas, molAB.nbas, molA.nbas,
                      molAB.nbas, 0, molA.nbas)  # ABBA
        vK = jk.get_jk(molAB,
                       dm_jb,
                       'ijkl,jk->il',
                       shls_slice=shls_slice,
                       vhfopt=vhfopt,
                       aosym='s1',
                       hermi=0)
        cK = np.einsum('ia,ia->', vK, dm_ia)

    return cJ, cK
Beispiel #15
0
 def test_mols(self):
     pmol = copy.copy(mol)
     mols = (mol, pmol, pmol, mol)
     dm = mf.make_rdm1()
     vj0 = jk.get_jk(mols, dm, 'ijkl,lk->ij')
     vj1 = scf.hf.get_jk(mol, dm)[0]
     self.assertAlmostEqual(abs(vj1-vj0).max(), 0, 9)
     self.assertAlmostEqual(lib.finger(vj0), 28.36214139459754, 9)
Beispiel #16
0
    def test_shls_slice(self):
        dm = mf.make_rdm1()
        ao_loc = mol.ao_loc_nr()
        shls_slice = [0, 2, 1, 4, 2, 5, 0, 4]
        locs = [ao_loc[i] for i in shls_slice]
        i0, i1, j0, j1, k0, k1, l0, l1 = locs

        vs = jk.get_jk(mol, (dm[j0:j1,k0:k1], dm[l0:l1,k0:k1]),
                       ['ijkl,jk->il', 'ijkl,lk->ij'], hermi=0,
                       intor='int2e_ip1', shls_slice=shls_slice)
        self.assertEqual(vs[0].shape, (3,2,6))
        self.assertEqual(vs[1].shape, (3,2,5))
Beispiel #17
0
    def test_shls_slice(self):
        dm = mf.make_rdm1()
        ao_loc = mol.ao_loc_nr()
        shls_slice = [0, 2, 1, 4, 2, 5, 0, 4]
        locs = [ao_loc[i] for i in shls_slice]
        i0, i1, j0, j1, k0, k1, l0, l1 = locs

        vs = jk.get_jk(mol, (dm[j0:j1,k0:k1], dm[l0:l1,k0:k1]),
                       ['ijkl,jk->il', 'ijkl,lk->ij'], hermi=0,
                       intor='int2e_ip1', shls_slice=shls_slice)
        self.assertEqual(vs[0].shape, (3,2,6))
        self.assertEqual(vs[1].shape, (3,2,5))
Beispiel #18
0
def _get_k_lr(mol, dm, omega=0, hermi=0):
    dm = numpy.asarray(dm)
    # Note, ks object caches the ERIs for small systems. The cached eris are
    # computed with regular Coulomb operator. ks.get_jk or ks.get_k do not evalute
    # the K matrix with the range separated Coulomb operator.  Here jk.get_jk
    # function computes the K matrix with the modified Coulomb operator.
    nao = dm.shape[-1]
    dms = dm.reshape(-1, nao, nao)
    with mol.with_range_coulomb(omega):
        # Compute the long range part of ERIs temporarily with omega. Restore
        # the original omega when the block ends
        vklr = jk.get_jk(mol, dms, ['ijkl,jk->il'] * len(dms))
    return numpy.asarray(vklr).reshape(dm.shape)
Beispiel #19
0
def _get_k_lr(mol, dm, omega=0, hermi=0):
    dm = numpy.asarray(dm)
# Note, ks object caches the ERIs for small systems. The cached eris are
# computed with regular Coulomb operator. ks.get_jk or ks.get_k do not evalute
# the K matrix with the range separated Coulomb operator.  Here jk.get_jk
# function computes the K matrix with the modified Coulomb operator.
    nao = dm.shape[-1]
    dms = dm.reshape(-1,nao,nao)
    with mol.with_range_coulomb(omega):
        # Compute the long range part of ERIs temporarily with omega. Restore
        # the original omega when the block ends
        vklr = jk.get_jk(mol, dms, ['ijkl,jk->il']*len(dms))
    return numpy.asarray(vklr).reshape(dm.shape)
Beispiel #20
0
def _get_k_lr(mol, dm, omega=0, hermi=0):
    omega_bak = mol._env[gto.PTR_RANGE_OMEGA]
    mol.set_range_coulomb(omega)

    dm = numpy.asarray(dm)
    # Note, ks object caches the ERIs for small systems. The cached eris are
    # computed with regular Coulomb operator. ks.get_jk or ks.get_k do not evalute
    # the K matrix with the range separated Coulomb operator.  Here jk.get_jk
    # function computes the K matrix with the modified Coulomb operator.
    nao = dm.shape[-1]
    dms = dm.reshape(-1, nao, nao)
    vklr = jk.get_jk(mol, dms, ['ijkl,jk->il'] * len(dms))

    mol.set_range_coulomb(omega_bak)
    return numpy.asarray(vklr).reshape(dm.shape)
Beispiel #21
0
def dia(magobj, gauge_orig=None):
    mol = magobj.mol
    mf = magobj._scf
    mo_energy = mf.mo_energy
    mo_coeff = mf.mo_coeff
    mo_occ = mf.mo_occ
    orbo = mo_coeff[:, mo_occ > 0]
    dm0 = numpy.dot(orbo, orbo.T) * 2
    dm0 = lib.tag_array(dm0, mo_coeff=mo_coeff, mo_occ=mo_occ)
    dme0 = numpy.dot(orbo * mo_energy[mo_occ > 0], orbo.T) * 2

    e2 = rhf_mag._get_dia_1e(magobj, gauge_orig, dm0, dme0)

    if gauge_orig is not None:
        return -e2

    # Computing the 2nd order Vxc integrals from GIAO
    grids = mf.grids
    ni = mf._numint
    xc_code = mf.xc
    xctype = ni._xc_type(xc_code)
    omega, alpha, hyb = ni.rsh_and_hybrid_coeff(xc_code, mol.spin)

    make_rho, nset, nao = ni._gen_rho_evaluator(mol, dm0, hermi=1)
    ngrids = len(grids.weights)
    mem_now = lib.current_memory()[0]
    max_memory = max(2000, mf.max_memory * .9 - mem_now)
    BLKSIZE = numint.BLKSIZE
    blksize = min(
        int(max_memory / 12 * 1e6 / 8 / nao / BLKSIZE) * BLKSIZE, ngrids)

    vmat = numpy.zeros((3, 3, nao, nao))
    if xctype == 'LDA':
        ao_deriv = 0
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory,
                                 blksize=blksize):
            rho = make_rho(0, ao, mask, 'LDA')
            vxc = ni.eval_xc(xc_code, rho, 0, deriv=1)[1]
            vrho = vxc[0]
            r_ao = numpy.einsum('pi,px->pxi', ao, coords)
            aow = numpy.einsum('pxi,p,p->pxi', r_ao, weight, vrho)
            vmat += lib.einsum('pxi,pyj->xyij', r_ao, aow)
            rho = vxc = vrho = aow = None

    elif xctype == 'GGA':
        ao_deriv = 1
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory,
                                 blksize=blksize):
            rho = make_rho(0, ao, mask, 'GGA')
            vxc = ni.eval_xc(xc_code, rho, 0, deriv=1)[1]
            wv = numint._rks_gga_wv0(rho, vxc, weight)

            # Computing \nabla (r * AO) = r * \nabla AO + [\nabla,r]_- * AO
            r_ao = numpy.einsum('npi,px->npxi', ao, coords)
            r_ao[1, :, 0] += ao[0]
            r_ao[2, :, 1] += ao[0]
            r_ao[3, :, 2] += ao[0]

            aow = numpy.einsum('npxi,np->pxi', r_ao, wv)
            vmat += lib.einsum('pxi,pyj->xyij', r_ao[0], aow)
            rho = vxc = vrho = vsigma = wv = aow = None

        vmat = vmat + vmat.transpose(0, 1, 3, 2)

    elif xctype == 'MGGA':
        raise NotImplementedError('meta-GGA')

    vmat = _add_giao_phase(mol, vmat)
    e2 += numpy.einsum('qp,xypq->xy', dm0, vmat)
    vmat = None

    e2 = e2.ravel()
    # Handle the hybrid functional and the range-separated functional
    if abs(hyb) > 1e-10:
        vs = jk.get_jk(mol, [dm0] * 3,
                       ['ijkl,ji->s2kl', 'ijkl,jk->s1il', 'ijkl,li->s1kj'],
                       'int2e_gg1',
                       's4',
                       9,
                       hermi=1)
        e2 += numpy.einsum('xpq,qp->x', vs[0], dm0)
        e2 -= numpy.einsum('xpq,qp->x', vs[1], dm0) * .25 * hyb
        e2 -= numpy.einsum('xpq,qp->x', vs[2], dm0) * .25 * hyb
        vk = jk.get_jk(mol,
                       dm0,
                       'ijkl,jk->s1il',
                       'int2e_g1g2',
                       'aa4',
                       9,
                       hermi=0)
        e2 -= numpy.einsum('xpq,qp->x', vk, dm0) * .5 * hyb

        if abs(omega) > 1e-10:
            with mol.with_range_coulomb(omega):
                vs = jk.get_jk(mol, [dm0] * 2,
                               ['ijkl,jk->s1il', 'ijkl,li->s1kj'],
                               'int2e_gg1',
                               's4',
                               9,
                               hermi=1)
                e2 -= numpy.einsum('xpq,qp->x', vs[0],
                                   dm0) * .25 * (alpha - hyb)
                e2 -= numpy.einsum('xpq,qp->x', vs[1],
                                   dm0) * .25 * (alpha - hyb)
                vk = jk.get_jk(mol,
                               dm0,
                               'ijkl,jk->s1il',
                               'int2e_g1g2',
                               'aa4',
                               9,
                               hermi=0)
                e2 -= numpy.einsum('xpq,qp->x', vk, dm0) * .5 * (alpha - hyb)

    else:
        vj = jk.get_jk(mol,
                       dm0,
                       'ijkl,ji->s2kl',
                       'int2e_gg1',
                       's4',
                       9,
                       hermi=1)
        e2 += numpy.einsum('xpq,qp->x', vj, dm0)

    return -e2.reshape(3, 3)
Beispiel #22
0
def get_vk_s8(mol, dm):
    ao_loc = mol.ao_loc_nr()
    nao = ao_loc[-1]
    vk = numpy.zeros((nao,nao))
    bas_groups = list(lib.prange(0, mol.nbas, 3))
    for ip, (ish0, ish1) in enumerate(bas_groups):
        for jp, (jsh0, jsh1) in enumerate(bas_groups[:ip]):
            for kp, (ksh0, ksh1) in enumerate(bas_groups[:ip]):
                for lp, (lsh0, lsh1) in enumerate(bas_groups[:kp]):
                    shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
                    i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
                    dms = [dm[j0:j1,k0:k1],
                           dm[j0:j1,l0:l1],
                           dm[i0:i1,k0:k1],
                           dm[i0:i1,l0:l1],
                           dm[l0:l1,i0:i1],
                           dm[l0:l1,j0:j1],
                           dm[k0:k1,i0:i1],
                           dm[k0:k1,j0:j1]]
                    scripts = ['ijkl,jk->il',
                               'ijkl,jl->ik',
                               'ijkl,ik->jl',
                               'ijkl,il->jk',
                               'ijkl,li->kj',
                               'ijkl,lj->ki',
                               'ijkl,ki->lj',
                               'ijkl,kj->li']
                    kparts = jk.get_jk(mol, dms, scripts, shls_slice=shls_slice)
                    vk[i0:i1,l0:l1] += kparts[0]
                    vk[i0:i1,k0:k1] += kparts[1]
                    vk[j0:j1,l0:l1] += kparts[2]
                    vk[j0:j1,k0:k1] += kparts[3]
                    vk[k0:k1,j0:j1] += kparts[4]
                    vk[k0:k1,i0:i1] += kparts[5]
                    vk[l0:l1,j0:j1] += kparts[6]
                    vk[l0:l1,i0:i1] += kparts[7]

                # ip > jp, ip > kp, kp == lp
                lsh0, lsh1 = ksh0, ksh1
                shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
                i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
                dms = [dm[j0:j1,k0:k1],
                       dm[i0:i1,k0:k1],
                       dm[k0:k1,j0:j1],
                       dm[k0:k1,i0:i1]]
                scripts = ['ijkl,jk->il',
                           'ijkl,ik->jl',
                           'ijkl,kj->li',
                           'ijkl,ki->lj']
                kparts = jk.get_jk(mol, dms, scripts, shls_slice=shls_slice)
                vk[i0:i1,l0:l1] += kparts[0]
                vk[j0:j1,l0:l1] += kparts[1]
                vk[l0:l1,i0:i1] += kparts[2]
                vk[l0:l1,j0:j1] += kparts[3]

            # ip == kp and ip > jp and kp > lp
            kp, ksh0, ksh1 = ip, ish0, ish1
            for lp, (lsh0, lsh1) in enumerate(bas_groups[:kp]):
                shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
                i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
                dms = [dm[j0:j1,k0:k1],
                       dm[i0:i1,k0:k1],
                       dm[j0:j1,l0:l1],
                       dm[i0:i1,l0:l1]]
                scripts = ['ijkl,jk->il',
                           'ijkl,ik->jl',
                           'ijkl,jl->ik',
                           'ijkl,il->jk']
                kparts = jk.get_jk(mol, dms, scripts, shls_slice=shls_slice)
                vk[i0:i1,l0:l1] += kparts[0]
                vk[j0:j1,l0:l1] += kparts[1]
                vk[i0:i1,k0:k1] += kparts[2]
                vk[j0:j1,k0:k1] += kparts[3]

        # ip == jp and ip >= kp
        jsh0, jsh1 = ish0, ish1
        for kp, (ksh0, ksh1) in enumerate(bas_groups[:ip+1]):
            for lp, (lsh0, lsh1) in enumerate(bas_groups[:kp]):
                shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
                i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
                dms = [dm[j0:j1,k0:k1],
                       dm[j0:j1,l0:l1],
                       dm[k0:k1,j0:j1],
                       dm[l0:l1,j0:j1]]
                scripts = ['ijkl,jk->il',
                           'ijkl,jl->ik',
                           'ijkl,kj->li',
                           'ijkl,lj->ki']
                kparts = jk.get_jk(mol, dms, scripts, shls_slice=shls_slice)
                vk[i0:i1,l0:l1] += kparts[0]
                vk[i0:i1,k0:k1] += kparts[1]
                vk[l0:l1,i0:i1] += kparts[2]
                vk[k0:k1,i0:i1] += kparts[3]

        # ip == jp and ip > kp and kp == lp
        for kp, (ksh0, ksh1) in enumerate(bas_groups[:ip]):
            lsh0, lsh1 = ksh0, ksh1
            shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
            i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
            dms = [dm[j0:j1,k0:k1],
                   dm[l0:l1,i0:i1]]
            scripts = ['ijkl,jk->il',
                       'ijkl,li->kj']
            kparts = jk.get_jk(mol, dms, scripts, shls_slice=shls_slice)
            vk[i0:i1,l0:l1] += kparts[0]
            vk[k0:k1,j0:j1] += kparts[1]

        # ip == jp == kp == lp
        kp, ksh0, ksh1 = ip, ish0, ish1
        lsh0, lsh1 = ksh0, ksh1
        shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
        i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
        kparts = jk.get_jk(mol,
                           [dm[j0:j1,k0:k1]],
                           scripts=['ijkl,jk->il'],
                           shls_slice=shls_slice)
        vk[i0:i1,l0:l1] += kparts[0]
    return vk
Beispiel #23
0
def get_vk_s8(mol, dm):
    ao_loc = mol.ao_loc_nr()
    nao = ao_loc[-1]
    vk = numpy.zeros((nao,nao))
    bas_groups = list(lib.prange(0, mol.nbas, 3))
    for ip, (ish0, ish1) in enumerate(bas_groups):
        for jp, (jsh0, jsh1) in enumerate(bas_groups[:ip]):
            for kp, (ksh0, ksh1) in enumerate(bas_groups[:ip]):
                for lp, (lsh0, lsh1) in enumerate(bas_groups[:kp]):
                    shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
                    i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
                    dms = [dm[j0:j1,k0:k1],
                           dm[j0:j1,l0:l1],
                           dm[i0:i1,k0:k1],
                           dm[i0:i1,l0:l1],
                           dm[l0:l1,i0:i1],
                           dm[l0:l1,j0:j1],
                           dm[k0:k1,i0:i1],
                           dm[k0:k1,j0:j1]]
                    scripts = ['ijkl,jk->il',
                               'ijkl,jl->ik',
                               'ijkl,ik->jl',
                               'ijkl,il->jk',
                               'ijkl,li->kj',
                               'ijkl,lj->ki',
                               'ijkl,ki->lj',
                               'ijkl,kj->li']
                    kparts = jk.get_jk(mol, dms, scripts, shls_slice=shls_slice)
                    vk[i0:i1,l0:l1] += kparts[0]
                    vk[i0:i1,k0:k1] += kparts[1]
                    vk[j0:j1,l0:l1] += kparts[2]
                    vk[j0:j1,k0:k1] += kparts[3]
                    vk[k0:k1,j0:j1] += kparts[4]
                    vk[k0:k1,i0:i1] += kparts[5]
                    vk[l0:l1,j0:j1] += kparts[6]
                    vk[l0:l1,i0:i1] += kparts[7]

                # ip > jp, ip > kp, kp == lp
                lsh0, lsh1 = ksh0, ksh1
                shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
                i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
                dms = [dm[j0:j1,k0:k1],
                       dm[i0:i1,k0:k1],
                       dm[k0:k1,j0:j1],
                       dm[k0:k1,i0:i1]]
                scripts = ['ijkl,jk->il',
                           'ijkl,ik->jl',
                           'ijkl,kj->li',
                           'ijkl,ki->lj']
                kparts = jk.get_jk(mol, dms, scripts, shls_slice=shls_slice)
                vk[i0:i1,l0:l1] += kparts[0]
                vk[j0:j1,l0:l1] += kparts[1]
                vk[l0:l1,i0:i1] += kparts[2]
                vk[l0:l1,j0:j1] += kparts[3]

            # ip == kp and ip > jp and kp > lp
            kp, ksh0, ksh1 = ip, ish0, ish1
            for lp, (lsh0, lsh1) in enumerate(bas_groups[:kp]):
                shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
                i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
                dms = [dm[j0:j1,k0:k1],
                       dm[i0:i1,k0:k1],
                       dm[j0:j1,l0:l1],
                       dm[i0:i1,l0:l1]]
                scripts = ['ijkl,jk->il',
                           'ijkl,ik->jl',
                           'ijkl,jl->ik',
                           'ijkl,il->jk']
                kparts = jk.get_jk(mol, dms, scripts, shls_slice=shls_slice)
                vk[i0:i1,l0:l1] += kparts[0]
                vk[j0:j1,l0:l1] += kparts[1]
                vk[i0:i1,k0:k1] += kparts[2]
                vk[j0:j1,k0:k1] += kparts[3]

        # ip == jp and ip >= kp
        jsh0, jsh1 = ish0, ish1
        for kp, (ksh0, ksh1) in enumerate(bas_groups[:ip+1]):
            for lp, (lsh0, lsh1) in enumerate(bas_groups[:kp]):
                shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
                i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
                dms = [dm[j0:j1,k0:k1],
                       dm[j0:j1,l0:l1],
                       dm[k0:k1,j0:j1],
                       dm[l0:l1,j0:j1]]
                scripts = ['ijkl,jk->il',
                           'ijkl,jl->ik',
                           'ijkl,kj->li',
                           'ijkl,lj->ki']
                kparts = jk.get_jk(mol, dms, scripts, shls_slice=shls_slice)
                vk[i0:i1,l0:l1] += kparts[0]
                vk[i0:i1,k0:k1] += kparts[1]
                vk[l0:l1,i0:i1] += kparts[2]
                vk[k0:k1,i0:i1] += kparts[3]

        # ip == jp and ip > kp and kp == lp
        for kp, (ksh0, ksh1) in enumerate(bas_groups[:ip]):
            lsh0, lsh1 = ksh0, ksh1
            shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
            i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
            dms = [dm[j0:j1,k0:k1],
                   dm[l0:l1,i0:i1]]
            scripts = ['ijkl,jk->il',
                       'ijkl,li->kj']
            kparts = jk.get_jk(mol, dms, scripts, shls_slice=shls_slice)
            vk[i0:i1,l0:l1] += kparts[0]
            vk[k0:k1,j0:j1] += kparts[1]

        # ip == jp == kp == lp
        kp, ksh0, ksh1 = ip, ish0, ish1
        lsh0, lsh1 = ksh0, ksh1
        shls_slice = (ish0, ish1, jsh0, jsh1, ksh0, ksh1, lsh0, lsh1)
        i0, i1, j0, j1, k0, k1, l0, l1 = [ao_loc[x] for x in shls_slice]
        kparts = jk.get_jk(mol,
                           [dm[j0:j1,k0:k1]],
                           scripts=['ijkl,jk->il'],
                           shls_slice=shls_slice)
        vk[i0:i1,l0:l1] += kparts[0]
    return vk
Beispiel #24
0
def get_j(dfobj, dm, hermi=1, direct_scf_tol=1e-13):
    from pyscf.scf import _vhf
    from pyscf.scf import jk
    from pyscf.df import addons
    t0 = t1 = (time.clock(), time.time())

    mol = dfobj.mol
    if dfobj._vjopt is None:
        dfobj.auxmol = auxmol = addons.make_auxmol(mol, dfobj.auxbasis)
        opt = _vhf.VHFOpt(mol, 'int3c2e', 'CVHFnr3c2e_schwarz_cond')
        opt.direct_scf_tol = direct_scf_tol

        # q_cond part 1: the regular int2e (ij|ij) for mol's basis
        opt.init_cvhf_direct(mol, 'int2e', 'CVHFsetnr_direct_scf')
        mol_q_cond = lib.frompointer(opt._this.contents.q_cond, mol.nbas**2)

        # Update q_cond to include the 2e-integrals (auxmol|auxmol)
        j2c = auxmol.intor('int2c2e', hermi=1)
        j2c_diag = numpy.sqrt(abs(j2c.diagonal()))
        aux_loc = auxmol.ao_loc
        aux_q_cond = [
            j2c_diag[i0:i1].max() for i0, i1 in zip(aux_loc[:-1], aux_loc[1:])
        ]
        q_cond = numpy.hstack((mol_q_cond, aux_q_cond))
        fsetqcond = _vhf.libcvhf.CVHFset_q_cond
        fsetqcond(opt._this, q_cond.ctypes.data_as(ctypes.c_void_p),
                  ctypes.c_int(q_cond.size))

        try:
            opt.j2c = j2c = scipy.linalg.cho_factor(j2c, lower=True)
            opt.j2c_type = 'cd'
        except scipy.linalg.LinAlgError:
            opt.j2c = j2c
            opt.j2c_type = 'regular'

        # jk.get_jk function supports 4-index integrals. Use bas_placeholder
        # (l=0, nctr=1, 1 function) to hold the last index.
        bas_placeholder = numpy.array([0, 0, 1, 1, 0, 0, 0, 0],
                                      dtype=numpy.int32)
        fakemol = mol + auxmol
        fakemol._bas = numpy.vstack((fakemol._bas, bas_placeholder))
        opt.fakemol = fakemol
        dfobj._vjopt = opt
        t1 = logger.timer_debug1(dfobj, 'df-vj init_direct_scf', *t1)

    opt = dfobj._vjopt
    fakemol = opt.fakemol
    dm = numpy.asarray(dm, order='C')
    dm_shape = dm.shape
    nao = dm_shape[-1]
    dm = dm.reshape(-1, nao, nao)
    n_dm = dm.shape[0]

    # First compute the density in auxiliary basis
    # j3c = fauxe2(mol, auxmol)
    # jaux = numpy.einsum('ijk,ji->k', j3c, dm)
    # rho = numpy.linalg.solve(auxmol.intor('int2c2e'), jaux)
    nbas = mol.nbas
    nbas1 = mol.nbas + dfobj.auxmol.nbas
    shls_slice = (0, nbas, 0, nbas, nbas, nbas1, nbas1, nbas1 + 1)
    with lib.temporary_env(opt,
                           prescreen='CVHFnr3c2e_vj_pass1_prescreen',
                           _dmcondname='CVHFsetnr_direct_scf_dm'):
        jaux = jk.get_jk(fakemol,
                         dm, ['ijkl,ji->kl'] * n_dm,
                         'int3c2e',
                         aosym='s2ij',
                         hermi=0,
                         shls_slice=shls_slice,
                         vhfopt=opt)
    # remove the index corresponding to bas_placeholder
    jaux = numpy.array(jaux)[:, :, 0]
    t1 = logger.timer_debug1(dfobj, 'df-vj pass 1', *t1)

    if opt.j2c_type == 'cd':
        rho = scipy.linalg.cho_solve(opt.j2c, jaux.T)
    else:
        rho = scipy.linalg.solve(opt.j2c, jaux.T)
    # transform rho to shape (:,1,naux), to adapt to 3c2e integrals (ij|k)
    rho = rho.T[:, numpy.newaxis, :]
    t1 = logger.timer_debug1(dfobj, 'df-vj solve ', *t1)

    # Next compute the Coulomb matrix
    # j3c = fauxe2(mol, auxmol)
    # vj = numpy.einsum('ijk,k->ij', j3c, rho)
    with lib.temporary_env(opt,
                           prescreen='CVHFnr3c2e_vj_pass2_prescreen',
                           _dmcondname=None):
        # CVHFnr3c2e_vj_pass2_prescreen requires custom dm_cond
        aux_loc = dfobj.auxmol.ao_loc
        dm_cond = [
            abs(rho[:, :, i0:i1]).max()
            for i0, i1 in zip(aux_loc[:-1], aux_loc[1:])
        ]
        dm_cond = numpy.array(dm_cond)
        fsetcond = _vhf.libcvhf.CVHFset_dm_cond
        fsetcond(opt._this, dm_cond.ctypes.data_as(ctypes.c_void_p),
                 ctypes.c_int(dm_cond.size))

        vj = jk.get_jk(fakemol,
                       rho, ['ijkl,lk->ij'] * n_dm,
                       'int3c2e',
                       aosym='s2ij',
                       hermi=1,
                       shls_slice=shls_slice,
                       vhfopt=opt)

    t1 = logger.timer_debug1(dfobj, 'df-vj pass 2', *t1)
    logger.timer(dfobj, 'df-vj', *t0)
    return numpy.asarray(vj).reshape(dm_shape)
Beispiel #25
0
def _eval_jk(mf, dm, hermi, gen_jobs):
    cpu0 = (logger.process_clock(), logger.perf_counter())
    mol = mf.mol
    ao_loc = mol.ao_loc_nr()
    nao = ao_loc[-1]

    bas_groups = _partition_bas(mol)
    jobs = gen_jobs(len(bas_groups), hermi)
    njobs = len(jobs)
    logger.debug1(mf, 'njobs %d', njobs)

    # Each job has multiple recipes.
    n_recipes = len(jobs[0][1:])
    dm = numpy.asarray(dm).reshape(-1, nao, nao)
    n_dm = dm.shape[0]
    vk = numpy.zeros((n_recipes, n_dm, nao, nao))

    if mf.opt is None:
        vhfopt = mf.init_direct_scf(mol)
    else:
        vhfopt = mf.opt
    # Assign the entire dm_cond to vhfopt.
    # The prescreen function CVHFnrs8_prescreen will index q_cond and dm_cond
    # over the entire basis.  "set_dm" in function jk.get_jk/direct_bindm only
    # creates a subblock of dm_cond which is not compatible with
    # CVHFnrs8_prescreen.
    vhfopt.set_dm(dm, mol._atm, mol._bas, mol._env)
    # Then skip the "set_dm" initialization in function jk.get_jk/direct_bindm.
    vhfopt._dmcondname = None

    logger.timer_debug1(mf, 'get_jk initialization', *cpu0)
    for job_id in mpi.work_stealing_partition(range(njobs)):
        group_ids = jobs[job_id][0]
        recipes = jobs[job_id][1:]

        shls_slice = lib.flatten([bas_groups[i] for i in group_ids])
        loc = ao_loc[shls_slice].reshape(4, 2)

        dm_blks = []
        for i_dm in range(n_dm):
            for ir, recipe in enumerate(recipes):
                for i, rec in enumerate(recipe):
                    p0, p1 = loc[rec[0]]
                    q0, q1 = loc[rec[1]]
                    dm_blks.append(dm[i_dm, p0:p1, q0:q1])
        scripts = [
            'ijkl,%s%s->%s%s' % tuple(['ijkl'[x] for x in rec])
            for recipe in recipes for rec in recipe
        ] * n_dm

        kparts = jk.get_jk(mol,
                           dm_blks,
                           scripts,
                           shls_slice=shls_slice,
                           vhfopt=vhfopt)

        for i_dm in range(n_dm):
            for ir, recipe in enumerate(recipes):
                for i, rec in enumerate(recipe):
                    p0, p1 = loc[rec[2]]
                    q0, q1 = loc[rec[3]]
                    vk[ir, i_dm, p0:p1, q0:q1] += kparts[i]
                # Pop the results of one recipe
                kparts = kparts[i + 1:]

    vk = mpi.reduce(vk)
    if rank == 0:
        if hermi:
            for i in range(n_recipes):
                for j in range(n_dm):
                    lib.hermi_triu(vk[i, j], hermi, inplace=True)
    else:
        # Zero out vk on workers. If reduce(get_jk()) is called twice,
        # non-zero vk on workers can cause error.
        vk[:] = 0
    logger.timer(mf, 'get_jk', *cpu0)
    return vk
Beispiel #26
0
def dia(magobj, gauge_orig=None):
    mol = magobj.mol
    mf = magobj._scf
    mo_energy = magobj._scf.mo_energy
    mo_coeff = magobj._scf.mo_coeff
    mo_occ = magobj._scf.mo_occ
    orboa = mo_coeff[0][:,mo_occ[0] > 0]
    orbob = mo_coeff[1][:,mo_occ[1] > 0]
    dm0a = lib.tag_array(orboa.dot(orboa.T), mo_coeff=mo_coeff[0], mo_occ=mo_occ[0])
    dm0b = lib.tag_array(orbob.dot(orbob.T), mo_coeff=mo_coeff[1], mo_occ=mo_occ[1])
    dm0 = dm0a + dm0b
    dme0a = numpy.dot(orboa * mo_energy[0][mo_occ[0] > 0], orboa.T)
    dme0b = numpy.dot(orbob * mo_energy[1][mo_occ[1] > 0], orbob.T)
    dme0 = dme0a + dme0b

    e2 = rhf_mag._get_dia_1e(magobj, gauge_orig, dm0, dme0)

    if gauge_orig is not None:
        return -e2

    # Computing the 2nd order Vxc integrals from GIAO
    grids = mf.grids
    ni = mf._numint
    xc_code = mf.xc
    xctype = ni._xc_type(xc_code)
    omega, alpha, hyb = ni.rsh_and_hybrid_coeff(xc_code, mol.spin)

    make_rhoa, nset, nao = ni._gen_rho_evaluator(mol, dm0a, hermi=1)
    make_rhob            = ni._gen_rho_evaluator(mol, dm0b, hermi=1)[0]
    ngrids = len(grids.weights)
    mem_now = lib.current_memory()[0]
    max_memory = max(2000, mf.max_memory*.9-mem_now)
    BLKSIZE = numint.BLKSIZE
    blksize = min(int(max_memory/12*1e6/8/nao/BLKSIZE)*BLKSIZE, ngrids)

    vmata = numpy.zeros((3,3,nao,nao))
    vmatb = numpy.zeros((3,3,nao,nao))
    if xctype == 'LDA':
        ao_deriv = 0
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory,
                                 blksize=blksize):
            rho = (make_rhoa(0, ao, mask, 'LDA'),
                   make_rhob(0, ao, mask, 'LDA'))
            vxc = ni.eval_xc(xc_code, rho, spin=1, deriv=1)[1]
            vrho = vxc[0]
            r_ao = numpy.einsum('pi,px->pxi', ao, coords)
            aow = numpy.einsum('pxi,p,p->pxi', r_ao, weight, vrho[:,0])
            vmata += lib.einsum('pxi,pyj->xyij', r_ao, aow)
            aow = numpy.einsum('pxi,p,p->pxi', r_ao, weight, vrho[:,1])
            vmatb += lib.einsum('pxi,pyj->xyij', r_ao, aow)
            rho = vxc = vrho = aow = None

    elif xctype == 'GGA':
        ao_deriv = 1
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory,
                                 blksize=blksize):
            rho = (make_rhoa(0, ao, mask, 'GGA'),
                   make_rhob(0, ao, mask, 'GGA'))
            vxc = ni.eval_xc(xc_code, rho, spin=1, deriv=1)[1]
            wva, wvb = numint._uks_gga_wv0(rho, vxc, weight)

            # Computing \nabla (r * AO) = r * \nabla AO + [\nabla,r]_- * AO
            r_ao = numpy.einsum('npi,px->npxi', ao, coords)
            r_ao[1,:,0] += ao[0]
            r_ao[2,:,1] += ao[0]
            r_ao[3,:,2] += ao[0]

            aow = numpy.einsum('npxi,np->pxi', r_ao, wva)
            vmata += lib.einsum('pxi,pyj->xyij', r_ao[0], aow)
            aow = numpy.einsum('npxi,np->pxi', r_ao, wvb)
            vmata += lib.einsum('pxi,pyj->xyij', r_ao[0], aow)
            rho = vxc = vrho = vsigma = wv = aow = None

        vmata = vmata + vmata.transpose(0,1,3,2)
        vmatb = vmatb + vmatb.transpose(0,1,3,2)

    elif xctype == 'MGGA':
        raise NotImplementedError('meta-GGA')

    vmata = rks_mag._add_giao_phase(mol, vmata)
    vmatb = rks_mag._add_giao_phase(mol, vmatb)
    e2 += numpy.einsum('qp,xypq->xy', dm0a, vmata)
    e2 += numpy.einsum('qp,xypq->xy', dm0b, vmatb)
    vmata = vmatb = None

    e2 = e2.ravel()
    # Handle the hybrid functional and the range-separated functional
    if abs(hyb) > 1e-10:
        vs = jk.get_jk(mol, [dm0, dm0a, dm0a, dm0b, dm0b],
                       ['ijkl,ji->s2kl',
                        'ijkl,jk->s1il', 'ijkl,li->s1kj',
                        'ijkl,jk->s1il', 'ijkl,li->s1kj'],
                       'int2e_gg1', 's4', 9, hermi=1)
        e2 += numpy.einsum('xpq,qp->x', vs[0], dm0)
        e2 -= numpy.einsum('xpq,qp->x', vs[1], dm0a) * .5 * hyb
        e2 -= numpy.einsum('xpq,qp->x', vs[2], dm0a) * .5 * hyb
        e2 -= numpy.einsum('xpq,qp->x', vs[3], dm0b) * .5 * hyb
        e2 -= numpy.einsum('xpq,qp->x', vs[4], dm0b) * .5 * hyb
        vk = jk.get_jk(mol, [dm0a, dm0b], ['ijkl,jk->s1il', 'ijkl,jk->s1il'],
                       'int2e_g1g2', 'aa4', 9, hermi=0)
        e2 -= numpy.einsum('xpq,qp->x', vk[0], dm0a) * hyb
        e2 -= numpy.einsum('xpq,qp->x', vk[1], dm0b) * hyb

        if abs(omega) > 1e-10:
            with mol.with_range_coulomb(omega):
                vs = jk.get_jk(mol, [dm0a, dm0a, dm0b, dm0b],
                               ['ijkl,jk->s1il', 'ijkl,li->s1kj',
                                'ijkl,jk->s1il', 'ijkl,li->s1kj'],
                               'int2e_gg1', 's4', 9, hermi=1)
                e2 -= numpy.einsum('xpq,qp->x', vs[0], dm0a) * .5 * (alpha-hyb)
                e2 -= numpy.einsum('xpq,qp->x', vs[1], dm0a) * .5 * (alpha-hyb)
                e2 -= numpy.einsum('xpq,qp->x', vs[2], dm0b) * .5 * (alpha-hyb)
                e2 -= numpy.einsum('xpq,qp->x', vs[3], dm0b) * .5 * (alpha-hyb)
                vk = jk.get_jk(mol, [dm0a, dm0b], ['ijkl,jk->s1il', 'ijkl,jk->s1il'],
                               'int2e_g1g2', 'aa4', 9, hermi=0)
                e2 -= numpy.einsum('xpq,qp->x', vk[0], dm0a) * (alpha-hyb)
                e2 -= numpy.einsum('xpq,qp->x', vk[1], dm0b) * (alpha-hyb)

    else:
        vj = jk.get_jk(mol, dm0, 'ijkl,ji->s2kl',
                       'int2e_gg1', 's4', 9, hermi=1)
        e2 += numpy.einsum('xpq,qp->x', vj, dm0)

    return -e2.reshape(3, 3)